diff --git a/Directory.Build.props b/Directory.Build.props index a4f567fdb..0baf38f42 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -37,10 +37,8 @@ - + --> diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs index 84cc4565a..2d5e00774 100644 --- a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs +++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs @@ -1,7 +1,10 @@ using System; using System.Text; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; + using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Sftp; @@ -97,33 +100,47 @@ private void SetupMocks() #region SftpSession.Connect() - _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object); - _channelSessionMock.InSequence(sequence).Setup(p => p.Open()); - _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true); - _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); - _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes)).Callback( - () => - { - _channelSessionMock.Raise(c => c.DataReceived += null, - new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes())); - }); - _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); - _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes)).Callback( - () => - { - _channelSessionMock.Raise(c => c.DataReceived += null, - new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes())); - }); + _ = _sessionMock.InSequence(sequence) + .Setup(p => p.CreateChannelSession()) + .Returns(_channelSessionMock.Object); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.Open()); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.SendSubsystemRequest("sftp")) + .Returns(true); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.IsOpen) + .Returns(true); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.SendData(_sftpInitRequestBytes)) + .Callback(() => + { + _channelSessionMock.Raise(c => c.DataReceived += null, + new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes())); + }); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.IsOpen) + .Returns(true); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.SendData(_sftpRealPathRequestBytes)) + .Callback(() => + { + _channelSessionMock.Raise(c => c.DataReceived += null, + new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes())); + }); #endregion SftpSession.Connect() - _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true); - _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpStatVfsRequestBytes)).Callback( - () => - { - _channelSessionMock.Raise(c => c.DataReceived += null, - new ChannelDataEventArgs(0, _sftpStatVfsResponse.GetBytes())); - }); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.IsOpen) + .Returns(true); + _ = _channelSessionMock.InSequence(sequence) + .Setup(p => p.SendData(_sftpStatVfsRequestBytes)) + .Callback(() => + { + _channelSessionMock.Raise(c => c.DataReceived += null, + new ChannelDataEventArgs(0, _sftpStatVfsResponse.GetBytes())); + }); } protected void Arrange() @@ -153,4 +170,4 @@ public void AvailableBlocksInReturnedValueShouldMatchValueInSftpResponse() Assert.AreEqual(_bAvail, _actual.AvailableBlocks); } } -} \ No newline at end of file +} diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs index b3735b91d..485ebe560 100644 --- a/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs +++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs @@ -3,7 +3,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp { - internal class SftpStatVfsResponseBuilder + internal sealed class SftpStatVfsResponseBuilder { private uint _protocolVersion; private uint _responseId; @@ -141,8 +141,13 @@ public StatVfsResponse Build() } } - internal class StatVfsResponse : SftpExtendedReplyResponse + internal sealed class StatVfsResponse : SftpResponse { + public override SftpMessageTypes SftpMessageType + { + get { return SftpMessageTypes.ExtendedReply; } + } + public SftpFileSytemInformation Information { get; set; } public StatVfsResponse(uint protocolVersion) diff --git a/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj b/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj index f4c0b6f33..88693e5aa 100644 --- a/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj +++ b/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj @@ -64,9 +64,9 @@ - - - + + + diff --git a/src/Renci.SshNet/.editorconfig b/src/Renci.SshNet/.editorconfig index c0430021e..5da8db715 100644 --- a/src/Renci.SshNet/.editorconfig +++ b/src/Renci.SshNet/.editorconfig @@ -13,6 +13,12 @@ dotnet_diagnostic.SYSLIB1045.severity = none # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1202.md dotnet_diagnostic.SA1202.severity = none +#### Meziantou.Analyzer rules #### + +# MA0053: Make class sealed +# https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0053.md +MA0053.public_class_should_be_sealed = false + #### .NET Compiler Platform analysers rules #### # CA1031: Do not catch general exception types diff --git a/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs b/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs index d46411044..45a624471 100644 --- a/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs +++ b/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs @@ -39,12 +39,16 @@ public static System.Security.Cryptography.RandomNumberGenerator CreateRandomNum public static System.Security.Cryptography.MD5 CreateMD5() { +#pragma warning disable CA5351 // Do not use broken cryptographic algorithms return System.Security.Cryptography.MD5.Create(); +#pragma warning restore CA5351 // Do not use broken cryptographic algorithms } public static System.Security.Cryptography.SHA1 CreateSHA1() { +#pragma warning disable CA5350 // Do not use weak cryptographic algorithms return System.Security.Cryptography.SHA1.Create(); +#pragma warning restore CA5350 // Do not use weak cryptographic algorithms } public static System.Security.Cryptography.SHA256 CreateSHA256() @@ -66,7 +70,9 @@ public static System.Security.Cryptography.SHA512 CreateSHA512() public static System.Security.Cryptography.RIPEMD160 CreateRIPEMD160() { #if FEATURE_HASH_RIPEMD160_CREATE +#pragma warning disable CA5350 // Do not use weak cryptographic algorithms return System.Security.Cryptography.RIPEMD160.Create(); +#pragma warning restore CA5350 // Do not use weak cryptographic algorithms #else return new System.Security.Cryptography.RIPEMD160Managed(); #endif @@ -80,22 +86,30 @@ public static System.Security.Cryptography.RIPEMD160 CreateRIPEMD160() public static System.Security.Cryptography.HMACMD5 CreateHMACMD5(byte[] key) { +#pragma warning disable CA5351 // Do not use broken cryptographic algorithms return new System.Security.Cryptography.HMACMD5(key); +#pragma warning restore CA5351 // Do not use broken cryptographic algorithms } public static HMACMD5 CreateHMACMD5(byte[] key, int hashSize) { +#pragma warning disable CA5351 // Do not use broken cryptographic algorithms return new HMACMD5(key, hashSize); +#pragma warning restore CA5351 // Do not use broken cryptographic algorithms } public static System.Security.Cryptography.HMACSHA1 CreateHMACSHA1(byte[] key) { +#pragma warning disable CA5350 // Do not use weak cryptographic algorithms return new System.Security.Cryptography.HMACSHA1(key); +#pragma warning restore CA5350 // Do not use weak cryptographic algorithms } public static HMACSHA1 CreateHMACSHA1(byte[] key, int hashSize) { +#pragma warning disable CA5350 // Do not use weak cryptographic algorithms return new HMACSHA1(key, hashSize); +#pragma warning restore CA5350 // Do not use weak cryptographic algorithms } public static System.Security.Cryptography.HMACSHA256 CreateHMACSHA256(byte[] key) @@ -131,7 +145,9 @@ public static HMACSHA512 CreateHMACSHA512(byte[] key, int hashSize) #if FEATURE_HMAC_RIPEMD160 public static System.Security.Cryptography.HMACRIPEMD160 CreateHMACRIPEMD160(byte[] key) { +#pragma warning disable CA5350 // Do not use weak cryptographic algorithms return new System.Security.Cryptography.HMACRIPEMD160(key); +#pragma warning restore CA5350 // Do not use weak cryptographic algorithms } #else public static global::SshNet.Security.Cryptography.HMACRIPEMD160 CreateHMACRIPEMD160(byte[] key) diff --git a/src/Renci.SshNet/Abstractions/DiagnosticAbstraction.cs b/src/Renci.SshNet/Abstractions/DiagnosticAbstraction.cs index 16ee1c0ab..18275e724 100644 --- a/src/Renci.SshNet/Abstractions/DiagnosticAbstraction.cs +++ b/src/Renci.SshNet/Abstractions/DiagnosticAbstraction.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.Threading; namespace Renci.SshNet.Abstractions { @@ -22,7 +21,13 @@ public static bool IsEnabled(TraceEventType traceEventType) [Conditional("DEBUG")] public static void Log(string text) { - Loggging.TraceEvent(TraceEventType.Verbose, Thread.CurrentThread.ManagedThreadId, text); + Loggging.TraceEvent(TraceEventType.Verbose, +#if NET6_0_OR_GREATER + System.Environment.CurrentManagedThreadId, +#else + System.Threading.Thread.CurrentThread.ManagedThreadId, +#endif // NET6_0_OR_GREATER + text); } } } diff --git a/src/Renci.SshNet/Abstractions/SocketAbstraction.cs b/src/Renci.SshNet/Abstractions/SocketAbstraction.cs index 5784879fa..a1fe71d75 100644 --- a/src/Renci.SshNet/Abstractions/SocketAbstraction.cs +++ b/src/Renci.SshNet/Abstractions/SocketAbstraction.cs @@ -43,13 +43,13 @@ public static bool CanWrite(Socket socket) public static Socket Connect(IPEndPoint remoteEndpoint, TimeSpan connectTimeout) { var socket = new Socket(remoteEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) { NoDelay = true }; - ConnectCore(socket, remoteEndpoint, connectTimeout, true); + ConnectCore(socket, remoteEndpoint, connectTimeout, ownsSocket: true); return socket; } public static void Connect(Socket socket, IPEndPoint remoteEndpoint, TimeSpan connectTimeout) { - ConnectCore(socket, remoteEndpoint, connectTimeout, false); + ConnectCore(socket, remoteEndpoint, connectTimeout, ownsSocket: false); } public static async Task ConnectAsync(Socket socket, IPEndPoint remoteEndpoint, CancellationToken cancellationToken) @@ -60,7 +60,7 @@ public static async Task ConnectAsync(Socket socket, IPEndPoint remoteEndpoint, private static void ConnectCore(Socket socket, IPEndPoint remoteEndpoint, TimeSpan connectTimeout, bool ownsSocket) { #if FEATURE_SOCKET_EAP - var connectCompleted = new ManualResetEvent(false); + var connectCompleted = new ManualResetEvent(initialState: false); var args = new SocketAsyncEventArgs { UserToken = connectCompleted, diff --git a/src/Renci.SshNet/Abstractions/SocketExtensions.cs b/src/Renci.SshNet/Abstractions/SocketExtensions.cs index 8e6c0133b..a51d0cb8d 100644 --- a/src/Renci.SshNet/Abstractions/SocketExtensions.cs +++ b/src/Renci.SshNet/Abstractions/SocketExtensions.cs @@ -35,7 +35,7 @@ public void SetCompleted() { IsCompleted = true; - var continuation = _continuationAction ?? Interlocked.CompareExchange(ref _continuationAction, SENTINEL, null); + var continuation = _continuationAction ?? Interlocked.CompareExchange(ref _continuationAction, SENTINEL, comparand: null); if (continuation is not null) { continuation(); @@ -57,7 +57,7 @@ public SocketAsyncEventArgsAwaitable GetAwaiter() void INotifyCompletion.OnCompleted(Action continuation) { - if (_continuationAction == SENTINEL || Interlocked.CompareExchange(ref _continuationAction, continuation, null) == SENTINEL) + if (_continuationAction == SENTINEL || Interlocked.CompareExchange(ref _continuationAction, continuation, comparand: null) == SENTINEL) { // We have already completed; run continuation asynchronously _ = Task.Run(continuation); @@ -92,7 +92,7 @@ public static async Task ConnectAsync(this Socket socket, IPEndPoint remoteEndpo { args.RemoteEndPoint = remoteEndpoint; - using (cancellationToken.Register(o => ((SocketAsyncEventArgsAwaitable)o).SetCancelled(), args, false)) + using (cancellationToken.Register(o => ((SocketAsyncEventArgsAwaitable)o).SetCancelled(), args, useSynchronizationContext: false)) { await args.ExecuteAsync(socket.ConnectAsync); } @@ -107,7 +107,7 @@ public static async Task ReceiveAsync(this Socket socket, byte[] buffer, in { args.SetBuffer(buffer, offset, length); - using (cancellationToken.Register(o => ((SocketAsyncEventArgsAwaitable)o).SetCancelled(), args, false)) + using (cancellationToken.Register(o => ((SocketAsyncEventArgsAwaitable)o).SetCancelled(), args, useSynchronizationContext: false)) { await args.ExecuteAsync(socket.ReceiveAsync); } diff --git a/src/Renci.SshNet/BaseClient.cs b/src/Renci.SshNet/BaseClient.cs index ed0db2bba..a879c02f8 100644 --- a/src/Renci.SshNet/BaseClient.cs +++ b/src/Renci.SshNet/BaseClient.cs @@ -180,7 +180,7 @@ protected BaseClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo) /// If is true, then the /// connection info will be disposed when this instance is disposed. /// - internal BaseClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, IServiceFactory serviceFactory) + private protected BaseClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, IServiceFactory serviceFactory) { if (connectionInfo is null) { diff --git a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs index 11eea894c..6c521bce2 100644 --- a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs @@ -11,7 +11,7 @@ namespace Renci.SshNet.Channels /// /// Implements "direct-tcpip" SSH channel. /// - internal class ChannelDirectTcpip : ClientChannel, IChannelDirectTcpip + internal sealed class ChannelDirectTcpip : ClientChannel, IChannelDirectTcpip { private readonly object _socketLock = new object(); diff --git a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs index 465c8f181..0d67c7afe 100644 --- a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs @@ -10,7 +10,7 @@ namespace Renci.SshNet.Channels /// /// Implements "forwarded-tcpip" SSH channel. /// - internal class ChannelForwardedTcpip : ServerChannel, IChannelForwardedTcpip + internal sealed class ChannelForwardedTcpip : ServerChannel, IChannelForwardedTcpip { private readonly object _socketShutdownAndCloseLock = new object(); private Socket _socket; diff --git a/src/Renci.SshNet/ClientAuthentication.cs b/src/Renci.SshNet/ClientAuthentication.cs index 6d91455af..1cdfbecbe 100644 --- a/src/Renci.SshNet/ClientAuthentication.cs +++ b/src/Renci.SshNet/ClientAuthentication.cs @@ -4,7 +4,7 @@ namespace Renci.SshNet { - internal class ClientAuthentication : IClientAuthentication + internal sealed class ClientAuthentication : IClientAuthentication { private readonly int _partialSuccessLimit; @@ -151,7 +151,7 @@ private bool TryAuthenticate(ISession session, return false; } - private class AuthenticationState + private sealed class AuthenticationState { private readonly IList _supportedAuthenticationMethods; diff --git a/src/Renci.SshNet/Common/BigInteger.cs b/src/Renci.SshNet/Common/BigInteger.cs index 47c0aa4a4..dd6919687 100644 --- a/src/Renci.SshNet/Common/BigInteger.cs +++ b/src/Renci.SshNet/Common/BigInteger.cs @@ -300,24 +300,6 @@ public BigInteger(ulong value) } } - private static bool Negative(byte[] v) - { - return (v[7] & 0x80) != 0; - } - - private static ushort Exponent(byte[] v) - { - return (ushort)((((ushort)(v[7] & 0x7F)) << (ushort)4) | (((ushort)(v[6] & 0xF0)) >> 4)); - } - - private static ulong Mantissa(byte[] v) - { - var i1 = (uint)v[0] | ((uint)v[1] << 8) | ((uint)v[2] << 16) | ((uint)v[3] << 24); - var i2 = (uint)v[4] | ((uint)v[5] << 8) | ((uint)(v[6] & 0xF) << 16); - - return (ulong)((ulong)i1 | ((ulong)i2 << 32)); - } - /// /// Initializes a new instance of the structure using a double-precision floating-point value. /// @@ -355,7 +337,7 @@ public BigInteger(double value) BigInteger res = mantissa; res = exponent > Bias ? res << (exponent - Bias) : res >> (Bias - exponent); - _sign = (short)(Negative(bytes) ? -1 : 1); + _sign = (short) (Negative(bytes) ? -1 : 1); _data = res._data; } } @@ -365,7 +347,7 @@ public BigInteger(double value) /// /// A single-precision floating-point value. public BigInteger(float value) - : this((double)value) + : this((double) value) { } @@ -391,10 +373,10 @@ public BigInteger(decimal value) return; } - _sign = (short)((bits[3] & DecimalSignMask) != 0 ? -1 : 1); + _sign = (short) ((bits[3] & DecimalSignMask) != 0 ? -1 : 1); _data = new uint[size]; - _data[0] = (uint)bits[0]; + _data[0] = (uint) bits[0]; if (size > 1) { _data[1] = (uint) bits[1]; @@ -498,9 +480,9 @@ public BigInteger(byte[] value) (uint) (value[j++] << 16) | (uint) (value[j++] << 24); - sub = (ulong)word - borrow; - word = (uint)sub; - borrow = (uint)(sub >> 32) & 0x1u; + sub = (ulong) word - borrow; + word = (uint) sub; + borrow = (uint) (sub >> 32) & 0x1u; _data[i] = ~word; } @@ -512,13 +494,13 @@ public BigInteger(byte[] value) uint storeMask = 0; for (var i = 0; i < size; ++i) { - word |= (uint)(value[j++] << (i * 8)); + word |= (uint) (value[j++] << (i * 8)); storeMask = (storeMask << 8) | 0xFF; } sub = word - borrow; - word = (uint)sub; - borrow = (uint)(sub >> 32) & 0x1u; + word = (uint) sub; + borrow = (uint) (sub >> 32) & 0x1u; if ((~word & storeMask) == 0) { @@ -538,6 +520,24 @@ public BigInteger(byte[] value) } } + private static bool Negative(byte[] v) + { + return (v[7] & 0x80) != 0; + } + + private static ushort Exponent(byte[] v) + { + return (ushort)((((ushort)(v[7] & 0x7F)) << (ushort)4) | (((ushort)(v[6] & 0xF0)) >> 4)); + } + + private static ulong Mantissa(byte[] v) + { + var i1 = (uint)v[0] | ((uint)v[1] << 8) | ((uint)v[2] << 16) | ((uint)v[3] << 24); + var i2 = (uint)v[4] | ((uint)v[5] << 8) | ((uint)(v[6] & 0xF) << 16); + + return ((ulong) i1 | ((ulong) i2 << 32)); + } + /// /// Gets a value indicating whether the value of the current object is an even number. /// @@ -2514,7 +2514,7 @@ static int BitScanBackward(uint word) /// of implicit conversion to a value, and its value is equal to the value of the /// current object; otherwise, false. /// - public override bool Equals(object obj) + public override readonly bool Equals(object obj) { if (obj is not BigInteger other) { @@ -2533,7 +2533,7 @@ public override bool Equals(object obj) /// true if this object and have the same value; /// otherwise, false. /// - public bool Equals(BigInteger other) + public readonly bool Equals(BigInteger other) { if (_sign != other._sign) { @@ -2572,37 +2572,27 @@ public readonly bool Equals(long other) } /// - /// Converts the numeric value of the current object to its equivalent string representation. + /// Returns a value that indicates whether the current instance and an unsigned 64-bit integer have the same value. /// + /// The unsigned 64-bit integer to compare. /// - /// The string representation of the current value. + /// true if the current instance and the unsigned 64-bit integer have the same value; otherwise, false. /// - public override string ToString() + [CLSCompliant(false)] + public readonly bool Equals(ulong other) { - return ToString(10, provider: null); + return CompareTo(other) == 0; } - private string ToStringWithPadding(string format, uint radix, IFormatProvider provider) + /// + /// Converts the numeric value of the current object to its equivalent string representation. + /// + /// + /// The string representation of the current value. + /// + public override readonly string ToString() { - if (format.Length > 1) - { - var precision = Convert.ToInt32(format.Substring(1), CultureInfo.InvariantCulture.NumberFormat); - var baseStr = ToString(radix, provider); - if (baseStr.Length < precision) - { - var additional = new string('0', precision - baseStr.Length); - if (baseStr[0] != '-') - { - return additional + baseStr; - } - - return "-" + additional + baseStr.Substring(1); - } - - return baseStr; - } - - return ToString(radix, provider); + return ToString(10, provider: null); } /// @@ -2615,9 +2605,9 @@ private string ToStringWithPadding(string format, uint radix, IFormatProvider pr /// parameter. /// /// is not a valid format string. - public string ToString(string format) + public readonly string ToString(string format) { - return ToString(format, provider: null); + return ToString(format, formatProvider: null); } /// @@ -2629,7 +2619,7 @@ public string ToString(string format) /// The string representation of the current value in the format specified by the /// parameter. /// - public string ToString(IFormatProvider provider) + public readonly string ToString(IFormatProvider provider) { return ToString(format: null, provider); } @@ -2639,16 +2629,16 @@ public string ToString(IFormatProvider provider) /// by using the specified format and culture-specific format information. /// /// A standard or custom numeric format string. - /// An object that supplies culture-specific formatting information. + /// An object that supplies culture-specific formatting information. /// /// The string representation of the current value as specified by the - /// and parameters. + /// and parameters. /// - public string ToString(string format, IFormatProvider provider) + public readonly string ToString(string format, IFormatProvider formatProvider) { if (string.IsNullOrEmpty(format)) { - return ToString(10, provider); + return ToString(10, formatProvider); } switch (format[0]) @@ -2659,7 +2649,7 @@ public string ToString(string format, IFormatProvider provider) case 'G': case 'r': case 'R': - return ToStringWithPadding(format, 10, provider); + return ToStringWithPadding(format, 10, formatProvider); case 'x': case 'X': return ToStringWithPadding(format, 16, provider: null); @@ -2668,6 +2658,29 @@ public string ToString(string format, IFormatProvider provider) } } + private readonly string ToStringWithPadding(string format, uint radix, IFormatProvider provider) + { + if (format.Length > 1) + { + var precision = Convert.ToInt32(format.Substring(1), CultureInfo.InvariantCulture.NumberFormat); + var baseStr = ToString(radix, provider); + if (baseStr.Length < precision) + { + var additional = new string('0', precision - baseStr.Length); + if (baseStr[0] != '-') + { + return additional + baseStr; + } + + return "-" + additional + baseStr.Substring(1); + } + + return baseStr; + } + + return ToString(radix, provider); + } + private static uint[] MakeTwoComplement(uint[] v) { var res = new uint[v.Length]; @@ -3369,7 +3382,7 @@ private static bool FindExponent(ref int pos, string s, ref int exponent, bool t } // Reduce the risk of throwing an overflow exc - exp = checked((exp * 10) - (int)(s[i] - '0')); + exp = checked((exp * 10) - (s[i] - '0')); if (exp is < int.MinValue or > int.MaxValue) { exc = tryParse ? null : new OverflowException("Value too large or too small."); @@ -3627,7 +3640,7 @@ public static BigInteger Max(BigInteger left, BigInteger right) /// public static BigInteger Abs(BigInteger value) { - return new BigInteger((short) Math.Abs(value._sign), value._data); + return new BigInteger(Math.Abs(value._sign), value._data); } /// @@ -3971,19 +3984,6 @@ public static double Log10(BigInteger value) return Log(value, 10); } - /// - /// Returns a value that indicates whether the current instance and an unsigned 64-bit integer have the same value. - /// - /// The unsigned 64-bit integer to compare. - /// - /// true if the current instance and the unsigned 64-bit integer have the same value; otherwise, false. - /// - [CLSCompliant(false)] - public readonly bool Equals(ulong other) - { - return CompareTo(other) == 0; - } - /// /// Returns the hash code for the current object. /// @@ -4207,40 +4207,6 @@ public readonly int CompareTo(ulong other) return LongCompare(low, high); } - private readonly int LongCompare(uint low, uint high) - { - uint h = 0; - - if (_data.Length > 1) - { - h = _data[1]; - } - - if (h > high) - { - return 1; - } - - if (h < high) - { - return -1; - } - - var l = _data[0]; - - if (l > low) - { - return 1; - } - - if (l < low) - { - return -1; - } - - return 0; - } - /// /// Compares this instance to a signed 64-bit integer and returns an integer that indicates whether the value of this /// instance is less than, equal to, or greater than the value of the signed 64-bit integer. @@ -4305,6 +4271,40 @@ public readonly int CompareTo(long other) return r; } + private readonly int LongCompare(uint low, uint high) + { + uint h = 0; + + if (_data.Length > 1) + { + h = _data[1]; + } + + if (h > high) + { + return 1; + } + + if (h < high) + { + return -1; + } + + var l = _data[0]; + + if (l > low) + { + return 1; + } + + if (l < low) + { + return -1; + } + + return 0; + } + /// /// Compares two values and returns an integer that indicates whether the first value is less than, equal to, or greater than the second value. /// @@ -4545,6 +4545,29 @@ private static uint[] CoreAdd(uint[] a, uint[] b) return res; } + private static uint[] CoreAdd(uint[] a, uint b) + { + var len = a.Length; + var res = new uint[len]; + + ulong sum = b; + int i; + for (i = 0; i < len; i++) + { + sum += a[i]; + res[i] = (uint) sum; + sum >>= 32; + } + + if (sum != 0) + { + Array.Resize(ref res, len + 1); + res[i] = (uint) sum; + } + + return res; + } + /*invariant a > b*/ private static uint[] CoreSub(uint[] a, uint[] b) { @@ -4584,29 +4607,6 @@ private static uint[] CoreSub(uint[] a, uint[] b) return res; } - private static uint[] CoreAdd(uint[] a, uint b) - { - var len = a.Length; - var res = new uint[len]; - - ulong sum = b; - int i; - for (i = 0; i < len; i++) - { - sum += a[i]; - res[i] = (uint)sum; - sum >>= 32; - } - - if (sum != 0) - { - Array.Resize(ref res, len + 1); - res[i] = (uint)sum; - } - - return res; - } - private static uint[] CoreSub(uint[] a, uint b) { var len = a.Length; diff --git a/src/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs b/src/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs index b5eadffe1..e67ccb901 100644 --- a/src/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs +++ b/src/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs @@ -3,7 +3,7 @@ /// /// Provides data for events. /// - internal class ChannelExtendedDataEventArgs : ChannelDataEventArgs + internal sealed class ChannelExtendedDataEventArgs : ChannelDataEventArgs { /// /// Initializes a new instance of the class. diff --git a/src/Renci.SshNet/Common/ChannelOpenConfirmedEventArgs.cs b/src/Renci.SshNet/Common/ChannelOpenConfirmedEventArgs.cs index 9af1e782d..78cd9cd6b 100644 --- a/src/Renci.SshNet/Common/ChannelOpenConfirmedEventArgs.cs +++ b/src/Renci.SshNet/Common/ChannelOpenConfirmedEventArgs.cs @@ -3,7 +3,7 @@ /// /// Provides data for event. /// - internal class ChannelOpenConfirmedEventArgs : ChannelEventArgs + internal sealed class ChannelOpenConfirmedEventArgs : ChannelEventArgs { /// /// Initializes a new instance of the class. diff --git a/src/Renci.SshNet/Common/ChannelOpenFailedEventArgs.cs b/src/Renci.SshNet/Common/ChannelOpenFailedEventArgs.cs index 43b5790c6..291e9d7a6 100644 --- a/src/Renci.SshNet/Common/ChannelOpenFailedEventArgs.cs +++ b/src/Renci.SshNet/Common/ChannelOpenFailedEventArgs.cs @@ -3,7 +3,7 @@ /// /// Provides data for event. /// - internal class ChannelOpenFailedEventArgs : ChannelEventArgs + internal sealed class ChannelOpenFailedEventArgs : ChannelEventArgs { /// /// Initializes a new instance of the class. diff --git a/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs b/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs index b03102aef..7747b7621 100644 --- a/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs +++ b/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs @@ -7,7 +7,7 @@ namespace Renci.SshNet.Common /// /// Provides data for event. /// - internal class ChannelRequestEventArgs : EventArgs + internal sealed class ChannelRequestEventArgs : EventArgs { /// /// Initializes a new instance of the class. diff --git a/src/Renci.SshNet/Common/DerData.cs b/src/Renci.SshNet/Common/DerData.cs index ee6c07e36..5928d3086 100644 --- a/src/Renci.SshNet/Common/DerData.cs +++ b/src/Renci.SshNet/Common/DerData.cs @@ -230,18 +230,6 @@ public void Write(byte[] data) WriteBytes(data); } - /// - /// Writes BITSTRING data into internal buffer. - /// - /// The data. - public void WriteBitstring(byte[] data) - { - _data.Add(BITSTRING); - var length = GetLength(data.Length); - WriteBytes(length); - WriteBytes(data); - } - /// /// Writes OBJECTIDENTIFIER data into internal buffer. /// @@ -285,6 +273,28 @@ public void Write(ObjectIdentifier identifier) WriteBytes(bytes); } + /// + /// Writes DerData data into internal buffer. + /// + /// DerData data to write. + public void Write(DerData data) + { + var bytes = data.Encode(); + _data.AddRange(bytes); + } + + /// + /// Writes BITSTRING data into internal buffer. + /// + /// The data. + public void WriteBitstring(byte[] data) + { + _data.Add(BITSTRING); + var length = GetLength(data.Length); + WriteBytes(length); + WriteBytes(data); + } + /// /// Writes OBJECTIDENTIFIER data into internal buffer. /// @@ -306,16 +316,6 @@ public void WriteNull() _data.Add(0); } - /// - /// Writes DerData data into internal buffer. - /// - /// DerData data to write. - public void Write(DerData data) - { - var bytes = data.Encode(); - _data.AddRange(bytes); - } - private static byte[] GetLength(int length) { if (length > 127) diff --git a/src/Renci.SshNet/Common/PosixPath.cs b/src/Renci.SshNet/Common/PosixPath.cs index 0dae95ea1..1eddc5710 100644 --- a/src/Renci.SshNet/Common/PosixPath.cs +++ b/src/Renci.SshNet/Common/PosixPath.cs @@ -5,7 +5,7 @@ namespace Renci.SshNet.Common /// /// Represents a POSIX path. /// - internal class PosixPath + internal sealed class PosixPath { private PosixPath() { diff --git a/src/Renci.SshNet/Common/SemaphoreLight.cs b/src/Renci.SshNet/Common/SemaphoreLight.cs index 8ee4167d1..5c20a9e94 100644 --- a/src/Renci.SshNet/Common/SemaphoreLight.cs +++ b/src/Renci.SshNet/Common/SemaphoreLight.cs @@ -215,14 +215,6 @@ private bool WaitWithTimeout(int timeoutInMilliseconds) } } - /// - /// Finalizes an instance of the class. - /// - ~SemaphoreLight() - { - Dispose(disposing: false); - } - /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -241,7 +233,7 @@ protected void Dispose(bool disposing) if (disposing) { var waitHandle = _waitHandle; - if (waitHandle != null) + if (waitHandle is not null) { waitHandle.Dispose(); _waitHandle = null; diff --git a/src/Renci.SshNet/Common/SshData.cs b/src/Renci.SshNet/Common/SshData.cs index 67823ec2d..ac063b7a0 100644 --- a/src/Renci.SshNet/Common/SshData.cs +++ b/src/Renci.SshNet/Common/SshData.cs @@ -358,30 +358,6 @@ protected void Write(string data, Encoding encoding) _stream.Write(data, encoding); } - /// - /// Writes data into internal buffer. - /// - /// The data to write. - /// is null. - protected void WriteBinaryString(byte[] buffer) - { - _stream.WriteBinary(buffer); - } - - /// - /// Writes data into internal buffer. - /// - /// An array of bytes. This method write bytes from buffer to the current SSH data stream. - /// The zero-based byte offset in at which to begin writing bytes to the SSH data stream. - /// The number of bytes to be written to the current SSH data stream. - /// is null. - /// The sum of and is greater than the buffer length. - /// or is negative. - protected void WriteBinary(byte[] buffer, int offset, int count) - { - _stream.WriteBinary(buffer, offset, count); - } - /// /// Writes mpint data into internal buffer. /// @@ -412,5 +388,29 @@ protected void Write(IDictionary data) Write(item.Value, Ascii); } } + + /// + /// Writes data into internal buffer. + /// + /// The data to write. + /// is null. + protected void WriteBinaryString(byte[] buffer) + { + _stream.WriteBinary(buffer); + } + + /// + /// Writes data into internal buffer. + /// + /// An array of bytes. This method write bytes from buffer to the current SSH data stream. + /// The zero-based byte offset in at which to begin writing bytes to the SSH data stream. + /// The number of bytes to be written to the current SSH data stream. + /// is null. + /// The sum of and is greater than the buffer length. + /// or is negative. + protected void WriteBinary(byte[] buffer, int offset, int count) + { + _stream.WriteBinary(buffer, offset, count); + } } } diff --git a/src/Renci.SshNet/Compression/Zlib.cs b/src/Renci.SshNet/Compression/Zlib.cs index b518717a4..0dc5918c4 100644 --- a/src/Renci.SshNet/Compression/Zlib.cs +++ b/src/Renci.SshNet/Compression/Zlib.cs @@ -3,7 +3,7 @@ /// /// Represents "zlib" compression implementation /// - internal class Zlib : Compressor + internal sealed class Zlib : Compressor { /// /// Gets algorithm name. @@ -20,7 +20,8 @@ public override string Name public override void Init(Session session) { base.Init(session); + IsActive = true; } } -} \ No newline at end of file +} diff --git a/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs b/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs index 8f3beb51f..068df230c 100644 --- a/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs +++ b/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs @@ -19,7 +19,7 @@ namespace Renci.SshNet.Connection /// /// https://tools.ietf.org/html/rfc4253#section-4.2. /// - internal class ProtocolVersionExchange : IProtocolVersionExchange + internal sealed class ProtocolVersionExchange : IProtocolVersionExchange { private const byte Null = 0x00; diff --git a/src/Renci.SshNet/Connection/ProxyConnector.cs b/src/Renci.SshNet/Connection/ProxyConnector.cs index 9bbf8b0f2..089ee562a 100644 --- a/src/Renci.SshNet/Connection/ProxyConnector.cs +++ b/src/Renci.SshNet/Connection/ProxyConnector.cs @@ -7,7 +7,7 @@ namespace Renci.SshNet.Connection { internal abstract class ProxyConnector : ConnectorBase { - public ProxyConnector(ISocketFactory socketFactory) + protected ProxyConnector(ISocketFactory socketFactory) : base(socketFactory) { } diff --git a/src/Renci.SshNet/Connection/SocketFactory.cs b/src/Renci.SshNet/Connection/SocketFactory.cs index 8c61b87c6..d279da288 100644 --- a/src/Renci.SshNet/Connection/SocketFactory.cs +++ b/src/Renci.SshNet/Connection/SocketFactory.cs @@ -2,7 +2,7 @@ namespace Renci.SshNet.Connection { - internal class SocketFactory : ISocketFactory + internal sealed class SocketFactory : ISocketFactory { public Socket Create(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) { diff --git a/src/Renci.SshNet/Connection/SshIdentification.cs b/src/Renci.SshNet/Connection/SshIdentification.cs index a950ad71f..931656296 100644 --- a/src/Renci.SshNet/Connection/SshIdentification.cs +++ b/src/Renci.SshNet/Connection/SshIdentification.cs @@ -5,7 +5,7 @@ namespace Renci.SshNet.Connection /// /// Represents an SSH identification. /// - internal class SshIdentification + internal sealed class SshIdentification { /// /// Initializes a new instance of the class with the specified protocol version diff --git a/src/Renci.SshNet/ConnectionInfo.cs b/src/Renci.SshNet/ConnectionInfo.cs index 89abcd63d..e7bd6cdd2 100644 --- a/src/Renci.SshNet/ConnectionInfo.cs +++ b/src/Renci.SshNet/ConnectionInfo.cs @@ -23,7 +23,7 @@ namespace Renci.SshNet /// public class ConnectionInfo : IConnectionInfoInternal { - internal static int DefaultPort = 22; + internal const int DefaultPort = 22; /// /// The default connection timeout. diff --git a/src/Renci.SshNet/ForwardedPortDynamic.NET.cs b/src/Renci.SshNet/ForwardedPortDynamic.NET.cs index eca6f6427..0ae0f4319 100644 --- a/src/Renci.SshNet/ForwardedPortDynamic.NET.cs +++ b/src/Renci.SshNet/ForwardedPortDynamic.NET.cs @@ -38,7 +38,7 @@ partial void InternalStart() // consider port started when we're listening for inbound connections _status = ForwardedPortStatus.Started; - StartAccept(null); + StartAccept(e: null); } private void StartAccept(SocketAsyncEventArgs e) @@ -61,12 +61,12 @@ private void StartAccept(SocketAsyncEventArgs e) { if (!_listener.AcceptAsync(e)) { - AcceptCompleted(null, e); + AcceptCompleted(sender: null, e); } } catch (ObjectDisposedException) { - if (_status == ForwardedPortStatus.Stopped || _status == ForwardedPortStatus.Stopped) + if (_status == ForwardedPortStatus.Stopping || _status == ForwardedPortStatus.Stopped) { // ignore ObjectDisposedException while stopping or stopped return; diff --git a/src/Renci.SshNet/ForwardedPortLocal.NET.cs b/src/Renci.SshNet/ForwardedPortLocal.NET.cs index 3bd9e3f52..ca7ec6261 100644 --- a/src/Renci.SshNet/ForwardedPortLocal.NET.cs +++ b/src/Renci.SshNet/ForwardedPortLocal.NET.cs @@ -33,7 +33,7 @@ partial void InternalStart() // consider port started when we're listening for inbound connections _status = ForwardedPortStatus.Started; - StartAccept(null); + StartAccept(e: null); } private void StartAccept(SocketAsyncEventArgs e) @@ -56,12 +56,12 @@ private void StartAccept(SocketAsyncEventArgs e) { if (!_listener.AcceptAsync(e)) { - AcceptCompleted(null, e); + AcceptCompleted(sender: null, e); } } catch (ObjectDisposedException) { - if (_status == ForwardedPortStatus.Stopped || _status == ForwardedPortStatus.Stopped) + if (_status == ForwardedPortStatus.Stopping || _status == ForwardedPortStatus.Stopped) { // ignore ObjectDisposedException while stopping or stopped return; diff --git a/src/Renci.SshNet/ForwardedPortRemote.cs b/src/Renci.SshNet/ForwardedPortRemote.cs index 4d220c644..ce465e12e 100644 --- a/src/Renci.SshNet/ForwardedPortRemote.cs +++ b/src/Renci.SshNet/ForwardedPortRemote.cs @@ -16,7 +16,7 @@ public class ForwardedPortRemote : ForwardedPort, IDisposable { private ForwardedPortStatus _status; private bool _requestStatus; - private EventWaitHandle _globalRequestResponse = new AutoResetEvent(false); + private EventWaitHandle _globalRequestResponse = new AutoResetEvent(initialState: false); private CountdownEvent _pendingChannelCountdown; private bool _isDisposed; @@ -390,7 +390,7 @@ protected override void Dispose(bool disposing) /// ~ForwardedPortRemote() { - Dispose(false); + Dispose(disposing: false); } } } diff --git a/src/Renci.SshNet/ForwardedPortStatus.cs b/src/Renci.SshNet/ForwardedPortStatus.cs index d82531a1c..2f151e842 100644 --- a/src/Renci.SshNet/ForwardedPortStatus.cs +++ b/src/Renci.SshNet/ForwardedPortStatus.cs @@ -3,7 +3,7 @@ namespace Renci.SshNet { - internal class ForwardedPortStatus + internal sealed class ForwardedPortStatus { public static readonly ForwardedPortStatus Stopped = new ForwardedPortStatus(1, "Stopped"); public static readonly ForwardedPortStatus Stopping = new ForwardedPortStatus(2, "Stopping"); @@ -19,14 +19,14 @@ private ForwardedPortStatus(int value, string name) _name = name; } - public override bool Equals(object other) + public override bool Equals(object obj) { - if (ReferenceEquals(this, other)) + if (ReferenceEquals(this, obj)) { return true; } - if (other is not ForwardedPortStatus forwardedPortStatus) + if (obj is not ForwardedPortStatus forwardedPortStatus) { return false; } diff --git a/src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs b/src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs index 90fc1f283..b559808d1 100644 --- a/src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs +++ b/src/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.cs @@ -17,7 +17,7 @@ public class KeyboardInteractiveAuthenticationMethod : AuthenticationMethod, IDi private readonly RequestMessage _requestMessage; private AuthenticationResult _authenticationResult = AuthenticationResult.Failure; private Session _session; - private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false); + private EventWaitHandle _authenticationCompleted = new AutoResetEvent(initialState: false); private Exception _exception; private bool _isDisposed; diff --git a/src/Renci.SshNet/Messages/Authentication/InformationRequestMessage.cs b/src/Renci.SshNet/Messages/Authentication/InformationRequestMessage.cs index 910a0f55e..c887cc883 100644 --- a/src/Renci.SshNet/Messages/Authentication/InformationRequestMessage.cs +++ b/src/Renci.SshNet/Messages/Authentication/InformationRequestMessage.cs @@ -9,7 +9,7 @@ namespace Renci.SshNet.Messages.Authentication /// Represents SSH_MSG_USERAUTH_INFO_REQUEST message. /// [Message("SSH_MSG_USERAUTH_INFO_REQUEST", 60)] - internal class InformationRequestMessage : Message + internal sealed class InformationRequestMessage : Message { /// /// Gets information request name. diff --git a/src/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs b/src/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs index 5e0c352fb..4aa9cda41 100644 --- a/src/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs +++ b/src/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs @@ -7,7 +7,7 @@ namespace Renci.SshNet.Messages.Authentication /// Represents SSH_MSG_USERAUTH_INFO_RESPONSE message. /// [Message("SSH_MSG_USERAUTH_INFO_RESPONSE", 61)] - internal class InformationResponseMessage : Message + internal sealed class InformationResponseMessage : Message { /// /// Gets authentication responses. diff --git a/src/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs b/src/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs index ac05dffa2..a87b53dfb 100644 --- a/src/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs +++ b/src/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs @@ -4,7 +4,7 @@ /// Represents SSH_MSG_USERAUTH_PASSWD_CHANGEREQ message. /// [Message("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ", 60)] - internal class PasswordChangeRequiredMessage : Message + internal sealed class PasswordChangeRequiredMessage : Message { /// /// Gets password change request message as UTF-8 encoded byte array. diff --git a/src/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs b/src/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs index 9658a2e05..b5582b788 100644 --- a/src/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs +++ b/src/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs @@ -4,7 +4,7 @@ /// Represents SSH_MSG_USERAUTH_PK_OK message. /// [Message("SSH_MSG_USERAUTH_PK_OK", 60)] - internal class PublicKeyMessage : Message + internal sealed class PublicKeyMessage : Message { /// /// Gets the name of the public key algorithm as ASCII encoded byte array. diff --git a/src/Renci.SshNet/Messages/Authentication/RequestMessageKeyboardInteractive.cs b/src/Renci.SshNet/Messages/Authentication/RequestMessageKeyboardInteractive.cs index 6961cb5a3..0b9b0fb68 100644 --- a/src/Renci.SshNet/Messages/Authentication/RequestMessageKeyboardInteractive.cs +++ b/src/Renci.SshNet/Messages/Authentication/RequestMessageKeyboardInteractive.cs @@ -5,7 +5,7 @@ namespace Renci.SshNet.Messages.Authentication /// /// Represents "keyboard-interactive" SSH_MSG_USERAUTH_REQUEST message. /// - internal class RequestMessageKeyboardInteractive : RequestMessage + internal sealed class RequestMessageKeyboardInteractive : RequestMessage { /// /// Gets message language. diff --git a/src/Renci.SshNet/Messages/Authentication/RequestMessageNone.cs b/src/Renci.SshNet/Messages/Authentication/RequestMessageNone.cs index 77cc55f3a..1827c3299 100644 --- a/src/Renci.SshNet/Messages/Authentication/RequestMessageNone.cs +++ b/src/Renci.SshNet/Messages/Authentication/RequestMessageNone.cs @@ -3,7 +3,7 @@ /// /// Represents "none" SSH_MSG_USERAUTH_REQUEST message. /// - internal class RequestMessageNone : RequestMessage + internal sealed class RequestMessageNone : RequestMessage { /// /// Initializes a new instance of the class. diff --git a/src/Renci.SshNet/Messages/Authentication/RequestMessagePassword.cs b/src/Renci.SshNet/Messages/Authentication/RequestMessagePassword.cs index 881617b85..603342c67 100644 --- a/src/Renci.SshNet/Messages/Authentication/RequestMessagePassword.cs +++ b/src/Renci.SshNet/Messages/Authentication/RequestMessagePassword.cs @@ -3,7 +3,7 @@ /// /// Represents "password" SSH_MSG_USERAUTH_REQUEST message. /// - internal class RequestMessagePassword : RequestMessage + internal sealed class RequestMessagePassword : RequestMessage { /// /// Gets authentication password. diff --git a/src/Renci.SshNet/Messages/Connection/CancelTcpIpForwardGlobalRequestMessage.cs b/src/Renci.SshNet/Messages/Connection/CancelTcpIpForwardGlobalRequestMessage.cs index eaf8c6be2..0b3431c06 100644 --- a/src/Renci.SshNet/Messages/Connection/CancelTcpIpForwardGlobalRequestMessage.cs +++ b/src/Renci.SshNet/Messages/Connection/CancelTcpIpForwardGlobalRequestMessage.cs @@ -2,12 +2,12 @@ namespace Renci.SshNet.Messages.Connection { - internal class CancelTcpIpForwardGlobalRequestMessage : GlobalRequestMessage + internal sealed class CancelTcpIpForwardGlobalRequestMessage : GlobalRequestMessage { private byte[] _addressToBind; public CancelTcpIpForwardGlobalRequestMessage(string addressToBind, uint portToBind) - : base(Ascii.GetBytes("cancel-tcpip-forward"), true) + : base(Ascii.GetBytes("cancel-tcpip-forward"), wantReply: true) { AddressToBind = addressToBind; PortToBind = portToBind; diff --git a/src/Renci.SshNet/Messages/Connection/ChannelRequest/EnvironmentVariableRequestInfo.cs b/src/Renci.SshNet/Messages/Connection/ChannelRequest/EnvironmentVariableRequestInfo.cs index 7df594542..6901f3241 100644 --- a/src/Renci.SshNet/Messages/Connection/ChannelRequest/EnvironmentVariableRequestInfo.cs +++ b/src/Renci.SshNet/Messages/Connection/ChannelRequest/EnvironmentVariableRequestInfo.cs @@ -3,7 +3,7 @@ /// /// Represents "env" type channel request information /// - internal class EnvironmentVariableRequestInfo : RequestInfo + internal sealed class EnvironmentVariableRequestInfo : RequestInfo { private byte[] _variableName; private byte[] _variableValue; diff --git a/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitSignalRequestInfo.cs b/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitSignalRequestInfo.cs index 512f3b97d..114bd577f 100644 --- a/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitSignalRequestInfo.cs +++ b/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitSignalRequestInfo.cs @@ -3,7 +3,7 @@ /// /// Represents "exit-signal" type channel request information /// - internal class ExitSignalRequestInfo : RequestInfo + internal sealed class ExitSignalRequestInfo : RequestInfo { private byte[] _signalName; private byte[] _errorMessage; diff --git a/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitStatusRequestInfo.cs b/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitStatusRequestInfo.cs index 96cc1d061..9aa92f96d 100644 --- a/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitStatusRequestInfo.cs +++ b/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExitStatusRequestInfo.cs @@ -3,7 +3,7 @@ /// /// Represents "exit-status" type channel request information /// - internal class ExitStatusRequestInfo : RequestInfo + internal sealed class ExitStatusRequestInfo : RequestInfo { /// /// Channel request name. diff --git a/src/Renci.SshNet/Messages/Connection/ChannelRequest/PseudoTerminalInfo.cs b/src/Renci.SshNet/Messages/Connection/ChannelRequest/PseudoTerminalInfo.cs index af57bb2d7..fbe5a11dd 100644 --- a/src/Renci.SshNet/Messages/Connection/ChannelRequest/PseudoTerminalInfo.cs +++ b/src/Renci.SshNet/Messages/Connection/ChannelRequest/PseudoTerminalInfo.cs @@ -7,7 +7,7 @@ namespace Renci.SshNet.Messages.Connection /// /// Represents "pty-req" type channel request information. /// - internal class PseudoTerminalRequestInfo : RequestInfo + internal sealed class PseudoTerminalRequestInfo : RequestInfo { /// /// Channel request name. diff --git a/src/Renci.SshNet/Messages/Connection/TcpIpForwardGlobalRequestMessage.cs b/src/Renci.SshNet/Messages/Connection/TcpIpForwardGlobalRequestMessage.cs index fdfbfb8df..edddcb567 100644 --- a/src/Renci.SshNet/Messages/Connection/TcpIpForwardGlobalRequestMessage.cs +++ b/src/Renci.SshNet/Messages/Connection/TcpIpForwardGlobalRequestMessage.cs @@ -7,7 +7,7 @@ internal sealed class TcpIpForwardGlobalRequestMessage : GlobalRequestMessage private byte[] _addressToBind; public TcpIpForwardGlobalRequestMessage(string addressToBind, uint portToBind) - : base(Ascii.GetBytes("tcpip-forward"), true) + : base(Ascii.GetBytes("tcpip-forward"), wantReply: true) { AddressToBind = addressToBind; PortToBind = portToBind; diff --git a/src/Renci.SshNet/Netconf/NetConfSession.cs b/src/Renci.SshNet/Netconf/NetConfSession.cs index 6e6f8c6c8..f1252f539 100644 --- a/src/Renci.SshNet/Netconf/NetConfSession.cs +++ b/src/Renci.SshNet/Netconf/NetConfSession.cs @@ -9,7 +9,7 @@ namespace Renci.SshNet.NetConf { - internal class NetConfSession : SubsystemSession, INetConfSession + internal sealed class NetConfSession : SubsystemSession, INetConfSession { private const string Prompt = "]]>]]>"; diff --git a/src/Renci.SshNet/NoneAuthenticationMethod.cs b/src/Renci.SshNet/NoneAuthenticationMethod.cs index 71e100175..99d025249 100644 --- a/src/Renci.SshNet/NoneAuthenticationMethod.cs +++ b/src/Renci.SshNet/NoneAuthenticationMethod.cs @@ -12,7 +12,7 @@ namespace Renci.SshNet public class NoneAuthenticationMethod : AuthenticationMethod, IDisposable { private AuthenticationResult _authenticationResult = AuthenticationResult.Failure; - private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false); + private EventWaitHandle _authenticationCompleted = new AutoResetEvent(initialState: false); private bool _isDisposed; /// diff --git a/src/Renci.SshNet/PasswordAuthenticationMethod.cs b/src/Renci.SshNet/PasswordAuthenticationMethod.cs index 5c7e8aaa9..ffa8213d8 100644 --- a/src/Renci.SshNet/PasswordAuthenticationMethod.cs +++ b/src/Renci.SshNet/PasswordAuthenticationMethod.cs @@ -18,7 +18,7 @@ public class PasswordAuthenticationMethod : AuthenticationMethod, IDisposable private readonly byte[] _password; private AuthenticationResult _authenticationResult = AuthenticationResult.Failure; private Session _session; - private EventWaitHandle _authenticationCompleted = new AutoResetEvent(false); + private EventWaitHandle _authenticationCompleted = new AutoResetEvent(initialState: false); private Exception _exception; private bool _isDisposed; diff --git a/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs b/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs index 1606ef757..960a68b20 100644 --- a/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs +++ b/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs @@ -15,7 +15,7 @@ namespace Renci.SshNet public class PrivateKeyAuthenticationMethod : AuthenticationMethod, IDisposable { private AuthenticationResult _authenticationResult = AuthenticationResult.Failure; - private EventWaitHandle _authenticationCompleted = new ManualResetEvent(false); + private EventWaitHandle _authenticationCompleted = new ManualResetEvent(initialState: false); private bool _isSignatureRequired; private bool _isDisposed; diff --git a/src/Renci.SshNet/PrivateKeyFile.cs b/src/Renci.SshNet/PrivateKeyFile.cs index e00a27fcd..3a2dbe049 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -400,7 +400,7 @@ private static byte[] DecryptKey(CipherInfo cipherInfo, byte[] cipherData, strin /// /// The OpenSSH V1 key. /// - private Key ParseOpenSshV1Key(byte[] keyFileData, string passPhrase) + private static Key ParseOpenSshV1Key(byte[] keyFileData, string passPhrase) { var keyReader = new SshDataReader(keyFileData); @@ -424,9 +424,9 @@ private Key ParseOpenSshV1Key(byte[] keyFileData, string passPhrase) var rounds = 0; if (kdfOptionsLen > 0) { - var saltLength = (int)keyReader.ReadUInt32(); + var saltLength = (int) keyReader.ReadUInt32(); salt = keyReader.ReadBytes(saltLength); - rounds = (int)keyReader.ReadUInt32(); + rounds = (int) keyReader.ReadUInt32(); } // number of public keys, only supporting 1 for now @@ -440,7 +440,7 @@ private Key ParseOpenSshV1Key(byte[] keyFileData, string passPhrase) _ = keyReader.ReadString(Encoding.UTF8); // possibly encrypted private key - var privateKeyLength = (int)keyReader.ReadUInt32(); + var privateKeyLength = (int) keyReader.ReadUInt32(); var privateKeyBytes = keyReader.ReadBytes(privateKeyLength); // decrypt private key if necessary @@ -602,7 +602,7 @@ protected virtual void Dispose(bool disposing) Dispose(disposing: false); } - private class SshDataReader : SshData + private sealed class SshDataReader : SshData { public SshDataReader(byte[] data) { diff --git a/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs b/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs index 68abce256..74413eac1 100644 --- a/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs +++ b/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs @@ -6,7 +6,7 @@ namespace Renci.SshNet /// /// Encloses a path in double quotes, and escapes any embedded double quote with a backslash. /// - internal class RemotePathDoubleQuoteTransformation : IRemotePathTransformation + internal sealed class RemotePathDoubleQuoteTransformation : IRemotePathTransformation { /// /// Encloses a path in double quotes, and escapes any embedded double quote with a backslash. diff --git a/src/Renci.SshNet/RemotePathNoneTransformation.cs b/src/Renci.SshNet/RemotePathNoneTransformation.cs index 31dea7a87..d1937514f 100644 --- a/src/Renci.SshNet/RemotePathNoneTransformation.cs +++ b/src/Renci.SshNet/RemotePathNoneTransformation.cs @@ -5,7 +5,7 @@ namespace Renci.SshNet /// /// Performs no transformation. /// - internal class RemotePathNoneTransformation : IRemotePathTransformation + internal sealed class RemotePathNoneTransformation : IRemotePathTransformation { /// /// Returns the specified path without applying a transformation. diff --git a/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs b/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs index 9f247ccff..7d02d29d6 100644 --- a/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs +++ b/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs @@ -6,7 +6,7 @@ namespace Renci.SshNet /// /// Quotes a path in a way to be suitable to be used with a shell-based server. /// - internal class RemotePathShellQuoteTransformation : IRemotePathTransformation + internal sealed class RemotePathShellQuoteTransformation : IRemotePathTransformation { /// /// Quotes a path in a way to be suitable to be used with a shell-based server. diff --git a/src/Renci.SshNet/Security/BouncyCastle/.editorconfig b/src/Renci.SshNet/Security/BouncyCastle/.editorconfig index 265666760..9440813d4 100644 --- a/src/Renci.SshNet/Security/BouncyCastle/.editorconfig +++ b/src/Renci.SshNet/Security/BouncyCastle/.editorconfig @@ -2,6 +2,5 @@ generated_code = true -# IDE0005: Remove unnecessary using directives -# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005 -dotnet_diagnostic.IDE0005.severity = none +# Do not reported any diagnostics for "imported" code +dotnet_analyzer_diagnostic.severity = none diff --git a/src/Renci.SshNet/Security/Chaos.NaCl/.editorconfig b/src/Renci.SshNet/Security/Chaos.NaCl/.editorconfig index 265666760..9440813d4 100644 --- a/src/Renci.SshNet/Security/Chaos.NaCl/.editorconfig +++ b/src/Renci.SshNet/Security/Chaos.NaCl/.editorconfig @@ -2,6 +2,5 @@ generated_code = true -# IDE0005: Remove unnecessary using directives -# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005 -dotnet_diagnostic.IDE0005.severity = none +# Do not reported any diagnostics for "imported" code +dotnet_analyzer_diagnostic.severity = none diff --git a/src/Renci.SshNet/Security/Cryptography/BlockCipher.cs b/src/Renci.SshNet/Security/Cryptography/BlockCipher.cs index 5a06d7a37..62050068d 100644 --- a/src/Renci.SshNet/Security/Cryptography/BlockCipher.cs +++ b/src/Renci.SshNet/Security/Cryptography/BlockCipher.cs @@ -66,11 +66,11 @@ protected BlockCipher(byte[] key, byte blockSize, CipherMode mode, CipherPadding /// /// Encrypts the specified data. /// - /// The data. - /// The zero-based offset in at which to begin encrypting. - /// The number of bytes to encrypt from . + /// The data. + /// The zero-based offset in at which to begin encrypting. + /// The number of bytes to encrypt from . /// Encrypted data - public override byte[] Encrypt(byte[] data, int offset, int length) + public override byte[] Encrypt(byte[] input, int offset, int length) { if (length % _blockSize > 0) { @@ -80,7 +80,7 @@ public override byte[] Encrypt(byte[] data, int offset, int length) } var paddingLength = _blockSize - (length % _blockSize); - data = _padding.Pad(data, offset, length, paddingLength); + input = _padding.Pad(input, offset, length, paddingLength); length += paddingLength; offset = 0; } @@ -92,11 +92,11 @@ public override byte[] Encrypt(byte[] data, int offset, int length) { if (_mode is null) { - writtenBytes += EncryptBlock(data, offset + (i * _blockSize), _blockSize, output, i * _blockSize); + writtenBytes += EncryptBlock(input, offset + (i * _blockSize), _blockSize, output, i * _blockSize); } else { - writtenBytes += _mode.EncryptBlock(data, offset + (i * _blockSize), _blockSize, output, i * _blockSize); + writtenBytes += _mode.EncryptBlock(input, offset + (i * _blockSize), _blockSize, output, i * _blockSize); } } @@ -111,23 +111,23 @@ public override byte[] Encrypt(byte[] data, int offset, int length) /// /// Decrypts the specified data. /// - /// The data. + /// The data. /// Decrypted data - public override byte[] Decrypt(byte[] data) + public override byte[] Decrypt(byte[] input) { - return Decrypt(data, 0, data.Length); + return Decrypt(input, 0, input.Length); } /// /// Decrypts the specified input. /// - /// The input. - /// The zero-based offset in at which to begin decrypting. - /// The number of bytes to decrypt from . + /// The input. + /// The zero-based offset in at which to begin decrypting. + /// The number of bytes to decrypt from . /// /// The decrypted data. /// - public override byte[] Decrypt(byte[] data, int offset, int length) + public override byte[] Decrypt(byte[] input, int offset, int length) { if (length % _blockSize > 0) { @@ -136,9 +136,9 @@ public override byte[] Decrypt(byte[] data, int offset, int length) throw new ArgumentException("data"); } - data = _padding.Pad(_blockSize, data, offset, length); + input = _padding.Pad(_blockSize, input, offset, length); offset = 0; - length = data.Length; + length = input.Length; } var output = new byte[length]; @@ -148,11 +148,11 @@ public override byte[] Decrypt(byte[] data, int offset, int length) { if (_mode is null) { - writtenBytes += DecryptBlock(data, offset + (i * _blockSize), _blockSize, output, i * _blockSize); + writtenBytes += DecryptBlock(input, offset + (i * _blockSize), _blockSize, output, i * _blockSize); } else { - writtenBytes += _mode.DecryptBlock(data, offset + (i * _blockSize), _blockSize, output, i * _blockSize); + writtenBytes += _mode.DecryptBlock(input, offset + (i * _blockSize), _blockSize, output, i * _blockSize); } } diff --git a/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs b/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs index 29e4c42e7..19fd1cd7f 100644 --- a/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs +++ b/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.cs @@ -606,7 +606,7 @@ public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputC throw new IndexOutOfRangeException("output buffer too short"); } - _encryptionKey ??= GenerateWorkingKey(true, Key); + _encryptionKey ??= GenerateWorkingKey(isEncryption: true, Key); UnPackBlock(inputBuffer, inputOffset); @@ -652,7 +652,7 @@ public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputC throw new IndexOutOfRangeException("output buffer too short"); } - _decryptionKey ??= GenerateWorkingKey(false, Key); + _decryptionKey ??= GenerateWorkingKey(isEncryption: false, Key); UnPackBlock(inputBuffer, inputOffset); diff --git a/src/Renci.SshNet/Security/Cryptography/Ciphers/Arc4Cipher.cs b/src/Renci.SshNet/Security/Cryptography/Ciphers/Arc4Cipher.cs index fc2174bf9..9a2562878 100644 --- a/src/Renci.SshNet/Security/Cryptography/Ciphers/Arc4Cipher.cs +++ b/src/Renci.SshNet/Security/Cryptography/Ciphers/Arc4Cipher.cs @@ -18,8 +18,6 @@ public sealed class Arc4Cipher : StreamCipher private int _y; - private byte[] _workingKey; - /// /// Gets the minimum data size. /// @@ -40,12 +38,10 @@ public override byte MinimumSize public Arc4Cipher(byte[] key, bool dischargeFirstBytes) : base(key) { - _workingKey = key; - SetKey(_workingKey); - // The first 1536 bytes of keystream - // generated by the cipher MUST be discarded, and the first byte of the - // first encrypted packet MUST be encrypted using the 1537th byte of - // keystream. + SetKey(key); + + // The first 1536 bytes of keystream generated by the cipher MUST be discarded, and the first byte of the + // first encrypted packet MUST be encrypted using the 1537th byte of keystream. if (dischargeFirstBytes) { _ = Encrypt(new byte[1536]); @@ -159,8 +155,6 @@ private int ProcessBytes(byte[] inputBuffer, int inputOffset, int inputCount, by private void SetKey(byte[] keyBytes) { - _workingKey = keyBytes; - _x = 0; _y = 0; diff --git a/src/Renci.SshNet/Security/Cryptography/Ciphers/DesCipher.cs b/src/Renci.SshNet/Security/Cryptography/Ciphers/DesCipher.cs index 1fbe5bc4b..29097eea7 100644 --- a/src/Renci.SshNet/Security/Cryptography/Ciphers/DesCipher.cs +++ b/src/Renci.SshNet/Security/Cryptography/Ciphers/DesCipher.cs @@ -245,7 +245,7 @@ public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputC throw new IndexOutOfRangeException("output buffer too short"); } - _encryptionKey ??= GenerateWorkingKey(true, Key); + _encryptionKey ??= GenerateWorkingKey(encrypting: true, Key); DesFunc(_encryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset); @@ -275,7 +275,7 @@ public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputC throw new IndexOutOfRangeException("output buffer too short"); } - _decryptionKey ??= GenerateWorkingKey(false, Key); + _decryptionKey ??= GenerateWorkingKey(encrypting: false, Key); DesFunc(_decryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset); diff --git a/src/Renci.SshNet/Security/Cryptography/Ciphers/RsaCipher.cs b/src/Renci.SshNet/Security/Cryptography/Ciphers/RsaCipher.cs index d3644ba3b..fda7fc5b5 100644 --- a/src/Renci.SshNet/Security/Cryptography/Ciphers/RsaCipher.cs +++ b/src/Renci.SshNet/Security/Cryptography/Ciphers/RsaCipher.cs @@ -30,11 +30,11 @@ public RsaCipher(RsaKey key) /// /// Encrypts the specified data. /// - /// The data. - /// The zero-based offset in at which to begin encrypting. - /// The number of bytes to encrypt from . + /// The data. + /// The zero-based offset in at which to begin encrypting. + /// The number of bytes to encrypt from . /// Encrypted data. - public override byte[] Encrypt(byte[] data, int offset, int length) + public override byte[] Encrypt(byte[] input, int offset, int length) { // Calculate signature var bitLength = _key.Modulus.BitLength; @@ -47,7 +47,7 @@ public override byte[] Encrypt(byte[] data, int offset, int length) paddedBlock[i] = 0xFF; } - Buffer.BlockCopy(data, offset, paddedBlock, paddedBlock.Length - length, length); + Buffer.BlockCopy(input, offset, paddedBlock, paddedBlock.Length - length, length); return Transform(paddedBlock); } @@ -55,31 +55,31 @@ public override byte[] Encrypt(byte[] data, int offset, int length) /// /// Decrypts the specified data. /// - /// The data. + /// The data. /// /// The decrypted data. /// /// Only block type 01 or 02 are supported. /// Thrown when decrypted block type is not supported. - public override byte[] Decrypt(byte[] data) + public override byte[] Decrypt(byte[] input) { - return Decrypt(data, 0, data.Length); + return Decrypt(input, 0, input.Length); } /// /// Decrypts the specified input. /// - /// The input. - /// The zero-based offset in at which to begin decrypting. - /// The number of bytes to decrypt from . + /// The input. + /// The zero-based offset in at which to begin decrypting. + /// The number of bytes to decrypt from . /// /// The decrypted data. /// /// Only block type 01 or 02 are supported. /// Thrown when decrypted block type is not supported. - public override byte[] Decrypt(byte[] data, int offset, int length) + public override byte[] Decrypt(byte[] input, int offset, int length) { - var paddedBlock = Transform(data, offset, length); + var paddedBlock = Transform(input, offset, length); if (paddedBlock[0] is not 1 and not 2) { diff --git a/src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs b/src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs index 3d52e2a26..644d44720 100644 --- a/src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs +++ b/src/Renci.SshNet/Security/Cryptography/Ciphers/TripleDesCipher.cs @@ -57,16 +57,15 @@ public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputC Buffer.BlockCopy(Key, 0, part1, 0, 8); Buffer.BlockCopy(Key, 8, part2, 0, 8); - _encryptionKey1 = GenerateWorkingKey(true, part1); - - _encryptionKey2 = GenerateWorkingKey(false, part2); + _encryptionKey1 = GenerateWorkingKey(encrypting: true, part1); + _encryptionKey2 = GenerateWorkingKey(encrypting: false, part2); if (Key.Length == 24) { var part3 = new byte[8]; Buffer.BlockCopy(Key, 16, part3, 0, 8); - _encryptionKey3 = GenerateWorkingKey(true, part3); + _encryptionKey3 = GenerateWorkingKey(encrypting: true, part3); } else { @@ -114,15 +113,15 @@ public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputC Buffer.BlockCopy(Key, 0, part1, 0, 8); Buffer.BlockCopy(Key, 8, part2, 0, 8); - _decryptionKey1 = GenerateWorkingKey(false, part1); - _decryptionKey2 = GenerateWorkingKey(true, part2); + _decryptionKey1 = GenerateWorkingKey(encrypting: false, part1); + _decryptionKey2 = GenerateWorkingKey(encrypting: true, part2); if (Key.Length == 24) { var part3 = new byte[8]; Buffer.BlockCopy(Key, 16, part3, 0, 8); - _decryptionKey3 = GenerateWorkingKey(false, part3); + _decryptionKey3 = GenerateWorkingKey(encrypting: false, part3); } else { diff --git a/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs b/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs index 48446c52d..93fc6ba4a 100644 --- a/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs +++ b/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs @@ -108,7 +108,7 @@ protected virtual void Dispose(bool disposing) } } - internal class SshDataSignature : SshData + internal sealed class SshDataSignature : SshData { private readonly int _signature_size; diff --git a/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs b/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs index 3de4beac5..0958ef0ce 100644 --- a/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs +++ b/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs @@ -28,7 +28,7 @@ public class EcdsaKey : Key, IDisposable #if NETFRAMEWORK private CngKey _key; - internal enum KeyBlobMagicNumber : int + internal enum KeyBlobMagicNumber { BCRYPT_ECDSA_PUBLIC_P256_MAGIC = 0x31534345, BCRYPT_ECDSA_PRIVATE_P256_MAGIC = 0x32534345, @@ -180,7 +180,7 @@ public override BigInteger[] Public } #pragma warning restore IDE0010 // Add missing cases #else - var parameter = Ecdsa.ExportParameters(false); + var parameter = Ecdsa.ExportParameters(includePrivateParameters: false); qx = parameter.Q.X; qy = parameter.Q.Y; switch (parameter.Curve.Oid.FriendlyName) @@ -218,7 +218,7 @@ public override BigInteger[] Public var curve_oid = GetCurveOid(curve_s); var publickey = value[1].ToByteArray().Reverse(); - Import(curve_oid, publickey, null); + Import(curve_oid, publickey, privatekey: null); } } @@ -278,7 +278,7 @@ public EcdsaKey(byte[] data) var construct = der.ReadBytes(der.ReadLength()); // object length // curve OID - var curve_der = new DerData(construct, true); + var curve_der = new DerData(construct, construct: true); var curve = curve_der.ReadObject(); // Construct @@ -297,7 +297,7 @@ public EcdsaKey(byte[] data) construct = der.ReadBytes(der.ReadLength()); // object length // PublicKey - var pubkey_der = new DerData(construct, true); + var pubkey_der = new DerData(construct, construct: true); var pubkey = pubkey_der.ReadBitString().TrimLeadingZeros(); Import(OidByteArrayToString(curve), pubkey, privatekey); @@ -306,7 +306,8 @@ public EcdsaKey(byte[] data) private void Import(string curve_oid, byte[] publickey, byte[] privatekey) { #if NETFRAMEWORK - var curve_magic = KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC; + KeyBlobMagicNumber curve_magic; + switch (GetCurveName(curve_oid)) { case "nistp256": @@ -426,7 +427,7 @@ private static string GetCurveOid(string curve_s) } #if NETFRAMEWORK - private string GetCurveName(string oid) + private static string GetCurveName(string oid) { switch (oid) { diff --git a/src/Renci.SshNet/Security/Cryptography/RsaDigitalSignature.cs b/src/Renci.SshNet/Security/Cryptography/RsaDigitalSignature.cs index 25a375f6b..9af398b46 100644 --- a/src/Renci.SshNet/Security/Cryptography/RsaDigitalSignature.cs +++ b/src/Renci.SshNet/Security/Cryptography/RsaDigitalSignature.cs @@ -44,7 +44,7 @@ protected override byte[] Hash(byte[] input) /// public void Dispose() { - Dispose(true); + Dispose(disposing: true); GC.SuppressFinalize(this); } @@ -78,7 +78,7 @@ protected virtual void Dispose(bool disposing) /// ~RsaDigitalSignature() { - Dispose(false); + Dispose(disposing: false); } #endregion diff --git a/src/Renci.SshNet/Security/Cryptography/RsaKey.cs b/src/Renci.SshNet/Security/Cryptography/RsaKey.cs index 6d0180114..dbb5ebb02 100644 --- a/src/Renci.SshNet/Security/Cryptography/RsaKey.cs +++ b/src/Renci.SshNet/Security/Cryptography/RsaKey.cs @@ -244,7 +244,7 @@ private static BigInteger PrimeExponent(BigInteger privateExponent, BigInteger p /// public void Dispose() { - Dispose(true); + Dispose(disposing: true); GC.SuppressFinalize(this); } @@ -278,7 +278,7 @@ protected virtual void Dispose(bool disposing) /// ~RsaKey() { - Dispose(false); + Dispose(disposing: false); } } } diff --git a/src/Renci.SshNet/Security/GroupExchangeHashData.cs b/src/Renci.SshNet/Security/GroupExchangeHashData.cs index 12b5fbf11..82b889bb8 100644 --- a/src/Renci.SshNet/Security/GroupExchangeHashData.cs +++ b/src/Renci.SshNet/Security/GroupExchangeHashData.cs @@ -3,7 +3,7 @@ namespace Renci.SshNet.Security { - internal class GroupExchangeHashData : SshData + internal sealed class GroupExchangeHashData : SshData { private byte[] _serverVersion; private byte[] _clientVersion; diff --git a/src/Renci.SshNet/Security/KeyExchange.cs b/src/Renci.SshNet/Security/KeyExchange.cs index 194358271..771ac6bf4 100644 --- a/src/Renci.SshNet/Security/KeyExchange.cs +++ b/src/Renci.SshNet/Security/KeyExchange.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; + using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Compression; @@ -483,7 +484,7 @@ protected override void SaveData() /// public void Dispose() { - Dispose(true); + Dispose(disposing: true); GC.SuppressFinalize(this); } @@ -501,7 +502,7 @@ protected virtual void Dispose(bool disposing) /// ~KeyExchange() { - Dispose(false); + Dispose(disposing: false); } #endregion diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs index 3302d9a94..2e286345c 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchangeSha256.cs @@ -29,15 +29,15 @@ protected override int HashSize /// /// Hashes the specified data bytes. /// - /// Data to hash. + /// Data to hash. /// /// The hash of the data. /// - protected override byte[] Hash(byte[] hashBytes) + protected override byte[] Hash(byte[] hashData) { using (var sha256 = CryptoAbstraction.CreateSHA256()) { - return sha256.ComputeHash(hashBytes); + return sha256.ComputeHash(hashData); } } } diff --git a/src/Renci.SshNet/ServiceFactory.cs b/src/Renci.SshNet/ServiceFactory.cs index 210df0229..16568faf2 100644 --- a/src/Renci.SshNet/ServiceFactory.cs +++ b/src/Renci.SshNet/ServiceFactory.cs @@ -122,10 +122,10 @@ public ISftpFileReader CreateSftpFileReader(string fileName, ISftpSession sftpSe // Issue #292: Avoid overlapping SSH_FXP_OPEN and SSH_FXP_LSTAT requests for the same file as this // causes a performance degradation on Sun SSH - var openAsyncResult = sftpSession.BeginOpen(fileName, Flags.Read, null, null); + var openAsyncResult = sftpSession.BeginOpen(fileName, Flags.Read, callback: null, state: null); var handle = sftpSession.EndOpen(openAsyncResult); - var statAsyncResult = sftpSession.BeginLStat(fileName, null, null); + var statAsyncResult = sftpSession.BeginLStat(fileName, callback: null, state: null); long? fileSize; int maxPendingReads; diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index 02013bd22..9fec6bd7e 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -870,23 +870,6 @@ void ISession.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout) WaitOnHandle(waitHandle, timeout); } - /// - /// Waits for the specified handle or the exception handle for the receive thread - /// to signal within the connection timeout. - /// - /// The wait handle. - /// A received package was invalid or failed the message integrity check. - /// None of the handles are signaled in time and the session is not disconnecting. - /// A socket error was signaled while receiving messages from the server. - /// - /// When neither handles are signaled in time and the session is not closing, then the - /// session is disconnected. - /// - internal void WaitOnHandle(WaitHandle waitHandle) - { - WaitOnHandle(waitHandle, ConnectionInfo.Timeout); - } - /// /// Waits for the specified to receive a signal, using a /// to specify the time interval. @@ -965,6 +948,23 @@ private WaitResult TryWait(WaitHandle waitHandle, TimeSpan timeout, out Exceptio } } + /// + /// Waits for the specified handle or the exception handle for the receive thread + /// to signal within the connection timeout. + /// + /// The wait handle. + /// A received package was invalid or failed the message integrity check. + /// None of the handles are signaled in time and the session is not disconnecting. + /// A socket error was signaled while receiving messages from the server. + /// + /// When neither handles are signaled in time and the session is not closing, then the + /// session is disconnected. + /// + internal void WaitOnHandle(WaitHandle waitHandle) + { + WaitOnHandle(waitHandle, ConnectionInfo.Timeout); + } + /// /// Waits for the specified handle or the exception handle for the receive thread /// to signal within the specified timeout. @@ -1869,8 +1869,7 @@ private void MessageListener() var message = ReceiveMessage(socket); if (message is null) { - // connection with SSH server was closed; - // break out of the message loop + // Connection with SSH server was closed, so break out of the message loop break; } diff --git a/src/Renci.SshNet/Sftp/Requests/ExtendedRequests/FStatVfsRequest.cs b/src/Renci.SshNet/Sftp/Requests/ExtendedRequests/FStatVfsRequest.cs index 49341e89a..685c03692 100644 --- a/src/Renci.SshNet/Sftp/Requests/ExtendedRequests/FStatVfsRequest.cs +++ b/src/Renci.SshNet/Sftp/Requests/ExtendedRequests/FStatVfsRequest.cs @@ -4,7 +4,7 @@ namespace Renci.SshNet.Sftp.Requests { - internal class FStatVfsRequest : SftpExtendedRequest + internal sealed class FStatVfsRequest : SftpExtendedRequest { private readonly Action _extendedReplyAction; diff --git a/src/Renci.SshNet/Sftp/Responses/SftpExtendedReplyResponse.cs b/src/Renci.SshNet/Sftp/Responses/SftpExtendedReplyResponse.cs index 1a7048ec5..bbd41680f 100644 --- a/src/Renci.SshNet/Sftp/Responses/SftpExtendedReplyResponse.cs +++ b/src/Renci.SshNet/Sftp/Responses/SftpExtendedReplyResponse.cs @@ -1,6 +1,6 @@ namespace Renci.SshNet.Sftp.Responses { - internal class SftpExtendedReplyResponse : SftpResponse + internal sealed class SftpExtendedReplyResponse : SftpResponse { public override SftpMessageTypes SftpMessageType { diff --git a/src/Renci.SshNet/Sftp/SftpFileReader.cs b/src/Renci.SshNet/Sftp/SftpFileReader.cs index ca8ed29d1..9d44bb330 100644 --- a/src/Renci.SshNet/Sftp/SftpFileReader.cs +++ b/src/Renci.SshNet/Sftp/SftpFileReader.cs @@ -8,7 +8,7 @@ namespace Renci.SshNet.Sftp { - internal class SftpFileReader : ISftpFileReader + internal sealed class SftpFileReader : ISftpFileReader { private const int ReadAheadWaitTimeoutInMilliseconds = 1000; @@ -64,8 +64,8 @@ public SftpFileReader(byte[] handle, ISftpSession sftpSession, uint chunkSize, i _semaphore = new SemaphoreLight(maxPendingReads); _queue = new Dictionary(maxPendingReads); _readLock = new object(); - _readAheadCompleted = new ManualResetEvent(false); - _disposingWaitHandle = new ManualResetEvent(false); + _readAheadCompleted = new ManualResetEvent(initialState: false); + _disposingWaitHandle = new ManualResetEvent(initialState: false); _waitHandles = _sftpSession.CreateWaitHandleArray(_disposingWaitHandle, _semaphore.AvailableWaitHandle); StartReadAhead(); @@ -78,7 +78,7 @@ public byte[] Read() throw new ObjectDisposedException(GetType().FullName); } - if (_exception != null) + if (_exception is not null) { throw _exception; } @@ -133,9 +133,9 @@ public byte[] Read() return data; } - // when we received an EOF for the next chunk and the size of the file is known, then - // we only complete the current chunk if we haven't already read up to the file size; - // this way we save an extra round-trip to the server + // When we received an EOF for the next chunk and the size of the file is known, then + // we only complete the current chunk if we haven't already read up to the file size. + // This way we save an extra round-trip to the server. if (data.Length == 0 && _fileSize.HasValue && _offset == (ulong) _fileSize.Value) { // avoid future reads @@ -214,12 +214,12 @@ public byte[] Read() ~SftpFileReader() { - Dispose(false); + Dispose(disposing: false); } public void Dispose() { - Dispose(true); + Dispose(disposing: true); GC.SuppressFinalize(this); } @@ -227,7 +227,7 @@ public void Dispose() /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected void Dispose(bool disposing) + private void Dispose(bool disposing) { if (_disposingOrDisposed) { @@ -266,7 +266,7 @@ protected void Dispose(bool disposing) { try { - var closeAsyncResult = _sftpSession.BeginClose(_handle, null, null); + var closeAsyncResult = _sftpSession.BeginClose(_handle, callback: null, state: null); _sftpSession.EndClose(closeAsyncResult); } catch (Exception ex) @@ -329,7 +329,7 @@ private void StartReadAhead() // mode to avoid having multiple read-aheads that read beyond EOF if (_fileSize != null && (long) _readAheadOffset > _fileSize.Value) { - var asyncResult = _sftpSession.BeginRead(_handle, _readAheadOffset, _chunkSize, null, bufferedRead); + var asyncResult = _sftpSession.BeginRead(_handle, _readAheadOffset, _chunkSize, callback: null, bufferedRead); var data = _sftpSession.EndRead(asyncResult); ReadCompletedCore(bufferedRead, data); } @@ -421,8 +421,8 @@ private void ReadCompletedCore(BufferedRead bufferedRead, byte[] data) // add item to queue _queue.Add(bufferedRead.ChunkIndex, bufferedRead); - // signal that a chunk has been read or EOF has been reached; - // in both cases, Read() will eventually also unblock the "read-ahead" thread + // Signal that a chunk has been read or EOF has been reached. + // In both cases, Read() will eventually also unblock the "read-ahead" thread. Monitor.PulseAll(_readLock); } diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index 26e22ee88..a17d5b8ee 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -193,8 +193,8 @@ private SftpFileStream(ISftpSession session, string path, FileAccess access, int * or SSH_FXP_WRITE message. */ - _readBufferSize = (int) session.CalculateOptimalReadLength((uint)bufferSize); - _writeBufferSize = (int) session.CalculateOptimalWriteLength((uint)bufferSize, _handle); + _readBufferSize = (int) session.CalculateOptimalReadLength((uint) bufferSize); + _writeBufferSize = (int) session.CalculateOptimalWriteLength((uint) bufferSize, _handle); _position = position; } diff --git a/src/Renci.SshNet/Sftp/SftpSession.cs b/src/Renci.SshNet/Sftp/SftpSession.cs index c43a7af96..77355d4a5 100644 --- a/src/Renci.SshNet/Sftp/SftpSession.cs +++ b/src/Renci.SshNet/Sftp/SftpSession.cs @@ -11,7 +11,7 @@ namespace Renci.SshNet.Sftp { - internal class SftpSession : SubsystemSession, ISftpSession + internal sealed class SftpSession : SubsystemSession, ISftpSession { internal const int MaximumSupportedVersion = 3; private const int MinimumSupportedVersion = 0; @@ -19,14 +19,10 @@ internal class SftpSession : SubsystemSession, ISftpSession private readonly Dictionary _requests = new Dictionary(); private readonly ISftpResponseFactory _sftpResponseFactory; private readonly List _data = new List(32 * 1024); + private readonly Encoding _encoding; private EventWaitHandle _sftpVersionConfirmed = new AutoResetEvent(initialState: false); private IDictionary _supportedExtensions; - /// - /// Gets the character encoding to use. - /// - protected Encoding Encoding { get; private set; } - /// /// Gets the remote working directory. /// @@ -66,7 +62,7 @@ public uint NextRequestId public SftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpResponseFactory) : base(session, "sftp", operationTimeout) { - Encoding = encoding; + _encoding = encoding; _sftpResponseFactory = sftpResponseFactory; } @@ -363,7 +359,7 @@ protected override void OnDataReceived(byte[] data) private bool TryLoadSftpMessage(byte[] packetData, int offset, int count) { // Create SFTP message - var response = _sftpResponseFactory.Create(ProtocolVersion, packetData[offset], Encoding); + var response = _sftpResponseFactory.Create(ProtocolVersion, packetData[offset], _encoding); // Load message data into it response.Load(packetData, offset + 1, count - 1); @@ -433,7 +429,7 @@ public byte[] RequestOpen(string path, Flags flags, bool nullOnError = false) var request = new SftpOpenRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, flags, response => { @@ -470,7 +466,7 @@ public async Task RequestOpenAsync(string path, Flags flags, Cancellatio SendRequest(new SftpOpenRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, flags, response => tcs.TrySetResult(response.Handle), response => tcs.TrySetException(GetSftpException(response)))); @@ -496,7 +492,7 @@ public SftpOpenAsyncResult BeginOpen(string path, Flags flags, AsyncCallback cal var request = new SftpOpenRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, flags, response => { @@ -624,7 +620,7 @@ public SftpCloseAsyncResult BeginClose(byte[] handle, AsyncCallback callback, ob handle, response => { - asyncResult.SetAsCompleted(GetSftpException(response), false); + asyncResult.SetAsCompleted(GetSftpException(response), completedSynchronously: false); }); SendRequest(request); @@ -919,7 +915,7 @@ public SftpFileAttributes RequestLStat(string path) var request = new SftpLStatRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { attributes = response.Attributes; @@ -960,7 +956,7 @@ public SFtpStatAsyncResult BeginLStat(string path, AsyncCallback callback, objec var request = new SftpLStatRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { asyncResult.SetAsCompleted(response.Attributes, completedSynchronously: false); @@ -1080,7 +1076,7 @@ public void RequestSetStat(string path, SftpFileAttributes attributes) var request = new SftpSetStatRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, attributes, response => { @@ -1148,7 +1144,7 @@ public byte[] RequestOpenDir(string path, bool nullOnError = false) var request = new SftpOpenDirRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { handle = response.Handle; @@ -1184,7 +1180,7 @@ public async Task RequestOpenDirAsync(string path, CancellationToken can SendRequest(new SftpOpenDirRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => tcs.TrySetResult(response.Handle), response => tcs.TrySetException(GetSftpException(response)))); @@ -1277,7 +1273,7 @@ public void RequestRemove(string path) var request = new SftpRemoveRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { exception = GetSftpException(response); @@ -1306,7 +1302,7 @@ public async Task RequestRemoveAsync(string path, CancellationToken cancellation SendRequest(new SftpRemoveRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { if (response.StatusCode == StatusCodes.Ok) @@ -1336,7 +1332,7 @@ public void RequestMkDir(string path) var request = new SftpMkDirRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { exception = GetSftpException(response); @@ -1367,7 +1363,7 @@ public void RequestRmDir(string path) var request = new SftpRmDirRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { exception = GetSftpException(response); @@ -1404,7 +1400,7 @@ internal KeyValuePair[] RequestRealPath(string path, var request = new SftpRealPathRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { result = response.Files; @@ -1440,7 +1436,7 @@ internal async Task[]> RequestRealPathA SendRequest(new SftpRealPathRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => tcs.TrySetResult(response.Files), response => { @@ -1474,7 +1470,7 @@ public SftpRealPathAsyncResult BeginRealPath(string path, AsyncCallback callback var request = new SftpRealPathRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => asyncResult.SetAsCompleted(response.Files[0].Key, completedSynchronously: false), response => asyncResult.SetAsCompleted(GetSftpException(response), completedSynchronously: false)); SendRequest(request); @@ -1533,7 +1529,7 @@ public SftpFileAttributes RequestStat(string path, bool nullOnError = false) var request = new SftpStatRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { attributes = response.Attributes; @@ -1574,7 +1570,7 @@ public SFtpStatAsyncResult BeginStat(string path, AsyncCallback callback, object var request = new SftpStatRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => asyncResult.SetAsCompleted(response.Attributes, completedSynchronously: false), response => asyncResult.SetAsCompleted(GetSftpException(response), completedSynchronously: false)); SendRequest(request); @@ -1634,7 +1630,7 @@ public void RequestRename(string oldPath, string newPath) NextRequestId, oldPath, newPath, - Encoding, + _encoding, response => { exception = GetSftpException(response); @@ -1664,7 +1660,7 @@ public async Task RequestRenameAsync(string oldPath, string newPath, Cancellatio NextRequestId, oldPath, newPath, - Encoding, + _encoding, response => { if (response.StatusCode == StatusCodes.Ok) @@ -1703,7 +1699,7 @@ internal KeyValuePair[] RequestReadLink(string path, var request = new SftpReadLinkRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { result = response.Files; @@ -1748,7 +1744,7 @@ public void RequestSymLink(string linkpath, string targetpath) NextRequestId, linkpath, targetpath, - Encoding, + _encoding, response => { exception = GetSftpException(response); @@ -1786,7 +1782,7 @@ public void RequestPosixRename(string oldPath, string newPath) NextRequestId, oldPath, newPath, - Encoding, + _encoding, response => { exception = GetSftpException(response); @@ -1833,7 +1829,7 @@ public SftpFileSytemInformation RequestStatVfs(string path, bool nullOnError = f var request = new StatVfsRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => { information = response.GetReply().Information; @@ -1879,7 +1875,7 @@ public async Task RequestStatVfsAsync(string path, Can SendRequest(new StatVfsRequest(ProtocolVersion, NextRequestId, path, - Encoding, + _encoding, response => tcs.TrySetResult(response.GetReply().Information), response => tcs.TrySetException(GetSftpException(response)))); diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 8190df20c..9fe19235a 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -18,7 +18,7 @@ namespace Renci.SshNet /// public class SftpClient : BaseClient, ISftpClient { - private static readonly Encoding Utf8NoBOM = new UTF8Encoding(false, true); + private static readonly Encoding Utf8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); /// /// Holds the instance that is used to communicate to the @@ -171,7 +171,7 @@ internal ISftpSession SftpSession /// The connection info. /// is null. public SftpClient(ConnectionInfo connectionInfo) - : this(connectionInfo, false) + : this(connectionInfo, ownsConnectionInfo: false) { } @@ -187,7 +187,7 @@ public SftpClient(ConnectionInfo connectionInfo) /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public SftpClient(string host, int port, string username, string password) - : this(new PasswordConnectionInfo(host, port, username, password), true) + : this(new PasswordConnectionInfo(host, port, username, password), ownsConnectionInfo: true) { } @@ -216,7 +216,7 @@ public SftpClient(string host, string username, string password) /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public SftpClient(string host, int port, string username, params IPrivateKeySource[] keyFiles) - : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true) + : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true) { } @@ -443,7 +443,7 @@ public async Task DeleteFileAsync(string path, CancellationToken cancellationTok /// The method was called after the client was disposed. public void RenameFile(string oldPath, string newPath) { - RenameFile(oldPath, newPath, false); + RenameFile(oldPath, newPath, isPosix: false); } /// @@ -464,12 +464,12 @@ public async Task RenameFileAsync(string oldPath, string newPath, CancellationTo if (oldPath is null) { - throw new ArgumentNullException("oldPath"); + throw new ArgumentNullException(nameof(oldPath)); } if (newPath is null) { - throw new ArgumentNullException("newPath"); + throw new ArgumentNullException(nameof(newPath)); } if (_sftpSession is null) @@ -501,12 +501,12 @@ public void RenameFile(string oldPath, string newPath, bool isPosix) if (oldPath is null) { - throw new ArgumentNullException("oldPath"); + throw new ArgumentNullException(nameof(oldPath)); } if (newPath is null) { - throw new ArgumentNullException("newPath"); + throw new ArgumentNullException(nameof(newPath)); } if (_sftpSession is null) @@ -604,7 +604,7 @@ public async Task> ListDirectoryAsync(string path, Cancel if (path is null) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } if (_sftpSession is null) @@ -675,11 +675,11 @@ public IAsyncResult BeginListDirectory(string path, AsyncCallback asyncCallback, listCallback?.Invoke(count); }); - asyncResult.SetAsCompleted(result, false); + asyncResult.SetAsCompleted(result, completedSynchronously: false); } catch (Exception exp) { - asyncResult.SetAsCompleted(exp, false); + asyncResult.SetAsCompleted(exp, completedSynchronously: false); } }); @@ -722,7 +722,7 @@ public ISftpFile Get(string path) if (path is null) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } if (_sftpSession is null) @@ -813,7 +813,7 @@ public void DownloadFile(string path, Stream output, Action downloadCallb { CheckDisposed(); - InternalDownloadFile(path, output, null, downloadCallback); + InternalDownloadFile(path, output, asyncResult: null, downloadCallback); } /// @@ -835,7 +835,7 @@ public void DownloadFile(string path, Stream output, Action downloadCallb /// public IAsyncResult BeginDownloadFile(string path, Stream output) { - return BeginDownloadFile(path, output, null, null); + return BeginDownloadFile(path, output, asyncCallback: null, state: null); } /// @@ -858,7 +858,7 @@ public IAsyncResult BeginDownloadFile(string path, Stream output) /// public IAsyncResult BeginDownloadFile(string path, Stream output, AsyncCallback asyncCallback) { - return BeginDownloadFile(path, output, asyncCallback, null); + return BeginDownloadFile(path, output, asyncCallback, state: null); } /// @@ -889,7 +889,7 @@ public IAsyncResult BeginDownloadFile(string path, Stream output, AsyncCallback if (output is null) { - throw new ArgumentNullException("output"); + throw new ArgumentNullException(nameof(output)); } var asyncResult = new SftpDownloadAsyncResult(asyncCallback, state); @@ -905,11 +905,11 @@ public IAsyncResult BeginDownloadFile(string path, Stream output, AsyncCallback downloadCallback?.Invoke(offset); }); - asyncResult.SetAsCompleted(null, false); + asyncResult.SetAsCompleted(exception: null, completedSynchronously: false); } catch (Exception exp) { - asyncResult.SetAsCompleted(exp, false); + asyncResult.SetAsCompleted(exp, completedSynchronously: false); } }); @@ -953,7 +953,7 @@ public void EndDownloadFile(IAsyncResult asyncResult) /// public void UploadFile(Stream input, string path, Action uploadCallback = null) { - UploadFile(input, path, true, uploadCallback); + UploadFile(input, path, canOverride: true, uploadCallback); } /// @@ -987,7 +987,7 @@ public void UploadFile(Stream input, string path, bool canOverride, Action @@ -1014,7 +1014,7 @@ public void UploadFile(Stream input, string path, bool canOverride, Action public IAsyncResult BeginUploadFile(Stream input, string path) { - return BeginUploadFile(input, path, true, null, null); + return BeginUploadFile(input, path, canOverride: true, asyncCallback: null, state: null); } /// @@ -1042,7 +1042,7 @@ public IAsyncResult BeginUploadFile(Stream input, string path) /// public IAsyncResult BeginUploadFile(Stream input, string path, AsyncCallback asyncCallback) { - return BeginUploadFile(input, path, true, asyncCallback, null); + return BeginUploadFile(input, path, canOverride: true, asyncCallback, state: null); } /// @@ -1072,7 +1072,7 @@ public IAsyncResult BeginUploadFile(Stream input, string path, AsyncCallback asy /// public IAsyncResult BeginUploadFile(Stream input, string path, AsyncCallback asyncCallback, object state, Action uploadCallback = null) { - return BeginUploadFile(input, path, true, asyncCallback, state, uploadCallback); + return BeginUploadFile(input, path, canOverride: true, asyncCallback, state, uploadCallback); } /// @@ -1106,7 +1106,7 @@ public IAsyncResult BeginUploadFile(Stream input, string path, bool canOverride, if (input is null) { - throw new ArgumentNullException("input"); + throw new ArgumentNullException(nameof(input)); } if (path.IsNullOrWhiteSpace()) @@ -1132,18 +1132,16 @@ public IAsyncResult BeginUploadFile(Stream input, string path, bool canOverride, try { InternalUploadFile(input, path, flags, asyncResult, offset => - { - asyncResult.Update(offset); - - uploadCallback?.Invoke(offset); - - }); + { + asyncResult.Update(offset); + uploadCallback?.Invoke(offset); + }); - asyncResult.SetAsCompleted(null, false); + asyncResult.SetAsCompleted(exception: null, completedSynchronously: false); } catch (Exception exp) { - asyncResult.SetAsCompleted(exp, false); + asyncResult.SetAsCompleted(exception: exp, completedSynchronously: false); } }); @@ -1186,7 +1184,7 @@ public SftpFileSytemInformation GetStatus(string path) if (path is null) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } if (_sftpSession is null) @@ -1217,7 +1215,7 @@ public async Task GetStatusAsync(string path, Cancella if (path is null) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } if (_sftpSession is null) @@ -1251,7 +1249,7 @@ public void AppendAllLines(string path, IEnumerable contents) if (contents is null) { - throw new ArgumentNullException("contents"); + throw new ArgumentNullException(nameof(contents)); } using (var stream = AppendText(path)) @@ -1279,7 +1277,7 @@ public void AppendAllLines(string path, IEnumerable contents, Encoding e if (contents is null) { - throw new ArgumentNullException("contents"); + throw new ArgumentNullException(nameof(contents)); } using (var stream = AppendText(path, encoding)) @@ -1366,7 +1364,7 @@ public StreamWriter AppendText(string path, Encoding encoding) if (encoding is null) { - throw new ArgumentNullException("encoding"); + throw new ArgumentNullException(nameof(encoding)); } return new StreamWriter(new SftpFileStream(_sftpSession, path, FileMode.Append, FileAccess.Write, (int) _bufferSize), encoding); @@ -1604,7 +1602,7 @@ public Task OpenAsync(string path, FileMode mode, FileAccess acc if (path is null) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } if (_sftpSession is null) @@ -2105,7 +2103,7 @@ public IEnumerable SynchronizeDirectories(string sourcePath, string de { if (sourcePath is null) { - throw new ArgumentNullException("sourcePath"); + throw new ArgumentNullException(nameof(sourcePath)); } if (destinationPath.IsNullOrWhiteSpace()) @@ -2113,7 +2111,7 @@ public IEnumerable SynchronizeDirectories(string sourcePath, string de throw new ArgumentException("destinationPath"); } - return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, null); + return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asynchResult: null); } /// @@ -2134,7 +2132,7 @@ public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destin { if (sourcePath is null) { - throw new ArgumentNullException("sourcePath"); + throw new ArgumentNullException(nameof(sourcePath)); } if (destinationPath.IsNullOrWhiteSpace()) @@ -2145,18 +2143,18 @@ public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destin var asyncResult = new SftpSynchronizeDirectoriesAsyncResult(asyncCallback, state); ThreadAbstraction.ExecuteThread(() => - { - try { - var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult); + try + { + var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult); - asyncResult.SetAsCompleted(result, false); - } - catch (Exception exp) - { - asyncResult.SetAsCompleted(exp, false); - } - }); + asyncResult.SetAsCompleted(result, completedSynchronously: false); + } + catch (Exception exp) + { + asyncResult.SetAsCompleted(exp, completedSynchronously: false); + } + }); return asyncResult; } @@ -2201,7 +2199,7 @@ private IEnumerable InternalSynchronizeDirectories(string sourcePath, #region Existing Files at The Destination - var destFiles = InternalListDirectory(destinationPath, null); + var destFiles = InternalListDirectory(destinationPath, listCallback: null); var destDict = new Dictionary(); foreach (var destFile in destFiles) { @@ -2241,7 +2239,7 @@ private IEnumerable InternalSynchronizeDirectories(string sourcePath, { using (var file = File.OpenRead(localFile.FullName)) { - InternalUploadFile(file, remoteFileName, uploadFlag, null, null); + InternalUploadFile(file, remoteFileName, uploadFlag, asyncResult: null, uploadCallback: null); } uploadedFiles.Add(localFile); @@ -2278,7 +2276,7 @@ private IEnumerable InternalListDirectory(string path, Action li { if (path is null) { - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); } if (_sftpSession is null) @@ -2301,7 +2299,7 @@ private IEnumerable InternalListDirectory(string path, Action li var files = _sftpSession.RequestReadDir(handle); - while (files != null) + while (files is not null) { foreach (var f in files) { @@ -2311,7 +2309,7 @@ private IEnumerable InternalListDirectory(string path, Action li } // Call callback to report number of files read - if (listCallback != null) + if (listCallback is not null) { // Execute callback on different thread ThreadAbstraction.ExecuteThread(() => listCallback(result.Count)); @@ -2339,7 +2337,7 @@ private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncR { if (output is null) { - throw new ArgumentNullException("output"); + throw new ArgumentNullException(nameof(output)); } if (path.IsNullOrWhiteSpace()) @@ -2360,8 +2358,8 @@ private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncR while (true) { - // Cancel download - if (asyncResult != null && asyncResult.IsDownloadCanceled) + // Cancel download + if (asyncResult is not null && asyncResult.IsDownloadCanceled) { break; } @@ -2376,7 +2374,7 @@ private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncR totalBytesRead += (ulong) data.Length; - if (downloadCallback != null) + if (downloadCallback is not null) { // copy offset to ensure it's not modified between now and execution of callback var downloadOffset = totalBytesRead; @@ -2403,7 +2401,7 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo { if (input is null) { - throw new ArgumentNullException("input"); + throw new ArgumentNullException(nameof(input)); } if (path.IsNullOrWhiteSpace()) @@ -2427,12 +2425,12 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo var bytesRead = input.Read(buffer, 0, buffer.Length); var expectedResponses = 0; - var responseReceivedWaitHandle = new AutoResetEvent(false); + var responseReceivedWaitHandle = new AutoResetEvent(initialState: false); do { - // Cancel upload - if (asyncResult != null && asyncResult.IsUploadCanceled) + // Cancel upload + if (asyncResult is not null && asyncResult.IsUploadCanceled) { break; } @@ -2441,7 +2439,7 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo { var writtenBytes = offset + (ulong) bytesRead; - _sftpSession.RequestWrite(handle, offset, buffer, 0, bytesRead, null, s => + _sftpSession.RequestWrite(handle, offset, buffer, offset: 0, bytesRead, wait: null, s => { if (s.StatusCode == StatusCodes.Ok) { @@ -2449,7 +2447,7 @@ private void InternalUploadFile(Stream input, string path, Flags flags, SftpUplo _ = responseReceivedWaitHandle.Set(); // Call callback to report number of bytes written - if (uploadCallback != null) + if (uploadCallback is not null) { // Execute callback on different thread ThreadAbstraction.ExecuteThread(() => uploadCallback(writtenBytes)); @@ -2494,7 +2492,7 @@ protected override void OnDisconnecting() // disconnect, dispose and dereference the SFTP session since we create a new SFTP session // on each connect var sftpSession = _sftpSession; - if (sftpSession != null) + if (sftpSession is not null) { _sftpSession = null; sftpSession.Dispose(); @@ -2512,7 +2510,7 @@ protected override void Dispose(bool disposing) if (disposing) { var sftpSession = _sftpSession; - if (sftpSession != null) + if (sftpSession is not null) { _sftpSession = null; sftpSession.Dispose(); diff --git a/src/Renci.SshNet/Shell.cs b/src/Renci.SshNet/Shell.cs index 892c530b4..0990ae812 100644 --- a/src/Renci.SshNet/Shell.cs +++ b/src/Renci.SshNet/Shell.cs @@ -102,7 +102,7 @@ public void Start() throw new SshException("Shell is started."); } - Starting?.Invoke(this, new EventArgs()); + Starting?.Invoke(this, EventArgs.Empty); _channel = _session.CreateChannelSession(); _channel.DataReceived += Channel_DataReceived; @@ -196,7 +196,7 @@ private void Channel_DataReceived(object sender, ChannelDataEventArgs e) private void Channel_Closed(object sender, ChannelEventArgs e) { - if (Stopping != null) + if (Stopping is not null) { // Handle event on different thread ThreadAbstraction.ExecuteThread(() => Stopping(this, EventArgs.Empty)); @@ -272,21 +272,21 @@ protected virtual void Dispose(bool disposing) UnsubscribeFromSessionEvents(_session); var channelClosedWaitHandle = _channelClosedWaitHandle; - if (channelClosedWaitHandle != null) + if (channelClosedWaitHandle is not null) { channelClosedWaitHandle.Dispose(); _channelClosedWaitHandle = null; } var channel = _channel; - if (channel != null) + if (channel is not null) { channel.Dispose(); _channel = null; } var dataReaderTaskCompleted = _dataReaderTaskCompleted; - if (dataReaderTaskCompleted != null) + if (dataReaderTaskCompleted is not null) { dataReaderTaskCompleted.Dispose(); _dataReaderTaskCompleted = null; diff --git a/src/Renci.SshNet/SshClient.cs b/src/Renci.SshNet/SshClient.cs index 5ed7036c5..fb8bb37f0 100644 --- a/src/Renci.SshNet/SshClient.cs +++ b/src/Renci.SshNet/SshClient.cs @@ -336,7 +336,7 @@ public Shell CreateShell(Stream input, Stream output, Stream extendedOutput, str /// Client is not connected. public Shell CreateShell(Stream input, Stream output, Stream extendedOutput) { - return CreateShell(input, output, extendedOutput, string.Empty, 0, 0, 0, 0, null, 1024); + return CreateShell(input, output, extendedOutput, string.Empty, 0, 0, 0, 0, terminalModes: null, 1024); } /// @@ -405,7 +405,7 @@ public Shell CreateShell(Encoding encoding, string input, Stream output, Stream /// Client is not connected. public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput) { - return CreateShell(encoding, input, output, extendedOutput, string.Empty, 0, 0, 0, 0, null, 1024); + return CreateShell(encoding, input, output, extendedOutput, string.Empty, 0, 0, 0, 0, terminalModes: null, 1024); } /// @@ -433,7 +433,7 @@ public Shell CreateShell(Encoding encoding, string input, Stream output, Stream /// public ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize) { - return CreateShellStream(terminalName, columns, rows, width, height, bufferSize, null); + return CreateShellStream(terminalName, columns, rows, width, height, bufferSize, terminalModeValues: null); } /// diff --git a/src/Renci.SshNet/SshCommand.cs b/src/Renci.SshNet/SshCommand.cs index 30a6bfe54..13c00992a 100644 --- a/src/Renci.SshNet/SshCommand.cs +++ b/src/Renci.SshNet/SshCommand.cs @@ -150,7 +150,7 @@ internal SshCommand(ISession session, string commandText, Encoding encoding) CommandText = commandText; _encoding = encoding; CommandTimeout = Session.InfiniteTimeSpan; - _sessionErrorOccuredWaitHandle = new AutoResetEvent(false); + _sessionErrorOccuredWaitHandle = new AutoResetEvent(initialState: false); _session.Disconnected += Session_Disconnected; _session.ErrorOccured += Session_ErrorOccured; @@ -172,7 +172,7 @@ internal SshCommand(ISession session, string commandText, Encoding encoding) /// Operation has timed out. public IAsyncResult BeginExecute() { - return BeginExecute(null, null); + return BeginExecute(callback: null, state: null); } /// @@ -189,7 +189,7 @@ public IAsyncResult BeginExecute() /// Operation has timed out. public IAsyncResult BeginExecute(AsyncCallback callback) { - return BeginExecute(callback, null); + return BeginExecute(callback, state: null); } /// @@ -216,13 +216,13 @@ public IAsyncResult BeginExecute(AsyncCallback callback, object state) // Create new AsyncResult object _asyncResult = new CommandAsyncResult { - AsyncWaitHandle = new ManualResetEvent(false), + AsyncWaitHandle = new ManualResetEvent(initialState: false), IsCompleted = false, AsyncState = state, }; // When command re-executed again, create a new channel - if (_channel != null) + if (_channel is not null) { throw new SshException("Invalid operation."); } @@ -233,14 +233,14 @@ public IAsyncResult BeginExecute(AsyncCallback callback, object state) } var outputStream = OutputStream; - if (outputStream != null) + if (outputStream is not null) { outputStream.Dispose(); OutputStream = null; } var extendedOutputStream = ExtendedOutputStream; - if (extendedOutputStream != null) + if (extendedOutputStream is not null) { extendedOutputStream.Dispose(); ExtendedOutputStream = null; @@ -333,7 +333,7 @@ public string EndExecute(IAsyncResult asyncResult) /// Operation has timed out. public string Execute() { - return EndExecute(BeginExecute(null, null)); + return EndExecute(BeginExecute(callback: null, state: null)); } /// @@ -341,7 +341,7 @@ public string Execute() /// public void CancelAsync() { - if (_channel != null && _channel.IsOpen && _asyncResult != null) + if (_channel is not null && _channel.IsOpen && _asyncResult is not null) { // TODO: check with Oleg if we shouldn't dispose the channel and uninitialize it ? _channel.Dispose(); @@ -407,7 +407,7 @@ private void Channel_Closed(object sender, ChannelEventArgs e) _asyncResult.IsCompleted = true; - if (_callback != null) + if (_callback is not null) { // Execute callback on different thread ThreadAbstraction.ExecuteThread(() => _callback(_asyncResult)); diff --git a/src/Renci.SshNet/SubsystemSession.cs b/src/Renci.SshNet/SubsystemSession.cs index 2c2b66c06..b89d30fd1 100644 --- a/src/Renci.SshNet/SubsystemSession.cs +++ b/src/Renci.SshNet/SubsystemSession.cs @@ -23,9 +23,9 @@ internal abstract class SubsystemSession : ISubsystemSession private ISession _session; private IChannelSession _channel; private Exception _exception; - private EventWaitHandle _errorOccuredWaitHandle = new ManualResetEvent(false); - private EventWaitHandle _sessionDisconnectedWaitHandle = new ManualResetEvent(false); - private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(false); + private EventWaitHandle _errorOccuredWaitHandle = new ManualResetEvent(initialState: false); + private EventWaitHandle _sessionDisconnectedWaitHandle = new ManualResetEvent(initialState: false); + private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(initialState: false); private bool _isDisposed; /// @@ -70,7 +70,7 @@ internal IChannelSession Channel /// public bool IsOpen { - get { return _channel != null && _channel.IsOpen; } + get { return _channel is not null && _channel.IsOpen; } } /// @@ -149,7 +149,7 @@ public void Disconnect() UnsubscribeFromSessionEvents(_session); var channel = _channel; - if (channel != null) + if (channel is not null) { _channel = null; channel.DataReceived -= Channel_DataReceived;