From fb96e1d582d8a54266257b578a86037ebc940d25 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Sun, 1 Jun 2025 10:26:18 +0200 Subject: [PATCH 01/16] Add .NET 10 target --- .editorconfig | 3 +++ .github/workflows/build.yml | 16 ++++++++-------- Directory.Packages.props | 4 ++-- global.json | 3 ++- src/Renci.SshNet/Renci.SshNet.csproj | 2 +- .../Renci.SshNet.AotCompatibilityTestApp.csproj | 2 +- .../Renci.SshNet.Benchmarks.csproj | 2 +- .../Renci.SshNet.IntegrationBenchmarks.csproj | 2 +- .../Renci.SshNet.IntegrationTests.csproj | 2 +- .../Renci.SshNet.Tests/Renci.SshNet.Tests.csproj | 2 +- 10 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.editorconfig b/.editorconfig index 788ade7af..ef89590f9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -726,6 +726,9 @@ dotnet_diagnostic.CA1848.severity = silent # By default, this diagnostic is only reported for private members. dotnet_code_quality.CA1859.api_surface = private,internal +# CA1873: Evaluation of this argument may be expensive and unnecessary if logging is disabled +dotnet_diagnostic.CA1873.severity = suggestion + # CA2208: Instantiate argument exceptions correctly # https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2208 # diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1bc033d8e..bb8385bc5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,33 +18,33 @@ jobs: uses: actions/setup-dotnet@v4 - name: Build Unit Tests .NET - run: dotnet build -f net9.0 test/Renci.SshNet.Tests/ + run: dotnet build -f net10.0 test/Renci.SshNet.Tests/ - name: Build IntegrationTests .NET - run: dotnet build -f net9.0 test/Renci.SshNet.IntegrationTests/ + run: dotnet build -f net10.0 test/Renci.SshNet.IntegrationTests/ - name: Run Unit Tests .NET run: | dotnet test \ - -f net9.0 \ + -f net10.0 \ --no-build \ --logger "console;verbosity=normal" \ --logger GitHubActions \ -p:CollectCoverage=true \ -p:CoverletOutputFormat=cobertura \ - -p:CoverletOutput=../../coverlet/linux_unit_test_net_9_coverage.xml \ + -p:CoverletOutput=../../coverlet/linux_unit_test_net_10_coverage.xml \ test/Renci.SshNet.Tests/ - name: Run Integration Tests .NET run: | dotnet test \ - -f net9.0 \ + -f net10.0 \ --no-build \ --logger "console;verbosity=normal" \ --logger GitHubActions \ -p:CollectCoverage=true \ -p:CoverletOutputFormat=cobertura \ - -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage.xml \ + -p:CoverletOutput=../../coverlet/linux_integration_test_net_10_coverage.xml \ test/Renci.SshNet.IntegrationTests/ - name: Archive Coverlet Results @@ -82,13 +82,13 @@ jobs: - name: Run Unit Tests .NET run: | dotnet test ` - -f net9.0 ` + -f net10.0 ` --no-build ` --logger "console;verbosity=normal" ` --logger GitHubActions ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` - -p:CoverletOutput=../../coverlet/windows_unit_test_net_9_coverage.xml ` + -p:CoverletOutput=../../coverlet/windows_unit_test_net_10_coverage.xml ` test/Renci.SshNet.Tests/ - name: Run Unit Tests .NET Framework diff --git a/Directory.Packages.props b/Directory.Packages.props index 6ae4272d0..b7083b1d9 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -12,7 +12,7 @@ - + @@ -23,4 +23,4 @@ - \ No newline at end of file + diff --git a/global.json b/global.json index 3be1c15ac..51bfa8d16 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,7 @@ { "sdk": { - "version": "9.0.300", + "version": "10.0.100-rc.1.25451.107", + "allowPrerelease": true, "rollForward": "latestFeature" } } diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 446865229..091ee6a7a 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -4,7 +4,7 @@ Renci.SshNet SSH.NET SSH.NET - net462;netstandard2.0;net8.0;net9.0 + net462;netstandard2.0;net8.0;net9.0;net10.0 diff --git a/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj b/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj index a18321dae..9d8a4d821 100644 --- a/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj +++ b/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net10.0 true true false diff --git a/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj b/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj index f421ad23f..e178dc835 100644 --- a/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj +++ b/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net10.0 enable enable diff --git a/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj b/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj index 3f32fe9bb..2a98efd7a 100644 --- a/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj +++ b/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net10.0 enable enable diff --git a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj index 8755ffb44..83d1a7be7 100644 --- a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj +++ b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj @@ -1,7 +1,7 @@  - net48;net8.0;net9.0 + net48;net8.0;net9.0;net10.0 enable true true diff --git a/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj b/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj index 1a7145aa3..25ffbd8f9 100644 --- a/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj +++ b/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj @@ -1,7 +1,7 @@  - net462;net8.0;net9.0 + net462;net8.0;net9.0;net10.0 From 1edc4ff75fbeade6f78d025c7c8f96df96929621 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Tue, 15 Jul 2025 20:49:18 +0200 Subject: [PATCH 02/16] fix IDE0031 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0031 --- src/Renci.SshNet/NetConfClient.cs | 7 ++--- src/Renci.SshNet/Netconf/NetConfSession.cs | 14 +++------- src/Renci.SshNet/Session.cs | 14 +++------- src/Renci.SshNet/SshClient.cs | 7 ++--- ...pose_SessionIsConnectedAndChannelIsOpen.cs | 14 +++------- ...pose_SessionIsConnectedAndChannelIsOpen.cs | 21 ++++---------- ...nelIsOpen_EofNotReceived_SendEofInvoked.cs | 7 ++--- ...IsConnectedAndChannelIsOpen_EofReceived.cs | 25 ++++++----------- ...ectionClosedByServer_NoDataSentByServer.cs | 7 ++--- ...est_ServerResponseContainsNullCharacter.cs | 7 ++--- ...entificationOnlyContainsProtocolVersion.cs | 7 ++--- ...changeTest_ServerResponseValid_Comments.cs | 7 ++--- ...erverResponseValid_EmptySoftwareVersion.cs | 7 ++--- ...angeTest_ServerResponseValid_NoComments.cs | 7 ++--- ...rminatedByLineFeedWithoutCarriageReturn.cs | 7 ++--- ...Test_TimeoutReadingIdentificationString.cs | 14 +++------- ...dedPortDynamicTest_Dispose_PortDisposed.cs | 7 ++--- ...ortDynamicTest_Dispose_PortNeverStarted.cs | 7 ++--- ...icTest_Dispose_PortStarted_ChannelBound.cs | 28 ++++++------------- ...est_Dispose_PortStarted_ChannelNotBound.cs | 14 +++------- ...rdedPortDynamicTest_Dispose_PortStopped.cs | 7 ++--- ...cTest_SessionErrorOccurred_ChannelBound.cs | 28 ++++++------------- ...ardedPortDynamicTest_Start_PortDisposed.cs | 7 ++--- ...dPortDynamicTest_Start_PortNeverStarted.cs | 7 ++--- ...wardedPortDynamicTest_Start_PortStarted.cs | 7 ++--- ...wardedPortDynamicTest_Start_PortStopped.cs | 7 ++--- ...wardedPortDynamicTest_Start_SessionNull.cs | 7 ++--- ...t_Started_SocketSendShutdownImmediately.cs | 7 ++--- ...cTest_Started_SocketVersionNotSupported.cs | 14 +++------- ...wardedPortDynamicTest_Stop_PortDisposed.cs | 7 ++--- ...edPortDynamicTest_Stop_PortNeverStarted.cs | 7 ++--- ...namicTest_Stop_PortStarted_ChannelBound.cs | 28 ++++++------------- ...icTest_Stop_PortStarted_ChannelNotBound.cs | 14 +++------- ...rwardedPortDynamicTest_Stop_PortStopped.cs | 7 ++--- ...ardedPortLocalTest_Dispose_PortDisposed.cs | 7 ++--- ...lTest_Dispose_PortDisposed_NeverStarted.cs | 7 ++--- ...dPortLocalTest_Dispose_PortNeverStarted.cs | 7 ++--- ...alTest_Dispose_PortStarted_ChannelBound.cs | 28 ++++++------------- ...est_Dispose_PortStarted_ChannelNotBound.cs | 7 ++--- ...wardedPortLocalTest_Dispose_PortStopped.cs | 7 ++--- ...rwardedPortLocalTest_Start_PortDisposed.cs | 7 ++--- ...dedPortLocalTest_Start_PortNeverStarted.cs | 7 ++--- ...orwardedPortLocalTest_Start_PortStarted.cs | 7 ++--- ...orwardedPortLocalTest_Start_PortStopped.cs | 7 ++--- ...orwardedPortLocalTest_Stop_PortDisposed.cs | 7 ++--- ...LocalTest_Stop_PortStarted_ChannelBound.cs | 28 ++++++------------- ...alTest_Stop_PortStarted_ChannelNotBound.cs | 7 ++--- ...ForwardedPortLocalTest_Stop_PortStopped.cs | 7 ++--- ...rdedPortRemoteTest_Dispose_PortDisposed.cs | 7 ++--- ...PortRemoteTest_Dispose_PortNeverStarted.cs | 7 ++--- ...teTest_Dispose_PortStarted_ChannelBound.cs | 25 ++++++----------- ...ardedPortRemoteTest_Dispose_PortStopped.cs | 7 ++--- ...wardedPortRemoteTest_Start_PortDisposed.cs | 7 ++--- ...rwardedPortRemoteTest_Start_SessionNull.cs | 7 ++--- ...rwardedPortRemoteTest_Stop_PortDisposed.cs | 7 ++--- .../Classes/SessionTest_ConnectedBase.cs | 28 ++++++------------- .../Classes/SessionTest_ConnectingBase.cs | 21 ++++---------- .../Common/AsyncSocketListener.cs | 7 ++--- 58 files changed, 186 insertions(+), 459 deletions(-) diff --git a/src/Renci.SshNet/NetConfClient.cs b/src/Renci.SshNet/NetConfClient.cs index e4b66ad92..5b509dc51 100644 --- a/src/Renci.SshNet/NetConfClient.cs +++ b/src/Renci.SshNet/NetConfClient.cs @@ -299,11 +299,8 @@ protected override void Dispose(bool disposing) if (disposing) { - if (_netConfSession != null) - { - _netConfSession.Dispose(); - _netConfSession = null; - } + _netConfSession?.Dispose(); + _netConfSession = null; } } diff --git a/src/Renci.SshNet/Netconf/NetConfSession.cs b/src/Renci.SshNet/Netconf/NetConfSession.cs index 2044a7852..60edc2d81 100644 --- a/src/Renci.SshNet/Netconf/NetConfSession.cs +++ b/src/Renci.SshNet/Netconf/NetConfSession.cs @@ -213,17 +213,11 @@ protected override void Dispose(bool disposing) if (disposing) { - if (_serverCapabilitiesConfirmed != null) - { - _serverCapabilitiesConfirmed.Dispose(); - _serverCapabilitiesConfirmed = null; - } + _serverCapabilitiesConfirmed?.Dispose(); + _serverCapabilitiesConfirmed = null; - if (_rpcReplyReceived != null) - { - _rpcReplyReceived.Dispose(); - _rpcReplyReceived = null; - } + _rpcReplyReceived?.Dispose(); + _rpcReplyReceived = null; } } } diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index ec3eac878..e94ebeb27 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -1570,17 +1570,11 @@ internal void OnNewKeysReceived(NewKeysMessage message) disposableClientCipher.Dispose(); } - if (_serverMac != null) - { - _serverMac.Dispose(); - _serverMac = null; - } + _serverMac?.Dispose(); + _serverMac = null; - if (_clientMac != null) - { - _clientMac.Dispose(); - _clientMac = null; - } + _clientMac?.Dispose(); + _clientMac = null; // Update negotiated algorithms _serverCipher = _keyExchange.CreateServerCipher(out _serverAead); diff --git a/src/Renci.SshNet/SshClient.cs b/src/Renci.SshNet/SshClient.cs index 3051074e1..05508462d 100644 --- a/src/Renci.SshNet/SshClient.cs +++ b/src/Renci.SshNet/SshClient.cs @@ -325,11 +325,8 @@ protected override void Dispose(bool disposing) if (disposing) { - if (_inputStream != null) - { - _inputStream.Dispose(); - _inputStream = null; - } + _inputStream?.Dispose(); + _inputStream = null; _isDisposed = true; } diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs index 332f3cfe7..8e4c13ea3 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs @@ -47,17 +47,11 @@ public void Initialize() [TestCleanup] public void CleanUp() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } + _client?.Dispose(); + _client = null; - if (_listener != null) - { - _listener.Stop(); - _listener = null; - } + _listener?.Stop(); + _listener = null; } private void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs index 8617aba37..4fcf476f7 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs @@ -47,23 +47,14 @@ public void Initialize() [TestCleanup] public void CleanUp() { - if (_remoteListener != null) - { - _remoteListener.Stop(); - _remoteListener = null; - } + _remoteListener?.Stop(); + _remoteListener = null; - if (_channelThread != null) - { - _channelThread.Join(); - _channelThread = null; - } + _channelThread?.Join(); + _channelThread = null; - if (_channel != null) - { - _channel.Dispose(); - _channel = null; - } + _channel?.Dispose(); + _channel = null; } private void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs index f6eb2933b..ed2946e49 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs @@ -31,11 +31,8 @@ public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceiv [TestCleanup] public void TearDown() { - if (_channelClosedEventHandlerCompleted != null) - { - _channelClosedEventHandlerCompleted.Dispose(); - _channelClosedEventHandlerCompleted = null; - } + _channelClosedEventHandlerCompleted?.Dispose(); + _channelClosedEventHandlerCompleted = null; } protected override void SetupData() diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs index 4f11009bb..c03bfea11 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs @@ -91,23 +91,14 @@ protected override void SetupMocks() [TestCleanup] public void TearDown() { - if (_channelClosedReceived != null) - { - _channelClosedReceived.Dispose(); - _channelClosedReceived = null; - } - - if (_raiseChannelCloseReceivedThread != null) - { - _raiseChannelCloseReceivedThread.Join(); - _raiseChannelCloseReceivedThread = null; - } - - if (_channelClosedEventHandlerCompleted != null) - { - _channelClosedEventHandlerCompleted.Dispose(); - _channelClosedEventHandlerCompleted = null; - } + _channelClosedReceived?.Dispose(); + _channelClosedReceived = null; + + _raiseChannelCloseReceivedThread?.Join(); + _raiseChannelCloseReceivedThread = null; + + _channelClosedEventHandlerCompleted?.Dispose(); + _channelClosedEventHandlerCompleted = null; } protected override void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ConnectionClosedByServer_NoDataSentByServer.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ConnectionClosedByServer_NoDataSentByServer.cs index 43aa9a3b1..b6ba2dbe5 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ConnectionClosedByServer_NoDataSentByServer.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ConnectionClosedByServer_NoDataSentByServer.cs @@ -35,11 +35,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; if (_client != null) { diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseContainsNullCharacter.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseContainsNullCharacter.cs index 164cb6a70..4d55fba2e 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseContainsNullCharacter.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseContainsNullCharacter.cs @@ -38,11 +38,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; if (_client != null) { diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseInvalid_SshIdentificationOnlyContainsProtocolVersion.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseInvalid_SshIdentificationOnlyContainsProtocolVersion.cs index 3b0649517..b68588ecb 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseInvalid_SshIdentificationOnlyContainsProtocolVersion.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseInvalid_SshIdentificationOnlyContainsProtocolVersion.cs @@ -38,11 +38,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; if (_client != null) { diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_Comments.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_Comments.cs index 2af8062b6..3835e6516 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_Comments.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_Comments.cs @@ -37,11 +37,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; if (_client != null) { diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_EmptySoftwareVersion.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_EmptySoftwareVersion.cs index c7daaf14d..141bf4189 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_EmptySoftwareVersion.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_EmptySoftwareVersion.cs @@ -38,11 +38,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; if (_client != null) { diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_NoComments.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_NoComments.cs index 365967209..ce80d99dd 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_NoComments.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_NoComments.cs @@ -37,11 +37,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; if (_client != null) { diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_TerminatedByLineFeedWithoutCarriageReturn.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_TerminatedByLineFeedWithoutCarriageReturn.cs index 2c35bce53..ad4953789 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_TerminatedByLineFeedWithoutCarriageReturn.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_ServerResponseValid_TerminatedByLineFeedWithoutCarriageReturn.cs @@ -37,11 +37,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; if (_client != null) { diff --git a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_TimeoutReadingIdentificationString.cs b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_TimeoutReadingIdentificationString.cs index 3710e2064..3917c9b29 100644 --- a/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_TimeoutReadingIdentificationString.cs +++ b/test/Renci.SshNet.Tests/Classes/Connection/ProtocolVersionExchangeTest_TimeoutReadingIdentificationString.cs @@ -37,17 +37,11 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_server != null) - { - _server.Dispose(); - _server = null; - } + _server?.Dispose(); + _server = null; - if (_client != null) - { - _client.Close(); - _client = null; - } + _client?.Close(); + _client = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortDisposed.cs index d39a91fab..8da9eee67 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortDisposed.cs @@ -24,11 +24,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortNeverStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortNeverStarted.cs index a9ce2b49e..adacc6c7a 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortNeverStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortNeverStarted.cs @@ -32,11 +32,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs index 692afe88d..76e819d5f 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs @@ -46,26 +46,14 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } - if (_channelBindStarted != null) - { - _channelBindStarted.Dispose(); - _channelBindStarted = null; - } - if (_channelBindCompleted != null) - { - _channelBindCompleted.Dispose(); - _channelBindCompleted = null; - } + _client?.Dispose(); + _client = null; + _forwardedPort?.Dispose(); + _forwardedPort = null; + _channelBindStarted?.Dispose(); + _channelBindStarted = null; + _channelBindCompleted?.Dispose(); + _channelBindCompleted = null; } private void CreateMocks() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelNotBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelNotBound.cs index 5804f6db1..ba949c2c2 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelNotBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelNotBound.cs @@ -38,16 +38,10 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _client?.Dispose(); + _client = null; + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStopped.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStopped.cs index 85ef70f8b..5a847d72a 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStopped.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStopped.cs @@ -32,11 +32,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs index c98784edd..dd26b91d5 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs @@ -47,26 +47,14 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } - if (_channelBindStarted != null) - { - _channelBindStarted.Dispose(); - _channelBindStarted = null; - } - if (_channelBindCompleted != null) - { - _channelBindCompleted.Dispose(); - _channelBindCompleted = null; - } + _client?.Dispose(); + _client = null; + _forwardedPort?.Dispose(); + _forwardedPort = null; + _channelBindStarted?.Dispose(); + _channelBindStarted = null; + _channelBindCompleted?.Dispose(); + _channelBindCompleted = null; } private void CreateMocks() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortDisposed.cs index 2ceac31e4..394be33e2 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortDisposed.cs @@ -25,11 +25,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortNeverStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortNeverStarted.cs index adc55951d..32d70787c 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortNeverStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortNeverStarted.cs @@ -34,11 +34,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStarted.cs index d39263b5b..922897a4b 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStarted.cs @@ -35,11 +35,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStopped.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStopped.cs index ad71d804c..bffee25fd 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStopped.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_PortStopped.cs @@ -34,11 +34,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_SessionNull.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_SessionNull.cs index c326c00d1..7c97f2aad 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_SessionNull.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Start_SessionNull.cs @@ -28,11 +28,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs index e58bf3d9c..597b0a0ec 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs @@ -59,11 +59,8 @@ public void Cleanup() } } - if (_channelDisposed != null) - { - _channelDisposed.Dispose(); - _channelDisposed = null; - } + _channelDisposed?.Dispose(); + _channelDisposed = null; } private void SetupData() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketVersionNotSupported.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketVersionNotSupported.cs index d28c311b2..850f6fcf1 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketVersionNotSupported.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketVersionNotSupported.cs @@ -45,17 +45,11 @@ public void Cleanup() _forwardedPort.Stop(); } - if (_client != null) - { - _client.Close(); - _client = null; - } + _client?.Close(); + _client = null; - if (_exceptionFired != null) - { - _exceptionFired.Dispose(); - _exceptionFired = null; - } + _exceptionFired?.Dispose(); + _exceptionFired = null; } private void SetupData() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortDisposed.cs index 58b020323..aa99838af 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortDisposed.cs @@ -27,11 +27,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortNeverStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortNeverStarted.cs index 118b075e4..1125acde1 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortNeverStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortNeverStarted.cs @@ -27,11 +27,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs index fcfc88a0f..cfda2a209 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs @@ -45,26 +45,14 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } - if (_channelBindStarted != null) - { - _channelBindStarted.Dispose(); - _channelBindStarted = null; - } - if (_channelBindCompleted != null) - { - _channelBindCompleted.Dispose(); - _channelBindCompleted = null; - } + _client?.Dispose(); + _client = null; + _forwardedPort?.Dispose(); + _forwardedPort = null; + _channelBindStarted?.Dispose(); + _channelBindStarted = null; + _channelBindCompleted?.Dispose(); + _channelBindCompleted = null; } private void CreateMocks() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelNotBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelNotBound.cs index fa716b6b3..6a3e0839e 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelNotBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelNotBound.cs @@ -38,16 +38,10 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _client?.Dispose(); + _client = null; + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStopped.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStopped.cs index dbc738801..a976733b7 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStopped.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStopped.cs @@ -32,11 +32,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed.cs index 66cc6d57f..7ae63cb4e 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed.cs @@ -30,11 +30,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed_NeverStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed_NeverStarted.cs index fb74e217d..9a12182e3 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed_NeverStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortDisposed_NeverStarted.cs @@ -24,11 +24,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortNeverStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortNeverStarted.cs index 22a1ae9fe..82c220624 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortNeverStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortNeverStarted.cs @@ -33,11 +33,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelBound.cs index 6980d3661..5f3ab59c1 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelBound.cs @@ -40,26 +40,14 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } - if (_channelBindStarted != null) - { - _channelBindStarted.Dispose(); - _channelBindStarted = null; - } - if (_channelBindCompleted != null) - { - _channelBindCompleted.Dispose(); - _channelBindCompleted = null; - } + _client?.Dispose(); + _client = null; + _forwardedPort?.Dispose(); + _forwardedPort = null; + _channelBindStarted?.Dispose(); + _channelBindStarted = null; + _channelBindCompleted?.Dispose(); + _channelBindCompleted = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelNotBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelNotBound.cs index 0f3b0a57c..f684f9ed5 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelNotBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelNotBound.cs @@ -35,11 +35,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStopped.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStopped.cs index a9dacf9a6..c17165b9f 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStopped.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStopped.cs @@ -33,11 +33,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortDisposed.cs index 6d841b9c9..d49b3219d 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortDisposed.cs @@ -28,11 +28,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortNeverStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortNeverStarted.cs index 9d003ff12..4a884631c 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortNeverStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortNeverStarted.cs @@ -35,11 +35,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStarted.cs index 60718f7b3..d3b4f4894 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStarted.cs @@ -36,11 +36,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStopped.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStopped.cs index c7d13ec38..0c61346cd 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStopped.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStopped.cs @@ -35,11 +35,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortDisposed.cs index 2806ec540..e62ac1cd6 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortDisposed.cs @@ -24,11 +24,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelBound.cs index a6432f38a..440a6f41c 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelBound.cs @@ -40,26 +40,14 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_client != null) - { - _client.Dispose(); - _client = null; - } - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } - if (_channelBound != null) - { - _channelBound.Dispose(); - _channelBound = null; - } - if (_channelBindCompleted != null) - { - _channelBindCompleted.Dispose(); - _channelBindCompleted = null; - } + _client?.Dispose(); + _client = null; + _forwardedPort?.Dispose(); + _forwardedPort = null; + _channelBound?.Dispose(); + _channelBound = null; + _channelBindCompleted?.Dispose(); + _channelBindCompleted = null; } private void CreateMocks() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelNotBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelNotBound.cs index b8e893db0..08c4e6ccc 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelNotBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelNotBound.cs @@ -35,11 +35,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStopped.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStopped.cs index 7ec8bde32..54b2594d9 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStopped.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStopped.cs @@ -33,11 +33,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortDisposed.cs index 2cedfbe5a..a8e2bd1b8 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortDisposed.cs @@ -27,11 +27,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortNeverStarted.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortNeverStarted.cs index 37f526e40..f559fec53 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortNeverStarted.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortNeverStarted.cs @@ -35,11 +35,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs index eea751b13..eb08449a8 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs @@ -49,23 +49,14 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (ForwardedPort != null) - { - ForwardedPort.Dispose(); - ForwardedPort = null; - } - - if (_channelBindStarted != null) - { - _channelBindStarted.Dispose(); - _channelBindStarted = null; - } - - if (_channelBindCompleted != null) - { - _channelBindCompleted.Dispose(); - _channelBindCompleted = null; - } + ForwardedPort?.Dispose(); + ForwardedPort = null; + + _channelBindStarted?.Dispose(); + _channelBindStarted = null; + + _channelBindCompleted?.Dispose(); + _channelBindCompleted = null; } private void CreateMocks() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStopped.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStopped.cs index ecb1a2ac2..fddcd680c 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStopped.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStopped.cs @@ -37,11 +37,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (ForwardedPort != null) - { - ForwardedPort.Dispose(); - ForwardedPort = null; - } + ForwardedPort?.Dispose(); + ForwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortDisposed.cs index 8b0b05112..ee7ee8699 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortDisposed.cs @@ -28,11 +28,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_SessionNull.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_SessionNull.cs index 9cd3a3046..7428b3652 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_SessionNull.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_SessionNull.cs @@ -28,11 +28,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Stop_PortDisposed.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Stop_PortDisposed.cs index 796bdda4d..53df67037 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Stop_PortDisposed.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Stop_PortDisposed.cs @@ -27,11 +27,8 @@ public void Setup() [TestCleanup] public void Cleanup() { - if (_forwardedPort != null) - { - _forwardedPort.Dispose(); - _forwardedPort = null; - } + _forwardedPort?.Dispose(); + _forwardedPort = null; } protected void Arrange() diff --git a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs index 24291fe73..c8ff510e9 100644 --- a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs +++ b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs @@ -66,23 +66,14 @@ public void Setup() [TestCleanup] public void TearDown() { - if (ServerListener != null) - { - ServerListener.Dispose(); - ServerListener = null; - } + ServerListener?.Dispose(); + ServerListener = null; - if (ServerSocket != null) - { - ServerSocket.Dispose(); - ServerSocket = null; - } + ServerSocket?.Dispose(); + ServerSocket = null; - if (Session != null) - { - Session.Dispose(); - Session = null; - } + Session?.Dispose(); + Session = null; if (ClientSocket != null && ClientSocket.Connected) { @@ -90,11 +81,8 @@ public void TearDown() ClientSocket.Dispose(); } - if (FirstKexReceived != null) - { - FirstKexReceived.Dispose(); - FirstKexReceived = null; - } + FirstKexReceived?.Dispose(); + FirstKexReceived = null; } protected virtual void SetupData() diff --git a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs index e8bb7bd7d..957bf2ece 100644 --- a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs +++ b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs @@ -79,23 +79,14 @@ protected virtual void ActionAfterKexInit() [TestCleanup] public void TearDown() { - if (ServerListener != null) - { - ServerListener.Dispose(); - ServerListener = null; - } + ServerListener?.Dispose(); + ServerListener = null; - if (ServerSocket != null) - { - ServerSocket.Dispose(); - ServerSocket = null; - } + ServerSocket?.Dispose(); + ServerSocket = null; - if (Session != null) - { - Session.Dispose(); - Session = null; - } + Session?.Dispose(); + Session = null; if (ClientSocket != null && ClientSocket.Connected) { diff --git a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs index 23e48799a..575d37160 100644 --- a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs +++ b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs @@ -90,11 +90,8 @@ public void Stop() _listener?.Dispose(); - if (_receiveThread != null) - { - _receiveThread.Join(); - _receiveThread = null; - } + _receiveThread?.Join(); + _receiveThread = null; } public void Dispose() From 45be01f6538ec333239598add43dfdfb1b375b51 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Tue, 15 Jul 2025 21:13:42 +0200 Subject: [PATCH 03/16] fix ca5399 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca5399 --- test/Renci.SshNet.IntegrationTests/SshTests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/Renci.SshNet.IntegrationTests/SshTests.cs b/test/Renci.SshNet.IntegrationTests/SshTests.cs index 276030e5d..4a4b5ffa3 100644 --- a/test/Renci.SshNet.IntegrationTests/SshTests.cs +++ b/test/Renci.SshNet.IntegrationTests/SshTests.cs @@ -542,7 +542,8 @@ public void Ssh_LocalPortForwardingCloseChannels() { using HttpClientHandler handler = new() { - AllowAutoRedirect = false + AllowAutoRedirect = false, + CheckCertificateRevocationList = true, }; using HttpClient httpClient = new(handler); @@ -598,7 +599,8 @@ public void Ssh_LocalPortForwarding() { using HttpClientHandler handler = new() { - AllowAutoRedirect = false + AllowAutoRedirect = false, + CheckCertificateRevocationList = true, }; using HttpClient httpClient = new(handler); From d0eb81280a6536cf85a2bbe308e680ed690d5531 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Tue, 15 Jul 2025 21:15:50 +0200 Subject: [PATCH 04/16] fix ca1515 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1515 --- test/Renci.SshNet.AotCompatibilityTestApp/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Renci.SshNet.AotCompatibilityTestApp/Program.cs b/test/Renci.SshNet.AotCompatibilityTestApp/Program.cs index a85c7ceda..4d5d1ced5 100644 --- a/test/Renci.SshNet.AotCompatibilityTestApp/Program.cs +++ b/test/Renci.SshNet.AotCompatibilityTestApp/Program.cs @@ -2,7 +2,7 @@ namespace Renci.SshNet.AotCompatibilityTestApp { - public static class Program + internal static class Program { public static void Main() { From c57b9231e81f2dc5d5ffecdb46f479c4ebce4104 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Tue, 15 Jul 2025 21:17:26 +0200 Subject: [PATCH 05/16] fix ca2002 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2002 --- src/Renci.SshNet/Common/Lock.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Renci.SshNet/Common/Lock.cs b/src/Renci.SshNet/Common/Lock.cs index fc29776d3..6e9496be6 100644 --- a/src/Renci.SshNet/Common/Lock.cs +++ b/src/Renci.SshNet/Common/Lock.cs @@ -5,14 +5,16 @@ namespace Renci.SshNet.Common { internal sealed class Lock { + private readonly object _lockObject = new object(); + public bool TryEnter() { - return Monitor.TryEnter(this); + return Monitor.TryEnter(_lockObject); } public void Exit() { - Monitor.Exit(this); + Monitor.Exit(_lockObject); } } } From 7c7eeb955b9c1d74e8902c38ddfe378426e4bee7 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Tue, 15 Jul 2025 21:35:27 +0200 Subject: [PATCH 06/16] fix ca1508 new false positives. https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1508 --- src/Renci.SshNet/Channels/ChannelDirectTcpip.cs | 4 ++++ src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs | 2 ++ src/Renci.SshNet/Sftp/SftpFileStream.cs | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs index 2e2c7527e..6d2b657cd 100644 --- a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs @@ -124,10 +124,12 @@ private void CloseSocket() lock (_socketLock) { +#pragma warning disable CA1508 // Avoid dead conditional code if (_socket is null) { return; } +#pragma warning restore CA1508 // Avoid dead conditional code // closing a socket actually disposes the socket, so we can safely dereference // the field to avoid entering the lock again later @@ -293,11 +295,13 @@ protected override void Dispose(bool disposing) lock (_socketLock) { var socket = _socket; +#pragma warning disable CA1508 // Avoid dead conditional code if (socket != null) { _socket = null; socket.Dispose(); } +#pragma warning restore CA1508 // Avoid dead conditional code } } diff --git a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs index 1f536ff27..87fbdb904 100644 --- a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs @@ -164,11 +164,13 @@ private void CloseSocket() lock (_socketShutdownAndCloseLock) { var socket = _socket; +#pragma warning disable CA1508 // Avoid dead conditional code if (socket != null) { _socket = null; socket.Dispose(); } +#pragma warning restore CA1508 // Avoid dead conditional code } } diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index c5e486a9a..a42ad0769 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -1065,6 +1065,7 @@ protected override void Dispose(bool disposing) { lock (_lock) { +#pragma warning disable CA1508 // Avoid dead conditional code if (_session != null) { _canRead = false; @@ -1088,6 +1089,7 @@ protected override void Dispose(bool disposing) _session = null; } +#pragma warning restore CA1508 // Avoid dead conditional code } } } From 8775b9412b6a2d580c73b10bffd71132efb39e41 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Tue, 15 Jul 2025 21:36:02 +0200 Subject: [PATCH 07/16] fix ca2000 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2000 --- src/Renci.SshNet/PrivateKeyFile.OpenSSH.cs | 10 +++++-- src/Renci.SshNet/PrivateKeyFile.PuTTY.cs | 4 +-- src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs | 34 +++++++++++----------- src/Renci.SshNet/Sftp/SftpFileStream.cs | 2 ++ src/Renci.SshNet/SftpClient.cs | 2 ++ 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Renci.SshNet/PrivateKeyFile.OpenSSH.cs b/src/Renci.SshNet/PrivateKeyFile.OpenSSH.cs index 0a02d8cf9..55fc11cae 100644 --- a/src/Renci.SshNet/PrivateKeyFile.OpenSSH.cs +++ b/src/Renci.SshNet/PrivateKeyFile.OpenSSH.cs @@ -32,7 +32,7 @@ public OpenSSH(byte[] data, string? passPhrase) /// public Key Parse() { - var keyReader = new SshDataStream(_data); + using var keyReader = new SshDataStream(_data); // check magic header var authMagic = "openssh-key-v1\0"u8; @@ -171,7 +171,7 @@ public Key Parse() // now parse the data we called the private key, it actually contains the public key again // so we need to parse through it to get the private key bytes, plus there's some // validation we need to do. - var privateKeyReader = new SshDataStream(privateKeyBytes); + using var privateKeyReader = new SshDataStream(privateKeyBytes); // check ints should match, they wouldn't match for example if the wrong passphrase was supplied var checkInt1 = (int)privateKeyReader.ReadUInt32(); @@ -200,7 +200,9 @@ public Key Parse() // k || ENC(A) unencryptedPrivateKey = privateKeyReader.ReadBinary(); +#pragma warning disable CA2000 // Dispose objects before losing scope parsedKey = new ED25519Key(unencryptedPrivateKey); +#pragma warning restore CA2000 // Dispose objects before losing scope break; case "ecdsa-sha2-nistp256": case "ecdsa-sha2-nistp384": @@ -210,7 +212,9 @@ public Key Parse() publicKey = privateKeyReader.ReadBinary(); unencryptedPrivateKey = privateKeyReader.ReadBinary(); +#pragma warning disable CA2000 // Dispose objects before losing scope parsedKey = new EcdsaKey(curve, publicKey, unencryptedPrivateKey.TrimLeadingZeros()); +#pragma warning restore CA2000 // Dispose objects before losing scope break; case "ssh-rsa": var modulus = privateKeyReader.ReadBigInt(); @@ -219,7 +223,9 @@ public Key Parse() var inverseQ = privateKeyReader.ReadBigInt(); var p = privateKeyReader.ReadBigInt(); var q = privateKeyReader.ReadBigInt(); +#pragma warning disable CA2000 // Dispose objects before losing scope parsedKey = new RsaKey(modulus, exponent, d, p, q, inverseQ); +#pragma warning restore CA2000 // Dispose objects before losing scope break; default: throw new SshException("OpenSSH key type '" + keyType + "' is not supported."); diff --git a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs index 3ac40242b..5e5b63118 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs @@ -163,11 +163,11 @@ public Key Parse() throw new SshException("MAC verification failed for PuTTY key file"); } - var publicKeyReader = new SshDataStream(_publicKey); + using var publicKeyReader = new SshDataStream(_publicKey); var keyType = publicKeyReader.ReadString(Encoding.UTF8); Debug.Assert(keyType == _algorithmName, $"{nameof(keyType)} is not the same as {nameof(_algorithmName)}"); - var privateKeyReader = new SshDataStream(privateKey); + using var privateKeyReader = new SshDataStream(privateKey); Key parsedKey; diff --git a/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs b/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs index 5be439608..5bae05f20 100644 --- a/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs +++ b/src/Renci.SshNet/PrivateKeyFile.SSHCOM.cs @@ -28,22 +28,22 @@ public SSHCOM(byte[] data, string? passPhrase) public Key Parse() { - var reader = new SshDataStream(_data); - var magicNumber = reader.ReadUInt32(); + using var dataReader = new SshDataStream(_data); + var magicNumber = dataReader.ReadUInt32(); if (magicNumber != 0x3f6ff9eb) { throw new SshException("Invalid SSH2 private key."); } - _ = reader.ReadUInt32(); // Read total bytes length including magic number - var keyType = reader.ReadString(SshData.Ascii); - var ssh2CipherName = reader.ReadString(SshData.Ascii); - var blobSize = (int)reader.ReadUInt32(); + _ = dataReader.ReadUInt32(); // Read total bytes length including magic number + var keyType = dataReader.ReadString(SshData.Ascii); + var ssh2CipherName = dataReader.ReadString(SshData.Ascii); + var blobSize = (int)dataReader.ReadUInt32(); byte[] keyData; if (ssh2CipherName == "none") { - keyData = reader.ReadBytes(blobSize); + keyData = dataReader.ReadBytes(blobSize); } else if (ssh2CipherName == "3des-cbc") { @@ -53,17 +53,17 @@ public Key Parse() } var key = GetCipherKey(_passPhrase, 192 / 8); - var ssh2Сipher = new TripleDesCipher(key, new byte[8], CipherMode.CBC, pkcs7Padding: false); - keyData = ssh2Сipher.Decrypt(reader.ReadBytes(blobSize)); + using var ssh2Сipher = new TripleDesCipher(key, new byte[8], CipherMode.CBC, pkcs7Padding: false); + keyData = ssh2Сipher.Decrypt(dataReader.ReadBytes(blobSize)); } else { throw new SshException(string.Format("Cipher method '{0}' is not supported.", ssh2CipherName)); } - reader = new SshDataStream(keyData); + using var keyReader = new SshDataStream(keyData); - var decryptedLength = reader.ReadUInt32(); + var decryptedLength = keyReader.ReadUInt32(); if (decryptedLength > blobSize - 4) { @@ -72,12 +72,12 @@ public Key Parse() if (keyType.Contains("rsa")) { - var exponent = ReadBigIntWithBits(reader); - var d = ReadBigIntWithBits(reader); - var modulus = ReadBigIntWithBits(reader); - var inverseQ = ReadBigIntWithBits(reader); - var q = ReadBigIntWithBits(reader); - var p = ReadBigIntWithBits(reader); + var exponent = ReadBigIntWithBits(keyReader); + var d = ReadBigIntWithBits(keyReader); + var modulus = ReadBigIntWithBits(keyReader); + var inverseQ = ReadBigIntWithBits(keyReader); + var q = ReadBigIntWithBits(keyReader); + var p = ReadBigIntWithBits(keyReader); return new RsaKey(modulus, exponent, d, p, q, inverseQ); } diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index a42ad0769..6ac7b4868 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -210,7 +210,9 @@ private SftpFileStream(ISftpSession session, string path, FileAccess access, int internal static SftpFileStream Open(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize) { +#pragma warning disable CA2000 // Dispose objects before losing scope return Open(session, path, mode, access, bufferSize, isAsync: false, CancellationToken.None).GetAwaiter().GetResult(); +#pragma warning restore CA2000 // Dispose objects before losing scope } internal static Task OpenAsync(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, CancellationToken cancellationToken) diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 949c64b3e..500edb1de 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -2136,6 +2136,7 @@ private List InternalSynchronizeDirectories(string sourcePath, string var remoteFileName = string.Format(CultureInfo.InvariantCulture, @"{0}/{1}", destinationPath, localFile.Name); try { +#pragma warning disable CA2000 // Dispose objects before losing scope using (var file = File.OpenRead(localFile.FullName)) { InternalUploadFile( @@ -2147,6 +2148,7 @@ private List InternalSynchronizeDirectories(string sourcePath, string isAsync: false, CancellationToken.None).GetAwaiter().GetResult(); } +#pragma warning restore CA2000 // Dispose objects before losing scope uploadedFiles.Add(localFile); From 0efb9ee62aaf71080c16f2d548e100b527e56c44 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Thu, 14 Aug 2025 20:39:58 +0200 Subject: [PATCH 08/16] fix ca2025 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2025 --- src/Renci.SshNet/SftpClient.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 500edb1de..afd2e2066 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -2139,6 +2139,7 @@ private List InternalSynchronizeDirectories(string sourcePath, string #pragma warning disable CA2000 // Dispose objects before losing scope using (var file = File.OpenRead(localFile.FullName)) { +#pragma warning disable CA2025 // Do not pass 'IDisposable' instances into unawaited tasks InternalUploadFile( file, remoteFileName, @@ -2147,6 +2148,7 @@ private List InternalSynchronizeDirectories(string sourcePath, string uploadCallback: null, isAsync: false, CancellationToken.None).GetAwaiter().GetResult(); +#pragma warning restore CA2025 // Do not pass 'IDisposable' instances into unawaited tasks } #pragma warning restore CA2000 // Dispose objects before losing scope From cce3cc7c0092af82b79d10bfc0a36d36fc2795a0 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Thu, 14 Aug 2025 20:40:03 +0200 Subject: [PATCH 09/16] fix ca1849 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1849 --- src/Renci.SshNet/SftpClient.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index afd2e2066..df7956718 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -2363,6 +2363,7 @@ private async Task InternalUploadFile( while (true) { +#pragma warning disable CA1849 // Call async methods when in an async method var bytesRead = isAsync #if NET ? await input.ReadAsync(buffer, cancellationToken).ConfigureAwait(false) @@ -2370,6 +2371,7 @@ private async Task InternalUploadFile( ? await input.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false) #endif : input.Read(buffer, 0, buffer.Length); +#pragma warning restore CA1849 // Call async methods when in an async method if (bytesRead == 0) { From 90510ea49072047f0face38801424ef48d8dace2 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Thu, 11 Sep 2025 18:20:26 +0200 Subject: [PATCH 10/16] fix Reverse() overloads because of https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/csharp-overload-resolution --- ...ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs | 2 +- ...orwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs | 2 +- .../ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs index 76e819d5f..a1073661b 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs @@ -211,7 +211,7 @@ private void EstablishSocks4Connection(Socket client) { var userNameBytes = Encoding.ASCII.GetBytes(_userName); var addressBytes = _remoteEndpoint.Address.GetAddressBytes(); - var portBytes = BitConverter.GetBytes((ushort)_remoteEndpoint.Port).Reverse().ToArray(); + var portBytes = BitConverter.GetBytes((ushort)_remoteEndpoint.Port).AsEnumerable().Reverse().ToArray(); _client.Connect(_endpoint); diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs index dd26b91d5..dd12165c6 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs @@ -218,7 +218,7 @@ private void EstablishSocks4Connection(Socket client) { var userNameBytes = Encoding.ASCII.GetBytes(_userName); var addressBytes = _remoteEndpoint.Address.GetAddressBytes(); - var portBytes = BitConverter.GetBytes((ushort)_remoteEndpoint.Port).Reverse().ToArray(); + var portBytes = BitConverter.GetBytes((ushort)_remoteEndpoint.Port).AsEnumerable().Reverse().ToArray(); _client.Connect(_endpoint); diff --git a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs index cfda2a209..4733f5233 100644 --- a/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs +++ b/test/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs @@ -198,7 +198,7 @@ private void EstablishSocks4Connection(Socket client) { var userNameBytes = Encoding.ASCII.GetBytes(_userName); var addressBytes = _remoteEndpoint.Address.GetAddressBytes(); - var portBytes = BitConverter.GetBytes((ushort)_remoteEndpoint.Port).Reverse().ToArray(); + var portBytes = BitConverter.GetBytes((ushort)_remoteEndpoint.Port).AsEnumerable().Reverse().ToArray(); _client.Connect(_endpoint); From 85c7895e94dd599f547babfec9a5a3c77121b9f8 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Thu, 11 Sep 2025 19:01:24 +0200 Subject: [PATCH 11/16] supress CA2002 --- src/Renci.SshNet/Common/Lock.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Renci.SshNet/Common/Lock.cs b/src/Renci.SshNet/Common/Lock.cs index 6e9496be6..b402390ab 100644 --- a/src/Renci.SshNet/Common/Lock.cs +++ b/src/Renci.SshNet/Common/Lock.cs @@ -5,16 +5,16 @@ namespace Renci.SshNet.Common { internal sealed class Lock { - private readonly object _lockObject = new object(); - public bool TryEnter() { - return Monitor.TryEnter(_lockObject); +#pragma warning disable CA2002 // Do not lock on objects with weak identity + return Monitor.TryEnter(this); +#pragma warning restore CA2002 // Do not lock on objects with weak identity } public void Exit() { - Monitor.Exit(_lockObject); + Monitor.Exit(this); } } } From e4fb0c9554d8b4ef1de7fb535992b8e33b01e109 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 18 Apr 2025 13:44:44 +0200 Subject: [PATCH 12/16] Use extension members for ThrowHelpers --- .../Abstractions/ThreadAbstraction.cs | 6 +- .../Abstractions/ThrowExtensions.cs | 94 ++++++++++++++++ src/Renci.SshNet/AuthenticationMethod.cs | 4 +- src/Renci.SshNet/BaseClient.cs | 6 +- src/Renci.SshNet/ClientAuthentication.cs | 4 +- .../Common/ChannelDataEventArgs.cs | 2 +- src/Renci.SshNet/Common/ChannelInputStream.cs | 2 +- .../Common/ChannelRequestEventArgs.cs | 2 +- src/Renci.SshNet/Common/Extensions.cs | 10 +- src/Renci.SshNet/Common/HostKeyEventArgs.cs | 2 +- src/Renci.SshNet/Common/PacketDump.cs | 4 +- src/Renci.SshNet/Common/PipeStream.cs | 2 +- .../Common/PortForwardEventArgs.cs | 2 +- src/Renci.SshNet/Common/PosixPath.cs | 6 +- src/Renci.SshNet/Common/SshData.cs | 4 +- src/Renci.SshNet/Common/SshDataStream.cs | 8 +- src/Renci.SshNet/Common/TaskToAsyncResult.cs | 24 +---- src/Renci.SshNet/Common/ThrowHelper.cs | 100 +----------------- src/Renci.SshNet/Connection/ConnectorBase.cs | 2 +- .../Connection/SshIdentification.cs | 6 +- src/Renci.SshNet/ConnectionInfo.cs | 10 +- src/Renci.SshNet/ExpectAction.cs | 10 +- src/Renci.SshNet/ForwardedPortDynamic.cs | 2 +- src/Renci.SshNet/ForwardedPortLocal.cs | 6 +- src/Renci.SshNet/ForwardedPortRemote.cs | 6 +- src/Renci.SshNet/MessageEventArgs`1.cs | 4 +- .../Messages/Connection/ChannelDataMessage.cs | 6 +- .../ChannelOpen/ChannelOpenMessage.cs | 4 +- .../ChannelRequest/ExecRequestInfo.cs | 6 +- .../Messages/Transport/IgnoreMessage.cs | 4 +- src/Renci.SshNet/NoneAuthenticationMethod.cs | 3 +- .../OrderedDictionary.netstandard.cs | 6 +- .../PasswordAuthenticationMethod.cs | 4 +- .../PrivateKeyAuthenticationMethod.cs | 2 +- src/Renci.SshNet/PrivateKeyFile.PuTTY.cs | 10 +- src/Renci.SshNet/PrivateKeyFile.cs | 6 +- .../RemotePathDoubleQuoteTransformation.cs | 4 +- .../RemotePathNoneTransformation.cs | 4 +- .../RemotePathShellQuoteTransformation.cs | 4 +- src/Renci.SshNet/ScpClient.cs | 20 ++-- .../Cryptography/Ciphers/AesCipher.BclImpl.cs | 2 +- .../Cryptography/ED25519DigitalSignature.cs | 2 +- .../Security/Cryptography/ED25519Key.cs | 2 +- .../Cryptography/EcdsaDigitalSignature.cs | 2 +- .../Security/Cryptography/EcdsaKey.cs | 2 +- .../Security/Cryptography/RsaKey.cs | 4 +- .../Security/Cryptography/SymmetricCipher.cs | 4 +- .../Security/KeyExchangeDiffieHellman.cs | 7 +- .../KeyExchangeDiffieHellmanGroupExchange.cs | 5 +- src/Renci.SshNet/ServiceFactory.cs | 8 +- src/Renci.SshNet/Session.cs | 10 +- .../Sftp/Requests/SftpRealPathRequest.cs | 3 +- src/Renci.SshNet/Sftp/SftpFile.cs | 6 +- src/Renci.SshNet/Sftp/SftpFileReader.cs | 2 +- src/Renci.SshNet/Sftp/SftpFileStream.cs | 6 +- src/Renci.SshNet/Sftp/SftpSession.cs | 12 +-- src/Renci.SshNet/SftpClient.cs | 88 +++++++-------- src/Renci.SshNet/ShellStream.cs | 6 +- src/Renci.SshNet/SshClient.cs | 4 +- src/Renci.SshNet/SshCommand.cs | 10 +- src/Renci.SshNet/SshMessageFactory.cs | 4 +- .../SshNetLoggingConfiguration.cs | 6 +- src/Renci.SshNet/SubsystemSession.cs | 10 +- .../Common/Socks5Handler.cs | 4 +- 64 files changed, 287 insertions(+), 333 deletions(-) create mode 100644 src/Renci.SshNet/Abstractions/ThrowExtensions.cs diff --git a/src/Renci.SshNet/Abstractions/ThreadAbstraction.cs b/src/Renci.SshNet/Abstractions/ThreadAbstraction.cs index 41db80396..5fab1e7b1 100644 --- a/src/Renci.SshNet/Abstractions/ThreadAbstraction.cs +++ b/src/Renci.SshNet/Abstractions/ThreadAbstraction.cs @@ -2,8 +2,6 @@ using System.Threading; using System.Threading.Tasks; -using Renci.SshNet.Common; - namespace Renci.SshNet.Abstractions { internal static class ThreadAbstraction @@ -18,7 +16,7 @@ internal static class ThreadAbstraction /// public static Task ExecuteThreadLongRunning(Action action) { - ThrowHelper.ThrowIfNull(action); + ArgumentNullException.ThrowIfNull(action); return Task.Factory.StartNew(action, CancellationToken.None, @@ -32,7 +30,7 @@ public static Task ExecuteThreadLongRunning(Action action) /// The action to execute. public static void ExecuteThread(Action action) { - ThrowHelper.ThrowIfNull(action); + ArgumentNullException.ThrowIfNull(action); _ = ThreadPool.QueueUserWorkItem(o => action()); } diff --git a/src/Renci.SshNet/Abstractions/ThrowExtensions.cs b/src/Renci.SshNet/Abstractions/ThrowExtensions.cs new file mode 100644 index 000000000..0c4b988fc --- /dev/null +++ b/src/Renci.SshNet/Abstractions/ThrowExtensions.cs @@ -0,0 +1,94 @@ +#nullable enable +#if !NET +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace System +{ + internal static class ThrowExtensions + { + extension(ObjectDisposedException) + { + public static void ThrowIf(bool condition, object instance) + { + if (condition) + { + Throw(instance); + + static void Throw(object? instance) + { + throw new ObjectDisposedException(instance?.GetType().FullName); + } + } + } + } + + extension(ArgumentNullException) + { + public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) + { + if (argument is null) + { + ThrowArgumentNullException(paramName); + } + + [DoesNotReturn] + static void ThrowArgumentNullException(string? paramName) + { + throw new ArgumentNullException(paramName); + } + } + } + + extension(ArgumentException) + { + public static void ThrowIfNullOrWhiteSpace([NotNull] string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) + { + if (string.IsNullOrWhiteSpace(argument)) + { + Throw(argument, paramName); + + [DoesNotReturn] + static void Throw(string? argument, string? paramName) + { + ThrowIfNull(argument, paramName); + throw new ArgumentException("The value cannot be an empty string or composed entirely of whitespace.", paramName); + } + } + } + + public static void ThrowIfNullOrEmpty([NotNull] string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) + { + if (string.IsNullOrEmpty(argument)) + { + Throw(argument, paramName); + + [DoesNotReturn] + static void Throw(string? argument, string? paramName) + { + ThrowIfNull(argument, paramName); + throw new ArgumentException("The value cannot be an empty string.", paramName); + } + } + } + } + + extension(ArgumentOutOfRangeException) + { + public static void ThrowIfNegative(long value, [CallerArgumentExpression(nameof(value))] string? paramName = null) + { + if (value < 0) + { + Throw(value, paramName); + + [DoesNotReturn] + static void Throw(long value, string? paramName) + { + throw new ArgumentOutOfRangeException(paramName, value, "Value must be non-negative."); + } + } + } + } + } +} +#endif diff --git a/src/Renci.SshNet/AuthenticationMethod.cs b/src/Renci.SshNet/AuthenticationMethod.cs index 3c5f2cfb3..fc205b109 100644 --- a/src/Renci.SshNet/AuthenticationMethod.cs +++ b/src/Renci.SshNet/AuthenticationMethod.cs @@ -1,7 +1,5 @@ using System; -using Renci.SshNet.Common; - namespace Renci.SshNet { /// @@ -36,7 +34,7 @@ public abstract class AuthenticationMethod : IAuthenticationMethod, IDisposable /// is whitespace or . protected AuthenticationMethod(string username) { - ThrowHelper.ThrowIfNullOrWhiteSpace(username); + ArgumentException.ThrowIfNullOrWhiteSpace(username); Username = username; } diff --git a/src/Renci.SshNet/BaseClient.cs b/src/Renci.SshNet/BaseClient.cs index 4b0850b15..243d83dab 100644 --- a/src/Renci.SshNet/BaseClient.cs +++ b/src/Renci.SshNet/BaseClient.cs @@ -186,8 +186,8 @@ protected BaseClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo) /// private protected BaseClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, IServiceFactory serviceFactory) { - ThrowHelper.ThrowIfNull(connectionInfo); - ThrowHelper.ThrowIfNull(serviceFactory); + ArgumentNullException.ThrowIfNull(connectionInfo); + ArgumentNullException.ThrowIfNull(serviceFactory); _connectionInfo = connectionInfo; _ownsConnectionInfo = ownsConnectionInfo; @@ -467,7 +467,7 @@ protected virtual void Dispose(bool disposing) /// The current instance is disposed. protected void CheckDisposed() { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); } /// diff --git a/src/Renci.SshNet/ClientAuthentication.cs b/src/Renci.SshNet/ClientAuthentication.cs index bd386ed27..7f998caf1 100644 --- a/src/Renci.SshNet/ClientAuthentication.cs +++ b/src/Renci.SshNet/ClientAuthentication.cs @@ -52,8 +52,8 @@ internal int PartialSuccessLimit /// Failed to authenticate the client. public void Authenticate(IConnectionInfoInternal connectionInfo, ISession session) { - ThrowHelper.ThrowIfNull(connectionInfo); - ThrowHelper.ThrowIfNull(session); + ArgumentNullException.ThrowIfNull(connectionInfo); + ArgumentNullException.ThrowIfNull(session); session.RegisterMessage("SSH_MSG_USERAUTH_FAILURE"); session.RegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); diff --git a/src/Renci.SshNet/Common/ChannelDataEventArgs.cs b/src/Renci.SshNet/Common/ChannelDataEventArgs.cs index 5ded6fe0b..1698dd295 100644 --- a/src/Renci.SshNet/Common/ChannelDataEventArgs.cs +++ b/src/Renci.SshNet/Common/ChannelDataEventArgs.cs @@ -16,7 +16,7 @@ internal class ChannelDataEventArgs : ChannelEventArgs public ChannelDataEventArgs(uint channelNumber, ArraySegment data) : base(channelNumber) { - ThrowHelper.ThrowIfNull(data.Array); + ArgumentNullException.ThrowIfNull(data.Array); Data = data; } diff --git a/src/Renci.SshNet/Common/ChannelInputStream.cs b/src/Renci.SshNet/Common/ChannelInputStream.cs index a5dd0b417..8be3a662f 100644 --- a/src/Renci.SshNet/Common/ChannelInputStream.cs +++ b/src/Renci.SshNet/Common/ChannelInputStream.cs @@ -106,7 +106,7 @@ public override void Write(byte[] buffer, int offset, int count) #endif ValidateBufferArguments(buffer, offset, count); - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); if (count == 0) { diff --git a/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs b/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs index ca82312e1..7677f1cb6 100644 --- a/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs +++ b/src/Renci.SshNet/Common/ChannelRequestEventArgs.cs @@ -16,7 +16,7 @@ internal sealed class ChannelRequestEventArgs : EventArgs /// is . public ChannelRequestEventArgs(RequestInfo info) { - ThrowHelper.ThrowIfNull(info); + ArgumentNullException.ThrowIfNull(info); Info = info; } diff --git a/src/Renci.SshNet/Common/Extensions.cs b/src/Renci.SshNet/Common/Extensions.cs index b7a97d067..89ac0b402 100644 --- a/src/Renci.SshNet/Common/Extensions.cs +++ b/src/Renci.SshNet/Common/Extensions.cs @@ -193,7 +193,7 @@ internal static void ValidatePort(this int value, [CallerArgumentExpression(name /// public static byte[] Take(this byte[] value, int offset, int count) { - ThrowHelper.ThrowIfNull(value); + ArgumentNullException.ThrowIfNull(value); if (count == 0) { @@ -225,7 +225,7 @@ public static byte[] Take(this byte[] value, int offset, int count) /// public static byte[] Take(this byte[] value, int count) { - ThrowHelper.ThrowIfNull(value); + ArgumentNullException.ThrowIfNull(value); if (count == 0) { @@ -244,8 +244,8 @@ public static byte[] Take(this byte[] value, int count) public static bool IsEqualTo(this byte[] left, byte[] right) { - ThrowHelper.ThrowIfNull(left); - ThrowHelper.ThrowIfNull(right); + ArgumentNullException.ThrowIfNull(left); + ArgumentNullException.ThrowIfNull(right); return left.AsSpan().SequenceEqual(right); } @@ -259,7 +259,7 @@ public static bool IsEqualTo(this byte[] left, byte[] right) /// public static byte[] TrimLeadingZeros(this byte[] value) { - ThrowHelper.ThrowIfNull(value); + ArgumentNullException.ThrowIfNull(value); for (var i = 0; i < value.Length; i++) { diff --git a/src/Renci.SshNet/Common/HostKeyEventArgs.cs b/src/Renci.SshNet/Common/HostKeyEventArgs.cs index b18d0cb4d..37fe829a5 100644 --- a/src/Renci.SshNet/Common/HostKeyEventArgs.cs +++ b/src/Renci.SshNet/Common/HostKeyEventArgs.cs @@ -97,7 +97,7 @@ public string FingerPrintMD5 /// is . public HostKeyEventArgs(KeyHostAlgorithm host) { - ThrowHelper.ThrowIfNull(host); + ArgumentNullException.ThrowIfNull(host); CanTrust = true; HostKey = host.KeyData.GetBytes(); diff --git a/src/Renci.SshNet/Common/PacketDump.cs b/src/Renci.SshNet/Common/PacketDump.cs index ec3b58587..66b2b9bf7 100644 --- a/src/Renci.SshNet/Common/PacketDump.cs +++ b/src/Renci.SshNet/Common/PacketDump.cs @@ -14,8 +14,8 @@ public static string Create(List data, int indentLevel) public static string Create(byte[] data, int indentLevel) { - ThrowHelper.ThrowIfNull(data); - ThrowHelper.ThrowIfNegative(indentLevel); + ArgumentNullException.ThrowIfNull(data); + ArgumentOutOfRangeException.ThrowIfNegative(indentLevel); const int lineWidth = 16; diff --git a/src/Renci.SshNet/Common/PipeStream.cs b/src/Renci.SshNet/Common/PipeStream.cs index 49e48b6ee..2a8d739e4 100644 --- a/src/Renci.SshNet/Common/PipeStream.cs +++ b/src/Renci.SshNet/Common/PipeStream.cs @@ -123,7 +123,7 @@ private void WriteCore(ReadOnlySpan buffer) { Debug.Assert(Monitor.IsEntered(_sync)); - ThrowHelper.ThrowObjectDisposedIf(_disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); _buffer.EnsureAvailableSpace(buffer.Length); diff --git a/src/Renci.SshNet/Common/PortForwardEventArgs.cs b/src/Renci.SshNet/Common/PortForwardEventArgs.cs index 89def98cf..9d427fe08 100644 --- a/src/Renci.SshNet/Common/PortForwardEventArgs.cs +++ b/src/Renci.SshNet/Common/PortForwardEventArgs.cs @@ -17,7 +17,7 @@ public sealed class PortForwardEventArgs : EventArgs /// is not within and . internal PortForwardEventArgs(string host, uint port) { - ThrowHelper.ThrowIfNull(host); + ArgumentNullException.ThrowIfNull(host); port.ValidatePort(); OriginatorHost = host; diff --git a/src/Renci.SshNet/Common/PosixPath.cs b/src/Renci.SshNet/Common/PosixPath.cs index 4d89c79f5..3a487b1ed 100644 --- a/src/Renci.SshNet/Common/PosixPath.cs +++ b/src/Renci.SshNet/Common/PosixPath.cs @@ -38,7 +38,7 @@ private PosixPath() /// is empty (""). public static PosixPath CreateAbsoluteOrRelativeFilePath(string path) { - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); var posixPath = new PosixPath(); @@ -92,7 +92,7 @@ public static PosixPath CreateAbsoluteOrRelativeFilePath(string path) /// public static string GetFileName(string path) { - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); var pathEnd = path.LastIndexOf('/'); if (pathEnd == -1) @@ -119,7 +119,7 @@ public static string GetFileName(string path) /// is . public static string GetDirectoryName(string path) { - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); var pathEnd = path.LastIndexOf('/'); if (pathEnd == -1) diff --git a/src/Renci.SshNet/Common/SshData.cs b/src/Renci.SshNet/Common/SshData.cs index 098408731..ff50a2148 100644 --- a/src/Renci.SshNet/Common/SshData.cs +++ b/src/Renci.SshNet/Common/SshData.cs @@ -91,7 +91,7 @@ protected virtual void WriteBytes(SshDataStream stream) /// is . public void Load(byte[] data) { - ThrowHelper.ThrowIfNull(data); + ArgumentNullException.ThrowIfNull(data); LoadInternal(data, 0, data.Length); } @@ -105,7 +105,7 @@ public void Load(byte[] data) /// is . public void Load(byte[] data, int offset, int count) { - ThrowHelper.ThrowIfNull(data); + ArgumentNullException.ThrowIfNull(data); LoadInternal(data, offset, count); } diff --git a/src/Renci.SshNet/Common/SshDataStream.cs b/src/Renci.SshNet/Common/SshDataStream.cs index a13b635ea..de0530bd0 100644 --- a/src/Renci.SshNet/Common/SshDataStream.cs +++ b/src/Renci.SshNet/Common/SshDataStream.cs @@ -112,7 +112,7 @@ public void Write(BigInteger data) /// is . public void Write(byte[] data) { - ThrowHelper.ThrowIfNull(data); + ArgumentNullException.ThrowIfNull(data); Write(data, 0, data.Length); } @@ -126,8 +126,8 @@ public void Write(byte[] data) /// is . public void Write(string s, Encoding encoding) { - ThrowHelper.ThrowIfNull(s); - ThrowHelper.ThrowIfNull(encoding); + ArgumentNullException.ThrowIfNull(s); + ArgumentNullException.ThrowIfNull(encoding); #if NET ReadOnlySpan value = s; @@ -192,7 +192,7 @@ private ArraySegment GetRemainingBuffer() /// is . public void WriteBinary(byte[] buffer) { - ThrowHelper.ThrowIfNull(buffer); + ArgumentNullException.ThrowIfNull(buffer); WriteBinary(buffer, 0, buffer.Length); } diff --git a/src/Renci.SshNet/Common/TaskToAsyncResult.cs b/src/Renci.SshNet/Common/TaskToAsyncResult.cs index febeb6580..d863ab559 100644 --- a/src/Renci.SshNet/Common/TaskToAsyncResult.cs +++ b/src/Renci.SshNet/Common/TaskToAsyncResult.cs @@ -1,6 +1,6 @@ #pragma warning disable #if !NET -// Copied verbatim from https://github.com/dotnet/runtime/blob/261611930d6b436d7c4395450356b624d903d9bf/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs +// Copied verbatim from https://github.com/dotnet/runtime/blob/7b2de1e5ed6368c536ee646346e6fd81939e6fe6/src/libraries/Common/src/System/Threading/Tasks/TaskToAsyncResult.cs // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -35,15 +35,7 @@ static class TaskToAsyncResult /// public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state) { -#if NET ArgumentNullException.ThrowIfNull(task); -#else - if (task is null) - { - throw new ArgumentNullException(nameof(task)); - } -#endif - return new TaskAsyncResult(task, state, callback); } @@ -72,14 +64,7 @@ public static TResult End(IAsyncResult asyncResult) => /// was not produced by a call to . public static Task Unwrap(IAsyncResult asyncResult) { -#if NET ArgumentNullException.ThrowIfNull(asyncResult); -#else - if (asyncResult is null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } -#endif if ((asyncResult as TaskAsyncResult)?._task is not Task task) { @@ -101,14 +86,7 @@ public static Task Unwrap(IAsyncResult asyncResult) /// public static Task Unwrap(IAsyncResult asyncResult) { -#if NET ArgumentNullException.ThrowIfNull(asyncResult); -#else - if (asyncResult is null) - { - throw new ArgumentNullException(nameof(asyncResult)); - } -#endif if ((asyncResult as TaskAsyncResult)?._task is not Task task) { diff --git a/src/Renci.SshNet/Common/ThrowHelper.cs b/src/Renci.SshNet/Common/ThrowHelper.cs index be6b13b4b..ddeb1e5bd 100644 --- a/src/Renci.SshNet/Common/ThrowHelper.cs +++ b/src/Renci.SshNet/Common/ThrowHelper.cs @@ -1,93 +1,19 @@ #nullable enable +#if !NET using System; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; namespace Renci.SshNet.Common { internal static class ThrowHelper { - public static void ThrowObjectDisposedIf(bool condition, object instance) - { -#if NET - ObjectDisposedException.ThrowIf(condition, instance); -#else - if (condition) - { - Throw(instance); - - static void Throw(object? instance) - { - throw new ObjectDisposedException(instance?.GetType().FullName); - } - } -#endif - } - - public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) - { -#if NET - ArgumentNullException.ThrowIfNull(argument, paramName); -#else - if (argument is null) - { - Throw(paramName); - - [DoesNotReturn] - static void Throw(string? paramName) - { - throw new ArgumentNullException(paramName); - } - } -#endif - } - - public static void ThrowIfNullOrWhiteSpace([NotNull] string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) - { -#if NET - ArgumentException.ThrowIfNullOrWhiteSpace(argument, paramName); -#else - if (string.IsNullOrWhiteSpace(argument)) - { - Throw(argument, paramName); - - [DoesNotReturn] - static void Throw(string? argument, string? paramName) - { - ThrowIfNull(argument, paramName); - throw new ArgumentException("The value cannot be an empty string or composed entirely of whitespace.", paramName); - } - } -#endif - } - - public static void ThrowIfNullOrEmpty([NotNull] string? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) - { -#if NET - ArgumentException.ThrowIfNullOrEmpty(argument, paramName); -#else - if (string.IsNullOrEmpty(argument)) - { - Throw(argument, paramName); - - [DoesNotReturn] - static void Throw(string? argument, string? paramName) - { - ThrowIfNull(argument, paramName); - throw new ArgumentException("The value cannot be an empty string.", paramName); - } - } -#endif - } - -#if !NET // A rough copy of // https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs#L960C13-L974C10 // for lower targets. public static void ValidateBufferArguments(byte[] buffer, int offset, int count) { - ThrowIfNull(buffer); - ThrowIfNegative(offset); + ArgumentNullException.ThrowIfNull(buffer); + ArgumentOutOfRangeException.ThrowIfNegative(offset); if ((uint)count > buffer.Length - offset) { @@ -102,24 +28,6 @@ static void Throw() } } } -#endif - - public static void ThrowIfNegative(long value, [CallerArgumentExpression(nameof(value))] string? paramName = null) - { -#if NET - ArgumentOutOfRangeException.ThrowIfNegative(value, paramName); -#else - if (value < 0) - { - Throw(value, paramName); - - [DoesNotReturn] - static void Throw(long value, string? paramName) - { - throw new ArgumentOutOfRangeException(paramName, value, "Value must be non-negative."); - } - } -#endif - } } } +#endif diff --git a/src/Renci.SshNet/Connection/ConnectorBase.cs b/src/Renci.SshNet/Connection/ConnectorBase.cs index 0816967b6..8dd09f797 100644 --- a/src/Renci.SshNet/Connection/ConnectorBase.cs +++ b/src/Renci.SshNet/Connection/ConnectorBase.cs @@ -18,7 +18,7 @@ internal abstract class ConnectorBase : IConnector protected ConnectorBase(ISocketFactory socketFactory, ILoggerFactory loggerFactory) { - ThrowHelper.ThrowIfNull(socketFactory); + ArgumentNullException.ThrowIfNull(socketFactory); SocketFactory = socketFactory; _logger = loggerFactory.CreateLogger(GetType()); diff --git a/src/Renci.SshNet/Connection/SshIdentification.cs b/src/Renci.SshNet/Connection/SshIdentification.cs index 41e06e277..25e84d03d 100644 --- a/src/Renci.SshNet/Connection/SshIdentification.cs +++ b/src/Renci.SshNet/Connection/SshIdentification.cs @@ -1,7 +1,5 @@ using System; -using Renci.SshNet.Common; - namespace Renci.SshNet.Connection { /// @@ -33,8 +31,8 @@ public SshIdentification(string protocolVersion, string softwareVersion) /// is . public SshIdentification(string protocolVersion, string softwareVersion, string comments) { - ThrowHelper.ThrowIfNull(protocolVersion); - ThrowHelper.ThrowIfNull(softwareVersion); + ArgumentNullException.ThrowIfNull(protocolVersion); + ArgumentNullException.ThrowIfNull(softwareVersion); ProtocolVersion = protocolVersion; SoftwareVersion = softwareVersion; diff --git a/src/Renci.SshNet/ConnectionInfo.cs b/src/Renci.SshNet/ConnectionInfo.cs index 18ca1eeb8..8b2fc6083 100644 --- a/src/Renci.SshNet/ConnectionInfo.cs +++ b/src/Renci.SshNet/ConnectionInfo.cs @@ -325,17 +325,17 @@ public ConnectionInfo(string host, int port, string username, params Authenticat /// No specified. public ConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params AuthenticationMethod[] authenticationMethods) { - ThrowHelper.ThrowIfNull(host); + ArgumentNullException.ThrowIfNull(host); port.ValidatePort(); - ThrowHelper.ThrowIfNullOrWhiteSpace(username); + ArgumentException.ThrowIfNullOrWhiteSpace(username); if (proxyType != ProxyTypes.None) { - ThrowHelper.ThrowIfNull(proxyHost); + ArgumentNullException.ThrowIfNull(proxyHost); proxyPort.ValidatePort(); } - ThrowHelper.ThrowIfNull(authenticationMethods); + ArgumentNullException.ThrowIfNull(authenticationMethods); if (authenticationMethods.Length == 0) { @@ -459,7 +459,7 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy /// No suitable authentication method found to complete authentication, or permission denied. internal void Authenticate(ISession session, IServiceFactory serviceFactory) { - ThrowHelper.ThrowIfNull(serviceFactory); + ArgumentNullException.ThrowIfNull(serviceFactory); IsAuthenticated = false; var clientAuthentication = serviceFactory.CreateClientAuthentication(); diff --git a/src/Renci.SshNet/ExpectAction.cs b/src/Renci.SshNet/ExpectAction.cs index 1e06aa753..7b64c5bff 100644 --- a/src/Renci.SshNet/ExpectAction.cs +++ b/src/Renci.SshNet/ExpectAction.cs @@ -1,8 +1,6 @@ using System; using System.Text.RegularExpressions; -using Renci.SshNet.Common; - namespace Renci.SshNet { /// @@ -28,8 +26,8 @@ public class ExpectAction /// or is . public ExpectAction(Regex expect, Action action) { - ThrowHelper.ThrowIfNull(expect); - ThrowHelper.ThrowIfNull(action); + ArgumentNullException.ThrowIfNull(expect); + ArgumentNullException.ThrowIfNull(action); Expect = expect; Action = action; @@ -43,8 +41,8 @@ public ExpectAction(Regex expect, Action action) /// or is . public ExpectAction(string expect, Action action) { - ThrowHelper.ThrowIfNull(expect); - ThrowHelper.ThrowIfNull(action); + ArgumentNullException.ThrowIfNull(expect); + ArgumentNullException.ThrowIfNull(action); Expect = new Regex(Regex.Escape(expect)); Action = action; diff --git a/src/Renci.SshNet/ForwardedPortDynamic.cs b/src/Renci.SshNet/ForwardedPortDynamic.cs index 72045e4c6..45ef5a3be 100644 --- a/src/Renci.SshNet/ForwardedPortDynamic.cs +++ b/src/Renci.SshNet/ForwardedPortDynamic.cs @@ -130,7 +130,7 @@ protected override void StopPort(TimeSpan timeout) /// The current instance is disposed. protected override void CheckDisposed() { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); } /// diff --git a/src/Renci.SshNet/ForwardedPortLocal.cs b/src/Renci.SshNet/ForwardedPortLocal.cs index 6ee313dfa..953bd8cf5 100644 --- a/src/Renci.SshNet/ForwardedPortLocal.cs +++ b/src/Renci.SshNet/ForwardedPortLocal.cs @@ -91,8 +91,8 @@ public ForwardedPortLocal(string boundHost, string host, uint port) /// is greater than . public ForwardedPortLocal(string boundHost, uint boundPort, string host, uint port) { - ThrowHelper.ThrowIfNull(boundHost); - ThrowHelper.ThrowIfNull(host); + ArgumentNullException.ThrowIfNull(boundHost); + ArgumentNullException.ThrowIfNull(host); boundPort.ValidatePort(); port.ValidatePort(); @@ -158,7 +158,7 @@ protected override void StopPort(TimeSpan timeout) /// The current instance is disposed. protected override void CheckDisposed() { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); } /// diff --git a/src/Renci.SshNet/ForwardedPortRemote.cs b/src/Renci.SshNet/ForwardedPortRemote.cs index 6186f78c1..3d9393dd2 100644 --- a/src/Renci.SshNet/ForwardedPortRemote.cs +++ b/src/Renci.SshNet/ForwardedPortRemote.cs @@ -88,8 +88,8 @@ public string Host /// is greater than . public ForwardedPortRemote(IPAddress boundHostAddress, uint boundPort, IPAddress hostAddress, uint port) { - ThrowHelper.ThrowIfNull(boundHostAddress); - ThrowHelper.ThrowIfNull(hostAddress); + ArgumentNullException.ThrowIfNull(boundHostAddress); + ArgumentNullException.ThrowIfNull(hostAddress); boundPort.ValidatePort(); port.ValidatePort(); @@ -227,7 +227,7 @@ protected override void StopPort(TimeSpan timeout) /// The current instance is disposed. protected override void CheckDisposed() { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); } private void Session_ChannelOpening(object sender, MessageEventArgs e) diff --git a/src/Renci.SshNet/MessageEventArgs`1.cs b/src/Renci.SshNet/MessageEventArgs`1.cs index c54afb3dc..9037239b2 100644 --- a/src/Renci.SshNet/MessageEventArgs`1.cs +++ b/src/Renci.SshNet/MessageEventArgs`1.cs @@ -1,7 +1,5 @@ using System; -using Renci.SshNet.Common; - namespace Renci.SshNet { /// @@ -22,7 +20,7 @@ public class MessageEventArgs : EventArgs /// is . public MessageEventArgs(T message) { - ThrowHelper.ThrowIfNull(message); + ArgumentNullException.ThrowIfNull(message); Message = message; } diff --git a/src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs b/src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs index 8416eb687..cc5f0f55f 100644 --- a/src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs +++ b/src/Renci.SshNet/Messages/Connection/ChannelDataMessage.cs @@ -1,4 +1,4 @@ -using Renci.SshNet.Common; +using System; namespace Renci.SshNet.Messages.Connection { @@ -89,7 +89,7 @@ public ChannelDataMessage() public ChannelDataMessage(uint localChannelNumber, byte[] data) : base(localChannelNumber) { - ThrowHelper.ThrowIfNull(data); + ArgumentNullException.ThrowIfNull(data); Data = data; Offset = 0; @@ -106,7 +106,7 @@ public ChannelDataMessage(uint localChannelNumber, byte[] data) public ChannelDataMessage(uint localChannelNumber, byte[] data, int offset, int size) : base(localChannelNumber) { - ThrowHelper.ThrowIfNull(data); + ArgumentNullException.ThrowIfNull(data); Data = data; Offset = offset; diff --git a/src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs b/src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs index bd5c52bfb..502c43300 100644 --- a/src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs +++ b/src/Renci.SshNet/Messages/Connection/ChannelOpen/ChannelOpenMessage.cs @@ -1,8 +1,6 @@ using System; using System.Globalization; -using Renci.SshNet.Common; - namespace Renci.SshNet.Messages.Connection { /// @@ -106,7 +104,7 @@ public ChannelOpenMessage() /// is . public ChannelOpenMessage(uint channelNumber, uint initialWindowSize, uint maximumPacketSize, ChannelOpenInfo info) { - ThrowHelper.ThrowIfNull(info); + ArgumentNullException.ThrowIfNull(info); ChannelType = Ascii.GetBytes(info.ChannelType); LocalChannelNumber = channelNumber; diff --git a/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExecRequestInfo.cs b/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExecRequestInfo.cs index 4d92d02d3..9337d77f4 100644 --- a/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExecRequestInfo.cs +++ b/src/Renci.SshNet/Messages/Connection/ChannelRequest/ExecRequestInfo.cs @@ -1,8 +1,6 @@ using System; using System.Text; -using Renci.SshNet.Common; - namespace Renci.SshNet.Messages.Connection { /// @@ -81,8 +79,8 @@ public ExecRequestInfo() public ExecRequestInfo(string command, Encoding encoding) : this() { - ThrowHelper.ThrowIfNull(command); - ThrowHelper.ThrowIfNull(encoding); + ArgumentNullException.ThrowIfNull(command); + ArgumentNullException.ThrowIfNull(encoding); _command = encoding.GetBytes(command); Encoding = encoding; diff --git a/src/Renci.SshNet/Messages/Transport/IgnoreMessage.cs b/src/Renci.SshNet/Messages/Transport/IgnoreMessage.cs index 25ebd43b2..ce9004580 100644 --- a/src/Renci.SshNet/Messages/Transport/IgnoreMessage.cs +++ b/src/Renci.SshNet/Messages/Transport/IgnoreMessage.cs @@ -1,7 +1,5 @@ using System; -using Renci.SshNet.Common; - namespace Renci.SshNet.Messages.Transport { /// @@ -47,7 +45,7 @@ public IgnoreMessage() /// The data. public IgnoreMessage(byte[] data) { - ThrowHelper.ThrowIfNull(data); + ArgumentNullException.ThrowIfNull(data); Data = data; } diff --git a/src/Renci.SshNet/NoneAuthenticationMethod.cs b/src/Renci.SshNet/NoneAuthenticationMethod.cs index 093660ccf..95e9a183f 100644 --- a/src/Renci.SshNet/NoneAuthenticationMethod.cs +++ b/src/Renci.SshNet/NoneAuthenticationMethod.cs @@ -1,7 +1,6 @@ using System; using System.Threading; -using Renci.SshNet.Common; using Renci.SshNet.Messages; using Renci.SshNet.Messages.Authentication; @@ -44,7 +43,7 @@ public NoneAuthenticationMethod(string username) /// is . public override AuthenticationResult Authenticate(Session session) { - ThrowHelper.ThrowIfNull(session); + ArgumentNullException.ThrowIfNull(session); session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; diff --git a/src/Renci.SshNet/OrderedDictionary.netstandard.cs b/src/Renci.SshNet/OrderedDictionary.netstandard.cs index a69b3200d..365920aec 100644 --- a/src/Renci.SshNet/OrderedDictionary.netstandard.cs +++ b/src/Renci.SshNet/OrderedDictionary.netstandard.cs @@ -9,7 +9,9 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; +#if !NET using Renci.SshNet.Common; +#endif namespace Renci.SshNet { @@ -486,8 +488,8 @@ public void Clear() public virtual void CopyTo(T[] array, int arrayIndex) { - ThrowHelper.ThrowIfNull(array); - ThrowHelper.ThrowIfNegative(arrayIndex); + ArgumentNullException.ThrowIfNull(array); + ArgumentOutOfRangeException.ThrowIfNegative(arrayIndex); if (array.Length - arrayIndex < Count) { diff --git a/src/Renci.SshNet/PasswordAuthenticationMethod.cs b/src/Renci.SshNet/PasswordAuthenticationMethod.cs index 315eb21dd..9abcaf298 100644 --- a/src/Renci.SshNet/PasswordAuthenticationMethod.cs +++ b/src/Renci.SshNet/PasswordAuthenticationMethod.cs @@ -69,7 +69,7 @@ public PasswordAuthenticationMethod(string username, string password) public PasswordAuthenticationMethod(string username, byte[] password) : base(username) { - ThrowHelper.ThrowIfNull(password); + ArgumentNullException.ThrowIfNull(password); _password = password; _requestMessage = new RequestMessagePassword(ServiceName.Connection, Username, _password); @@ -85,7 +85,7 @@ public PasswordAuthenticationMethod(string username, byte[] password) /// is . public override AuthenticationResult Authenticate(Session session) { - ThrowHelper.ThrowIfNull(session); + ArgumentNullException.ThrowIfNull(session); _session = session; diff --git a/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs b/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs index 85554adad..cd55829e8 100644 --- a/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs +++ b/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs @@ -42,7 +42,7 @@ public override string Name public PrivateKeyAuthenticationMethod(string username, params IPrivateKeySource[] keyFiles) : base(username) { - ThrowHelper.ThrowIfNull(keyFiles); + ArgumentNullException.ThrowIfNull(keyFiles); KeyFiles = new Collection(keyFiles); } diff --git a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs index 5e5b63118..34c46c90c 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs @@ -72,11 +72,11 @@ public Key Parse() switch (_version) { case "3": - ThrowHelper.ThrowIfNullOrEmpty(_argon2Type); - ThrowHelper.ThrowIfNullOrEmpty(_argon2Iterations); - ThrowHelper.ThrowIfNullOrEmpty(_argon2Memory); - ThrowHelper.ThrowIfNullOrEmpty(_argon2Parallelism); - ThrowHelper.ThrowIfNullOrEmpty(_argon2Salt); + ArgumentException.ThrowIfNullOrEmpty(_argon2Type); + ArgumentException.ThrowIfNullOrEmpty(_argon2Iterations); + ArgumentException.ThrowIfNullOrEmpty(_argon2Memory); + ArgumentException.ThrowIfNullOrEmpty(_argon2Parallelism); + ArgumentException.ThrowIfNullOrEmpty(_argon2Salt); var keyData = Argon2( _argon2Type, diff --git a/src/Renci.SshNet/PrivateKeyFile.cs b/src/Renci.SshNet/PrivateKeyFile.cs index a7339a913..24058cd73 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -172,7 +172,7 @@ public Key Key /// The key. public PrivateKeyFile(Key key) { - ThrowHelper.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(key); _key = key; _hostAlgorithms.Add(new KeyHostAlgorithm(key.ToString(), key)); @@ -223,7 +223,7 @@ public PrivateKeyFile(string fileName, string? passPhrase) /// is . public PrivateKeyFile(string fileName, string? passPhrase, string? certificateFileName) { - ThrowHelper.ThrowIfNull(fileName); + ArgumentNullException.ThrowIfNull(fileName); using (var keyFile = File.OpenRead(fileName)) { @@ -263,7 +263,7 @@ public PrivateKeyFile(Stream privateKey, string? passPhrase) /// A certificate which certifies the private key. public PrivateKeyFile(Stream privateKey, string? passPhrase, Stream? certificate) { - ThrowHelper.ThrowIfNull(privateKey); + ArgumentNullException.ThrowIfNull(privateKey); Open(privateKey, passPhrase); diff --git a/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs b/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs index b167e0119..3a5f16da1 100644 --- a/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs +++ b/src/Renci.SshNet/RemotePathDoubleQuoteTransformation.cs @@ -1,8 +1,6 @@ using System; using System.Text; -using Renci.SshNet.Common; - namespace Renci.SshNet { /// @@ -52,7 +50,7 @@ internal sealed class RemotePathDoubleQuoteTransformation : IRemotePathTransform /// public string Transform(string path) { - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); var transformed = new StringBuilder(path.Length); diff --git a/src/Renci.SshNet/RemotePathNoneTransformation.cs b/src/Renci.SshNet/RemotePathNoneTransformation.cs index 08cae8cc6..c0b394888 100644 --- a/src/Renci.SshNet/RemotePathNoneTransformation.cs +++ b/src/Renci.SshNet/RemotePathNoneTransformation.cs @@ -1,7 +1,5 @@ using System; -using Renci.SshNet.Common; - namespace Renci.SshNet { /// @@ -23,7 +21,7 @@ internal sealed class RemotePathNoneTransformation : IRemotePathTransformation /// public string Transform(string path) { - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); return path; } diff --git a/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs b/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs index d019547bf..578ec4dcb 100644 --- a/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs +++ b/src/Renci.SshNet/RemotePathShellQuoteTransformation.cs @@ -1,8 +1,6 @@ using System; using System.Text; -using Renci.SshNet.Common; - namespace Renci.SshNet { /// @@ -82,7 +80,7 @@ internal sealed class RemotePathShellQuoteTransformation : IRemotePathTransforma /// public string Transform(string path) { - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); // result is at least value and (likely) leading/trailing single-quotes var sb = new StringBuilder(path.Length + 2); diff --git a/src/Renci.SshNet/ScpClient.cs b/src/Renci.SshNet/ScpClient.cs index 18fc97591..35ce5f5c8 100644 --- a/src/Renci.SshNet/ScpClient.cs +++ b/src/Renci.SshNet/ScpClient.cs @@ -116,7 +116,7 @@ public IRemotePathTransformation RemotePathTransformation } set { - ThrowHelper.ThrowIfNull(value); + ArgumentNullException.ThrowIfNull(value); _remotePathTransformation = value; } @@ -288,7 +288,7 @@ public void Upload(Stream source, string path) /// Client is not connected. public void Upload(FileInfo fileInfo, string path) { - ThrowHelper.ThrowIfNull(fileInfo); + ArgumentNullException.ThrowIfNull(fileInfo); if (Session is null) { @@ -335,8 +335,8 @@ public void Upload(FileInfo fileInfo, string path) /// Client is not connected. public void Upload(DirectoryInfo directoryInfo, string path) { - ThrowHelper.ThrowIfNull(directoryInfo); - ThrowHelper.ThrowIfNullOrEmpty(path); + ArgumentNullException.ThrowIfNull(directoryInfo); + ArgumentException.ThrowIfNullOrEmpty(path); if (Session is null) { @@ -378,8 +378,8 @@ public void Upload(DirectoryInfo directoryInfo, string path) /// Client is not connected. public void Download(string filename, FileInfo fileInfo) { - ThrowHelper.ThrowIfNullOrEmpty(filename); - ThrowHelper.ThrowIfNull(fileInfo); + ArgumentException.ThrowIfNullOrEmpty(filename); + ArgumentNullException.ThrowIfNull(fileInfo); if (Session is null) { @@ -418,8 +418,8 @@ public void Download(string filename, FileInfo fileInfo) /// Client is not connected. public void Download(string directoryName, DirectoryInfo directoryInfo) { - ThrowHelper.ThrowIfNullOrEmpty(directoryName); - ThrowHelper.ThrowIfNull(directoryInfo); + ArgumentException.ThrowIfNullOrEmpty(directoryName); + ArgumentNullException.ThrowIfNull(directoryInfo); if (Session is null) { @@ -458,8 +458,8 @@ public void Download(string directoryName, DirectoryInfo directoryInfo) /// Client is not connected. public void Download(string filename, Stream destination) { - ThrowHelper.ThrowIfNullOrWhiteSpace(filename); - ThrowHelper.ThrowIfNull(destination); + ArgumentException.ThrowIfNullOrWhiteSpace(filename); + ArgumentNullException.ThrowIfNull(destination); if (Session is null) { diff --git a/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.BclImpl.cs b/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.BclImpl.cs index 76e43e949..a4dd353ce 100644 --- a/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.BclImpl.cs +++ b/src/Renci.SshNet/Security/Cryptography/Ciphers/AesCipher.BclImpl.cs @@ -25,7 +25,7 @@ public BclImpl( if (cipherMode != System.Security.Cryptography.CipherMode.ECB) { - ThrowHelper.ThrowIfNull(iv); + ArgumentNullException.ThrowIfNull(iv); aes.IV = iv.Take(16); } diff --git a/src/Renci.SshNet/Security/Cryptography/ED25519DigitalSignature.cs b/src/Renci.SshNet/Security/Cryptography/ED25519DigitalSignature.cs index d828a7c88..cd74d4c15 100644 --- a/src/Renci.SshNet/Security/Cryptography/ED25519DigitalSignature.cs +++ b/src/Renci.SshNet/Security/Cryptography/ED25519DigitalSignature.cs @@ -21,7 +21,7 @@ public class ED25519DigitalSignature : DigitalSignature, IDisposable /// is . public ED25519DigitalSignature(ED25519Key key) { - ThrowHelper.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(key); _key = key; } diff --git a/src/Renci.SshNet/Security/Cryptography/ED25519Key.cs b/src/Renci.SshNet/Security/Cryptography/ED25519Key.cs index af5e928a3..1cc43294f 100644 --- a/src/Renci.SshNet/Security/Cryptography/ED25519Key.cs +++ b/src/Renci.SshNet/Security/Cryptography/ED25519Key.cs @@ -78,7 +78,7 @@ protected internal override DigitalSignature DigitalSignature /// The encoded public key data. public ED25519Key(SshKeyData publicKeyData) { - ThrowHelper.ThrowIfNull(publicKeyData); + ArgumentNullException.ThrowIfNull(publicKeyData); if (publicKeyData.Name != "ssh-ed25519" || publicKeyData.Keys.Length != 1) { diff --git a/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs b/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs index 3070c2003..5f15fe0db 100644 --- a/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs +++ b/src/Renci.SshNet/Security/Cryptography/EcdsaDigitalSignature.cs @@ -18,7 +18,7 @@ public class EcdsaDigitalSignature : DigitalSignature, IDisposable /// is . public EcdsaDigitalSignature(EcdsaKey key) { - ThrowHelper.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(key); _key = key; } diff --git a/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs b/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs index f74500d85..aaf9123b8 100644 --- a/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs +++ b/src/Renci.SshNet/Security/Cryptography/EcdsaKey.cs @@ -188,7 +188,7 @@ public ECDsa? Ecdsa /// The encoded public key data. public EcdsaKey(SshKeyData publicKeyData) { - ThrowHelper.ThrowIfNull(publicKeyData); + ArgumentNullException.ThrowIfNull(publicKeyData); if (!publicKeyData.Name.StartsWith("ecdsa-sha2-", StringComparison.Ordinal) || publicKeyData.Keys.Length != 2) { diff --git a/src/Renci.SshNet/Security/Cryptography/RsaKey.cs b/src/Renci.SshNet/Security/Cryptography/RsaKey.cs index 9dff0ece5..78669a99e 100644 --- a/src/Renci.SshNet/Security/Cryptography/RsaKey.cs +++ b/src/Renci.SshNet/Security/Cryptography/RsaKey.cs @@ -139,7 +139,7 @@ public override BigInteger[] Public /// The encoded public key data. public RsaKey(SshKeyData publicKeyData) { - ThrowHelper.ThrowIfNull(publicKeyData); + ArgumentNullException.ThrowIfNull(publicKeyData); if (publicKeyData.Name != "ssh-rsa" || publicKeyData.Keys.Length != 2) { @@ -159,7 +159,7 @@ public RsaKey(SshKeyData publicKeyData) /// DER encoded private key data. public RsaKey(byte[] privateKeyData) { - ThrowHelper.ThrowIfNull(privateKeyData); + ArgumentNullException.ThrowIfNull(privateKeyData); var keyReader = new AsnReader(privateKeyData, AsnEncodingRules.DER); var sequenceReader = keyReader.ReadSequence(); diff --git a/src/Renci.SshNet/Security/Cryptography/SymmetricCipher.cs b/src/Renci.SshNet/Security/Cryptography/SymmetricCipher.cs index a65ea3d13..87674a9f8 100644 --- a/src/Renci.SshNet/Security/Cryptography/SymmetricCipher.cs +++ b/src/Renci.SshNet/Security/Cryptography/SymmetricCipher.cs @@ -1,7 +1,5 @@ using System; -using Renci.SshNet.Common; - namespace Renci.SshNet.Security.Cryptography { /// @@ -21,7 +19,7 @@ public abstract class SymmetricCipher : Cipher /// is . protected SymmetricCipher(byte[] key) { - ThrowHelper.ThrowIfNull(key); + ArgumentNullException.ThrowIfNull(key); Key = key; } diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs index c9e31e9ac..ad8b77f33 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellman.cs @@ -7,7 +7,6 @@ using Org.BouncyCastle.Crypto.Parameters; using Renci.SshNet.Abstractions; -using Renci.SshNet.Common; using Renci.SshNet.Messages.Transport; namespace Renci.SshNet.Security @@ -53,9 +52,9 @@ public KeyExchangeDiffieHellman( DHParameters parameters, HashAlgorithmName hashAlgorithm) { - ThrowHelper.ThrowIfNull(name); - ThrowHelper.ThrowIfNull(parameters); - ThrowHelper.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + ArgumentNullException.ThrowIfNull(name); + ArgumentNullException.ThrowIfNull(parameters); + ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); Name = name; _dhParameters = parameters; diff --git a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchange.cs b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchange.cs index 0a9d46579..d755b5642 100644 --- a/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchange.cs +++ b/src/Renci.SshNet/Security/KeyExchangeDiffieHellmanGroupExchange.cs @@ -7,7 +7,6 @@ using Org.BouncyCastle.Crypto.Parameters; using Renci.SshNet.Abstractions; -using Renci.SshNet.Common; using Renci.SshNet.Messages.Transport; namespace Renci.SshNet.Security @@ -83,8 +82,8 @@ public KeyExchangeDiffieHellmanGroupExchange( uint preferredGroupSize, uint maximumGroupSize) { - ThrowHelper.ThrowIfNull(name); - ThrowHelper.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); + ArgumentNullException.ThrowIfNull(name); + ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); if (preferredGroupSize < minimumGroupSize || preferredGroupSize > maximumGroupSize) { diff --git a/src/Renci.SshNet/ServiceFactory.cs b/src/Renci.SshNet/ServiceFactory.cs index ab3ae16cb..8e8d721c1 100644 --- a/src/Renci.SshNet/ServiceFactory.cs +++ b/src/Renci.SshNet/ServiceFactory.cs @@ -87,8 +87,8 @@ public PipeStream CreatePipeStream() /// public IKeyExchange CreateKeyExchange(IDictionary> clientAlgorithms, string[] serverAlgorithms) { - ThrowHelper.ThrowIfNull(clientAlgorithms); - ThrowHelper.ThrowIfNull(serverAlgorithms); + ArgumentNullException.ThrowIfNull(clientAlgorithms); + ArgumentNullException.ThrowIfNull(serverAlgorithms); // find an algorithm that is supported by both client and server var keyExchangeAlgorithmFactory = (from c in clientAlgorithms @@ -215,8 +215,8 @@ public IRemotePathTransformation CreateRemotePathDoubleQuoteTransformation() /// The value of is not supported. public IConnector CreateConnector(IConnectionInfo connectionInfo, ISocketFactory socketFactory) { - ThrowHelper.ThrowIfNull(connectionInfo); - ThrowHelper.ThrowIfNull(socketFactory); + ArgumentNullException.ThrowIfNull(connectionInfo); + ArgumentNullException.ThrowIfNull(socketFactory); var loggerFactory = connectionInfo.LoggerFactory ?? SshNetLoggingConfiguration.LoggerFactory; diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index e94ebeb27..06f94a0bf 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -557,9 +557,9 @@ public string ClientVersion /// is . internal Session(ConnectionInfo connectionInfo, IServiceFactory serviceFactory, ISocketFactory socketFactory) { - ThrowHelper.ThrowIfNull(connectionInfo); - ThrowHelper.ThrowIfNull(serviceFactory); - ThrowHelper.ThrowIfNull(socketFactory); + ArgumentNullException.ThrowIfNull(connectionInfo); + ArgumentNullException.ThrowIfNull(serviceFactory); + ArgumentNullException.ThrowIfNull(socketFactory); ConnectionInfo = connectionInfo; SessionLoggerFactory = connectionInfo.LoggerFactory ?? SshNetLoggingConfiguration.LoggerFactory; @@ -937,7 +937,7 @@ WaitResult ISession.TryWait(WaitHandle waitHandle, TimeSpan timeout, out Excepti /// private WaitResult TryWait(WaitHandle waitHandle, TimeSpan timeout, out Exception exception) { - ThrowHelper.ThrowIfNull(waitHandle); + ArgumentNullException.ThrowIfNull(waitHandle); var waitHandles = new[] { @@ -999,7 +999,7 @@ internal void WaitOnHandle(WaitHandle waitHandle) /// A socket error was signaled while receiving messages from the server. internal void WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout) { - ThrowHelper.ThrowIfNull(waitHandle); + ArgumentNullException.ThrowIfNull(waitHandle); var waitHandles = new[] { diff --git a/src/Renci.SshNet/Sftp/Requests/SftpRealPathRequest.cs b/src/Renci.SshNet/Sftp/Requests/SftpRealPathRequest.cs index c34e907e5..dc591baa4 100644 --- a/src/Renci.SshNet/Sftp/Requests/SftpRealPathRequest.cs +++ b/src/Renci.SshNet/Sftp/Requests/SftpRealPathRequest.cs @@ -1,7 +1,6 @@ using System; using System.Text; -using Renci.SshNet.Common; using Renci.SshNet.Sftp.Responses; namespace Renci.SshNet.Sftp.Requests @@ -44,7 +43,7 @@ protected override int BufferCapacity public SftpRealPathRequest(uint protocolVersion, uint requestId, string path, Encoding encoding, Action nameAction, Action statusAction) : base(protocolVersion, requestId, statusAction) { - ThrowHelper.ThrowIfNull(nameAction); + ArgumentNullException.ThrowIfNull(nameAction); Encoding = encoding; Path = path; diff --git a/src/Renci.SshNet/Sftp/SftpFile.cs b/src/Renci.SshNet/Sftp/SftpFile.cs index 44694b5be..31cb00023 100644 --- a/src/Renci.SshNet/Sftp/SftpFile.cs +++ b/src/Renci.SshNet/Sftp/SftpFile.cs @@ -33,8 +33,8 @@ internal SftpFile(ISftpSession sftpSession, string fullName, SftpFileAttributes throw new SshConnectionException("Client not connected."); } - ThrowHelper.ThrowIfNull(attributes); - ThrowHelper.ThrowIfNull(fullName); + ArgumentNullException.ThrowIfNull(attributes); + ArgumentNullException.ThrowIfNull(fullName); _sftpSession = sftpSession; Attributes = attributes; @@ -485,7 +485,7 @@ public Task DeleteAsync(CancellationToken cancellationToken = default) /// is . public void MoveTo(string destFileName) { - ThrowHelper.ThrowIfNull(destFileName); + ArgumentNullException.ThrowIfNull(destFileName); _sftpSession.RequestRename(FullName, destFileName); diff --git a/src/Renci.SshNet/Sftp/SftpFileReader.cs b/src/Renci.SshNet/Sftp/SftpFileReader.cs index 1f3fe396e..b36e8c992 100644 --- a/src/Renci.SshNet/Sftp/SftpFileReader.cs +++ b/src/Renci.SshNet/Sftp/SftpFileReader.cs @@ -78,7 +78,7 @@ public SftpFileReader(byte[] handle, ISftpSession sftpSession, uint chunkSize, i public byte[] Read() { - ThrowHelper.ThrowObjectDisposedIf(_disposingOrDisposed, this); + ObjectDisposedException.ThrowIf(_disposingOrDisposed, this); if (_exception is not null) { diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index 6ac7b4868..5495e6f55 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -224,7 +224,7 @@ private static async Task Open(ISftpSession session, string path { Debug.Assert(isAsync || cancellationToken == default); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (bufferSize <= 0) { @@ -828,7 +828,7 @@ public override long Seek(long offset, SeekOrigin origin) /// public override void SetLength(long value) { - ThrowHelper.ThrowIfNegative(value); + ArgumentOutOfRangeException.ThrowIfNegative(value); // Lock down the file stream while we do this. lock (_lock) @@ -1179,7 +1179,7 @@ private void SetupWrite() private void CheckSessionIsOpen() { - ThrowHelper.ThrowObjectDisposedIf(_session is null, this); + ObjectDisposedException.ThrowIf(_session is null, this); if (!_session.IsOpen) { diff --git a/src/Renci.SshNet/Sftp/SftpSession.cs b/src/Renci.SshNet/Sftp/SftpSession.cs index 1de63eaf2..9a6c401b5 100644 --- a/src/Renci.SshNet/Sftp/SftpSession.cs +++ b/src/Renci.SshNet/Sftp/SftpSession.cs @@ -542,7 +542,7 @@ public SftpOpenAsyncResult BeginOpen(string path, Flags flags, AsyncCallback cal /// is . public byte[] EndOpen(SftpOpenAsyncResult asyncResult) { - ThrowHelper.ThrowIfNull(asyncResult); + ArgumentNullException.ThrowIfNull(asyncResult); if (asyncResult.EndInvokeCalled) { @@ -658,7 +658,7 @@ public SftpCloseAsyncResult BeginClose(byte[] handle, AsyncCallback callback, ob /// is . public void EndClose(SftpCloseAsyncResult asyncResult) { - ThrowHelper.ThrowIfNull(asyncResult); + ArgumentNullException.ThrowIfNull(asyncResult); if (asyncResult.EndInvokeCalled) { @@ -733,7 +733,7 @@ public SftpReadAsyncResult BeginRead(byte[] handle, ulong offset, uint length, A /// is . public byte[] EndRead(SftpReadAsyncResult asyncResult) { - ThrowHelper.ThrowIfNull(asyncResult); + ArgumentNullException.ThrowIfNull(asyncResult); if (asyncResult.EndInvokeCalled) { @@ -1056,7 +1056,7 @@ public SFtpStatAsyncResult BeginLStat(string path, AsyncCallback callback, objec /// is . public SftpFileAttributes EndLStat(SFtpStatAsyncResult asyncResult) { - ThrowHelper.ThrowIfNull(asyncResult); + ArgumentNullException.ThrowIfNull(asyncResult); if (asyncResult.EndInvokeCalled) { @@ -1665,7 +1665,7 @@ public SftpRealPathAsyncResult BeginRealPath(string path, AsyncCallback callback /// is . public string EndRealPath(SftpRealPathAsyncResult asyncResult) { - ThrowHelper.ThrowIfNull(asyncResult); + ArgumentNullException.ThrowIfNull(asyncResult); if (asyncResult.EndInvokeCalled) { @@ -1762,7 +1762,7 @@ public SFtpStatAsyncResult BeginStat(string path, AsyncCallback callback, object /// is . public SftpFileAttributes EndStat(SFtpStatAsyncResult asyncResult) { - ThrowHelper.ThrowIfNull(asyncResult); + ArgumentNullException.ThrowIfNull(asyncResult); if (asyncResult.EndInvokeCalled) { diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index df7956718..ad00a2f72 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -298,7 +298,7 @@ internal SftpClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, ISer public void ChangeDirectory(string path) { CheckDisposed(); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -323,7 +323,7 @@ public void ChangeDirectory(string path) public Task ChangeDirectoryAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -364,7 +364,7 @@ public void ChangePermissions(string path, short mode) public void CreateDirectory(string path) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -390,7 +390,7 @@ public void CreateDirectory(string path) public async Task CreateDirectoryAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -415,7 +415,7 @@ public async Task CreateDirectoryAsync(string path, CancellationToken cancellati public void DeleteDirectory(string path) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -431,7 +431,7 @@ public void DeleteDirectory(string path) public async Task DeleteDirectoryAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -458,7 +458,7 @@ public async Task DeleteDirectoryAsync(string path, CancellationToken cancellati public void DeleteFile(string path) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -474,7 +474,7 @@ public void DeleteFile(string path) public async Task DeleteFileAsync(string path, CancellationToken cancellationToken) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -516,8 +516,8 @@ public void RenameFile(string oldPath, string newPath) public void RenameFile(string oldPath, string newPath, bool isPosix) { CheckDisposed(); - ThrowHelper.ThrowIfNull(oldPath); - ThrowHelper.ThrowIfNull(newPath); + ArgumentNullException.ThrowIfNull(oldPath); + ArgumentNullException.ThrowIfNull(newPath); if (_sftpSession is null) { @@ -553,8 +553,8 @@ public void RenameFile(string oldPath, string newPath, bool isPosix) public async Task RenameFileAsync(string oldPath, string newPath, CancellationToken cancellationToken) { CheckDisposed(); - ThrowHelper.ThrowIfNull(oldPath); - ThrowHelper.ThrowIfNull(newPath); + ArgumentNullException.ThrowIfNull(oldPath); + ArgumentNullException.ThrowIfNull(newPath); if (_sftpSession is null) { @@ -581,8 +581,8 @@ public async Task RenameFileAsync(string oldPath, string newPath, CancellationTo public void SymbolicLink(string path, string linkPath) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); - ThrowHelper.ThrowIfNullOrWhiteSpace(linkPath); + ArgumentException.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(linkPath); if (_sftpSession is null) { @@ -633,7 +633,7 @@ public IEnumerable ListDirectory(string path, Action? listCallba public async IAsyncEnumerable ListDirectoryAsync(string path, [EnumeratorCancellation] CancellationToken cancellationToken) { CheckDisposed(); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -738,7 +738,7 @@ public IEnumerable EndListDirectory(IAsyncResult asyncResult) public ISftpFile Get(string path) { CheckDisposed(); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -768,7 +768,7 @@ public ISftpFile Get(string path) public async Task GetAsync(string path, CancellationToken cancellationToken) { CheckDisposed(); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -799,7 +799,7 @@ public async Task GetAsync(string path, CancellationToken cancellatio public bool Exists(string path) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -855,7 +855,7 @@ public bool Exists(string path) public async Task ExistsAsync(string path, CancellationToken cancellationToken = default) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -977,8 +977,8 @@ public IAsyncResult BeginDownloadFile(string path, Stream output, AsyncCallback? public IAsyncResult BeginDownloadFile(string path, Stream output, AsyncCallback? asyncCallback, object? state, Action? downloadCallback = null) { CheckDisposed(); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); - ThrowHelper.ThrowIfNull(output); + ArgumentException.ThrowIfNullOrWhiteSpace(path); + ArgumentNullException.ThrowIfNull(output); var asyncResult = new SftpDownloadAsyncResult(asyncCallback, state); @@ -1028,8 +1028,8 @@ public void UploadFile(Stream input, string path, Action? uploadCallback /// public void UploadFile(Stream input, string path, bool canOverride, Action? uploadCallback = null) { - ThrowHelper.ThrowIfNull(input); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentNullException.ThrowIfNull(input); + ArgumentException.ThrowIfNullOrWhiteSpace(path); CheckDisposed(); var flags = Flags.Write | Flags.Truncate; @@ -1056,8 +1056,8 @@ public void UploadFile(Stream input, string path, bool canOverride, Action public Task UploadFileAsync(Stream input, string path, CancellationToken cancellationToken = default) { - ThrowHelper.ThrowIfNull(input); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentNullException.ThrowIfNull(input); + ArgumentException.ThrowIfNullOrWhiteSpace(path); CheckDisposed(); return InternalUploadFile( @@ -1182,8 +1182,8 @@ public IAsyncResult BeginUploadFile(Stream input, string path, AsyncCallback? as /// public IAsyncResult BeginUploadFile(Stream input, string path, bool canOverride, AsyncCallback? asyncCallback, object? state, Action? uploadCallback = null) { - ThrowHelper.ThrowIfNull(input); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentNullException.ThrowIfNull(input); + ArgumentException.ThrowIfNullOrWhiteSpace(path); CheckDisposed(); var flags = Flags.Write | Flags.Truncate; @@ -1258,7 +1258,7 @@ public void EndUploadFile(IAsyncResult asyncResult) public SftpFileSystemInformation GetStatus(string path) { CheckDisposed(); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -1285,7 +1285,7 @@ public SftpFileSystemInformation GetStatus(string path) public async Task GetStatusAsync(string path, CancellationToken cancellationToken) { CheckDisposed(); - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -1315,7 +1315,7 @@ public async Task GetStatusAsync(string path, Cancell public void AppendAllLines(string path, IEnumerable contents) { CheckDisposed(); - ThrowHelper.ThrowIfNull(contents); + ArgumentNullException.ThrowIfNull(contents); using (var stream = AppendText(path)) { @@ -1339,7 +1339,7 @@ public void AppendAllLines(string path, IEnumerable contents) public void AppendAllLines(string path, IEnumerable contents, Encoding encoding) { CheckDisposed(); - ThrowHelper.ThrowIfNull(contents); + ArgumentNullException.ThrowIfNull(contents); using (var stream = AppendText(path, encoding)) { @@ -1422,7 +1422,7 @@ public StreamWriter AppendText(string path) public StreamWriter AppendText(string path, Encoding encoding) { CheckDisposed(); - ThrowHelper.ThrowIfNull(encoding); + ArgumentNullException.ThrowIfNull(encoding); return new StreamWriter(Open(path, FileMode.Append, FileAccess.Write), encoding); } @@ -1795,7 +1795,7 @@ public IEnumerable ReadLines(string path) public IEnumerable ReadLines(string path, Encoding encoding) { // We allow this usage exception to throw eagerly... - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); // ... but other exceptions will throw lazily i.e. inside the state machine created // by yield. We could choose to open the file eagerly as well in order to throw @@ -1868,7 +1868,7 @@ public void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc) /// public void WriteAllBytes(string path, byte[] bytes) { - ThrowHelper.ThrowIfNull(bytes); + ArgumentNullException.ThrowIfNull(bytes); UploadFile(new MemoryStream(bytes), path); } @@ -2014,8 +2014,8 @@ public void SetAttributes(string path, SftpFileAttributes fileAttributes) /// If a problem occurs while copying the file. public IEnumerable SynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern) { - ThrowHelper.ThrowIfNull(sourcePath); - ThrowHelper.ThrowIfNullOrWhiteSpace(destinationPath); + ArgumentNullException.ThrowIfNull(sourcePath); + ArgumentException.ThrowIfNullOrWhiteSpace(destinationPath); return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult: null); } @@ -2036,9 +2036,9 @@ public IEnumerable SynchronizeDirectories(string sourcePath, string de /// If a problem occurs while copying the file. public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, AsyncCallback? asyncCallback, object? state) { - ThrowHelper.ThrowIfNull(sourcePath); - ThrowHelper.ThrowIfNullOrWhiteSpace(destinationPath); - ThrowHelper.ThrowIfNull(searchPattern); + ArgumentNullException.ThrowIfNull(sourcePath); + ArgumentException.ThrowIfNullOrWhiteSpace(destinationPath); + ArgumentNullException.ThrowIfNull(searchPattern); var asyncResult = new SftpSynchronizeDirectoriesAsyncResult(asyncCallback, state); @@ -2185,7 +2185,7 @@ private List InternalSynchronizeDirectories(string sourcePath, string /// Client not connected. private List InternalListDirectory(string path, SftpListDirectoryAsyncResult? asyncResult, Action? listCallback) { - ThrowHelper.ThrowIfNull(path); + ArgumentNullException.ThrowIfNull(path); if (_sftpSession is null) { @@ -2249,8 +2249,8 @@ private List InternalListDirectory(string path, SftpListDirectoryAsyn /// Client not connected. private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncResult? asyncResult, Action? downloadCallback) { - ThrowHelper.ThrowIfNull(output); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentNullException.ThrowIfNull(output); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { @@ -2297,8 +2297,8 @@ private void InternalDownloadFile(string path, Stream output, SftpDownloadAsyncR private async Task InternalDownloadFileAsync(string path, Stream output, CancellationToken cancellationToken) { - ThrowHelper.ThrowIfNull(output); - ThrowHelper.ThrowIfNullOrWhiteSpace(path); + ArgumentNullException.ThrowIfNull(output); + ArgumentException.ThrowIfNullOrWhiteSpace(path); if (_sftpSession is null) { diff --git a/src/Renci.SshNet/ShellStream.cs b/src/Renci.SshNet/ShellStream.cs index e3ef7ff07..958af4da2 100644 --- a/src/Renci.SshNet/ShellStream.cs +++ b/src/Renci.SshNet/ShellStream.cs @@ -215,7 +215,7 @@ public override bool CanWrite /// public override void Flush() { - ThrowHelper.ThrowObjectDisposedIf(_disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); if (_writeBuffer.ActiveLength > 0) { @@ -295,7 +295,7 @@ public override void SetLength(long value) /// The stream is closed. public void ChangeWindowSize(uint columns, uint rows, uint width, uint height) { - ThrowHelper.ThrowObjectDisposedIf(_disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); _channel.SendWindowChangeRequest(columns, rows, width, height); } @@ -864,7 +864,7 @@ public override void Write(ReadOnlySpan buffer) private void Write(ReadOnlySpan buffer) #endif { - ThrowHelper.ThrowObjectDisposedIf(_disposed, this); + ObjectDisposedException.ThrowIf(_disposed, this); while (!buffer.IsEmpty) { diff --git a/src/Renci.SshNet/SshClient.cs b/src/Renci.SshNet/SshClient.cs index 05508462d..b174d508b 100644 --- a/src/Renci.SshNet/SshClient.cs +++ b/src/Renci.SshNet/SshClient.cs @@ -155,7 +155,7 @@ protected override void OnDisconnecting() /// public void AddForwardedPort(ForwardedPort port) { - ThrowHelper.ThrowIfNull(port); + ArgumentNullException.ThrowIfNull(port); EnsureSessionIsOpen(); @@ -166,7 +166,7 @@ public void AddForwardedPort(ForwardedPort port) /// public void RemoveForwardedPort(ForwardedPort port) { - ThrowHelper.ThrowIfNull(port); + ArgumentNullException.ThrowIfNull(port); // Stop port forwarding before removing it port.Stop(); diff --git a/src/Renci.SshNet/SshCommand.cs b/src/Renci.SshNet/SshCommand.cs index bd7ae139f..ce1042244 100644 --- a/src/Renci.SshNet/SshCommand.cs +++ b/src/Renci.SshNet/SshCommand.cs @@ -214,9 +214,9 @@ public string Error /// Either , is . internal SshCommand(ISession session, string commandText, Encoding encoding) { - ThrowHelper.ThrowIfNull(session); - ThrowHelper.ThrowIfNull(commandText); - ThrowHelper.ThrowIfNull(encoding); + ArgumentNullException.ThrowIfNull(session); + ArgumentNullException.ThrowIfNull(commandText); + ArgumentNullException.ThrowIfNull(encoding); _session = session; CommandText = commandText; @@ -244,7 +244,7 @@ internal SshCommand(ISession session, string commandText, Encoding encoding) #pragma warning disable CA1849 // Call async methods when in an async method; PipeStream.DisposeAsync would complete synchronously anyway. public Task ExecuteAsync(CancellationToken cancellationToken = default) { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); if (cancellationToken.IsCancellationRequested) { @@ -385,7 +385,7 @@ public IAsyncResult BeginExecute(AsyncCallback? callback, object? state) /// Operation has timed out. public IAsyncResult BeginExecute(string commandText, AsyncCallback? callback, object? state) { - ThrowHelper.ThrowIfNull(commandText); + ArgumentNullException.ThrowIfNull(commandText); CommandText = commandText; diff --git a/src/Renci.SshNet/SshMessageFactory.cs b/src/Renci.SshNet/SshMessageFactory.cs index 038d7c3ae..d598ff867 100644 --- a/src/Renci.SshNet/SshMessageFactory.cs +++ b/src/Renci.SshNet/SshMessageFactory.cs @@ -184,7 +184,7 @@ public void EnableActivatedMessages() public void EnableAndActivateMessage(string messageName) { - ThrowHelper.ThrowIfNull(messageName); + ArgumentNullException.ThrowIfNull(messageName); lock (_lock) { @@ -208,7 +208,7 @@ public void EnableAndActivateMessage(string messageName) public void DisableAndDeactivateMessage(string messageName) { - ThrowHelper.ThrowIfNull(messageName); + ArgumentNullException.ThrowIfNull(messageName); lock (_lock) { diff --git a/src/Renci.SshNet/SshNetLoggingConfiguration.cs b/src/Renci.SshNet/SshNetLoggingConfiguration.cs index fa8581b3b..6d68904a5 100644 --- a/src/Renci.SshNet/SshNetLoggingConfiguration.cs +++ b/src/Renci.SshNet/SshNetLoggingConfiguration.cs @@ -1,9 +1,9 @@ #nullable enable +using System; + using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -using Renci.SshNet.Common; - namespace Renci.SshNet { /// @@ -19,7 +19,7 @@ public static class SshNetLoggingConfiguration /// The logger factory. public static void InitializeLogging(ILoggerFactory loggerFactory) { - ThrowHelper.ThrowIfNull(loggerFactory); + ArgumentNullException.ThrowIfNull(loggerFactory); LoggerFactory = loggerFactory; } diff --git a/src/Renci.SshNet/SubsystemSession.cs b/src/Renci.SshNet/SubsystemSession.cs index a632f41e8..47e37161c 100644 --- a/src/Renci.SshNet/SubsystemSession.cs +++ b/src/Renci.SshNet/SubsystemSession.cs @@ -55,7 +55,7 @@ internal IChannelSession Channel { get { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); return _channel; } @@ -89,8 +89,8 @@ public ILoggerFactory SessionLoggerFactory /// or is . protected SubsystemSession(ISession session, string subsystemName, int operationTimeout) { - ThrowHelper.ThrowIfNull(session); - ThrowHelper.ThrowIfNull(subsystemName); + ArgumentNullException.ThrowIfNull(session); + ArgumentNullException.ThrowIfNull(subsystemName); _session = session; _subsystemName = subsystemName; @@ -106,7 +106,7 @@ protected SubsystemSession(ISession session, string subsystemName, int operation /// The channel session could not be opened, or the subsystem could not be executed. public void Connect() { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); if (IsOpen) { @@ -166,7 +166,7 @@ public void Disconnect() /// The data to be sent. public void SendData(byte[] data) { - ThrowHelper.ThrowObjectDisposedIf(_isDisposed, this); + ObjectDisposedException.ThrowIf(_isDisposed, this); EnsureSessionIsOpen(); _channel.SendData(data); diff --git a/test/Renci.SshNet.IntegrationTests/Common/Socks5Handler.cs b/test/Renci.SshNet.IntegrationTests/Common/Socks5Handler.cs index 1c2beda8f..d8b72cb33 100644 --- a/test/Renci.SshNet.IntegrationTests/Common/Socks5Handler.cs +++ b/test/Renci.SshNet.IntegrationTests/Common/Socks5Handler.cs @@ -22,7 +22,7 @@ public Socks5Handler(IPEndPoint proxyEndPoint, string userName, string password) public Socket Connect(IPEndPoint endPoint) { - ThrowHelper.ThrowIfNull(endPoint); + ArgumentNullException.ThrowIfNull(endPoint); var addressBytes = GetAddressBytes(endPoint); return Connect(addressBytes, endPoint.Port); @@ -30,7 +30,7 @@ public Socket Connect(IPEndPoint endPoint) public Socket Connect(string host, int port) { - ThrowHelper.ThrowIfNull(host); + ArgumentNullException.ThrowIfNull(host); if (host.Length > byte.MaxValue) { From 0770be48632dd6daa0db53ba5cd3ae10bde19045 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 18 Apr 2025 14:25:19 +0200 Subject: [PATCH 13/16] use extension members for CryptoAbstractions --- .../Abstractions/CryptoAbstraction.cs | 72 ------------------- .../Abstractions/MD5Extensions.cs | 19 +++++ .../RandomNumberGeneratorExtensions.cs | 22 ++++++ .../Abstractions/SHA1Extensions.cs | 18 +++++ .../Abstractions/SHA256Extensions.cs | 19 +++++ .../Abstractions/SHA384Extensions.cs | 19 +++++ .../Abstractions/SHA512Extensions.cs | 19 +++++ src/Renci.SshNet/Common/HostKeyEventArgs.cs | 6 +- src/Renci.SshNet/Messages/Message.cs | 6 +- .../Transport/KeyExchangeInitMessage.cs | 4 +- src/Renci.SshNet/PrivateKeyFile.PuTTY.cs | 5 +- src/Renci.SshNet/Security/Certificate.cs | 4 +- .../Security/KeyExchangeECCurve25519.cs | 6 +- .../Security/KeyExchangeECDH256.cs | 8 +-- .../Security/KeyExchangeECDH384.cs | 8 +-- .../Security/KeyExchangeECDH521.cs | 8 +-- .../KeyExchangeMLKem768X25519Sha256.cs | 5 +- .../KeyExchangeSNtruP761X25519Sha512.cs | 5 +- .../Classes/AbstractionsTest.cs | 7 +- .../Connection/ChannelDataMessageTest.cs | 6 +- ...tpFileReader_EndLStatThrowsSshException.cs | 4 +- ...izeIsAlmostSixTimesGreaterThanChunkSize.cs | 4 +- ...tpFileReader_FileSizeIsEqualToChunkSize.cs | 4 +- ...eIsExactlyFiveTimesGreaterThanChunkSize.cs | 4 +- ...pFileReader_FileSizeIsLessThanChunkSize.cs | 4 +- ...leMoreThanFiveTimesGreaterThanChunkSize.cs | 4 +- ...IsMoreThanMaxPendingReadsTimesChunkSize.cs | 4 +- ...est_CreateSftpFileReader_FileSizeIsZero.cs | 4 +- .../Classes/SessionTest_ConnectingBase.cs | 3 +- .../SftpSessionTest_Connected_RequestRead.cs | 6 +- ...tipleSftpMessagesInSingleSshDataMessage.cs | 6 +- ...essagesSplitOverMultipleSshDataMessages.cs | 6 +- ...eived_SingleSftpMessageInSshDataMessage.cs | 6 +- .../Classes/ShellStreamTest_ReadExpect.cs | 4 +- ...ferEmptyAndWriteLessBytesThanBufferSize.cs | 4 +- ...ferEmptyAndWriteMoreBytesThanBufferSize.cs | 4 +- ...yAndWriteNumberOfBytesEqualToBufferSize.cs | 4 +- ...fferFullAndWriteLessBytesThanBufferSize.cs | 6 +- ..._Write_WriteBufferFullAndWriteZeroBytes.cs | 4 +- ...tyAndWriteLessBytesThanBufferCanContain.cs | 6 +- ...tyAndWriteMoreBytesThanBufferCanContain.cs | 6 +- ...te_WriteBufferNotEmptyAndWriteZeroBytes.cs | 4 +- 42 files changed, 207 insertions(+), 160 deletions(-) create mode 100644 src/Renci.SshNet/Abstractions/MD5Extensions.cs create mode 100644 src/Renci.SshNet/Abstractions/RandomNumberGeneratorExtensions.cs create mode 100644 src/Renci.SshNet/Abstractions/SHA1Extensions.cs create mode 100644 src/Renci.SshNet/Abstractions/SHA256Extensions.cs create mode 100644 src/Renci.SshNet/Abstractions/SHA384Extensions.cs create mode 100644 src/Renci.SshNet/Abstractions/SHA512Extensions.cs diff --git a/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs b/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs index 0081e8860..70cec1e7b 100644 --- a/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs +++ b/src/Renci.SshNet/Abstractions/CryptoAbstraction.cs @@ -10,77 +10,5 @@ internal static class CryptoAbstraction private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create(); internal static readonly SecureRandom SecureRandom = new SecureRandom(new CryptoApiRandomGenerator(Randomizer)); - - /// - /// Generates a array of the specified length, and fills it with a - /// cryptographically strong random sequence of values. - /// - /// The length of the array generate. - public static byte[] GenerateRandom(int length) - { - var random = new byte[length]; - Randomizer.GetBytes(random); - return random; - } - - public static byte[] HashMD5(byte[] source) - { -#if NET - return MD5.HashData(source); -#else - using (var md5 = MD5.Create()) - { - return md5.ComputeHash(source); - } -#endif - } - - public static byte[] HashSHA1(byte[] source) - { -#if NET - return SHA1.HashData(source); -#else - using (var sha1 = SHA1.Create()) - { - return sha1.ComputeHash(source); - } -#endif - } - - public static byte[] HashSHA256(byte[] source) - { -#if NET - return SHA256.HashData(source); -#else - using (var sha256 = SHA256.Create()) - { - return sha256.ComputeHash(source); - } -#endif - } - - public static byte[] HashSHA384(byte[] source) - { -#if NET - return SHA384.HashData(source); -#else - using (var sha384 = SHA384.Create()) - { - return sha384.ComputeHash(source); - } -#endif - } - - public static byte[] HashSHA512(byte[] source) - { -#if NET - return SHA512.HashData(source); -#else - using (var sha512 = SHA512.Create()) - { - return sha512.ComputeHash(source); - } -#endif - } } } diff --git a/src/Renci.SshNet/Abstractions/MD5Extensions.cs b/src/Renci.SshNet/Abstractions/MD5Extensions.cs new file mode 100644 index 000000000..bb2532152 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/MD5Extensions.cs @@ -0,0 +1,19 @@ +#nullable enable +namespace System.Security.Cryptography +{ + internal static class MD5Extensions + { + extension(MD5) + { +#if !NET + public static byte[] HashData(byte[] source) + { + using (var md5 = MD5.Create()) + { + return md5.ComputeHash(source); + } + } +#endif + } + } +} diff --git a/src/Renci.SshNet/Abstractions/RandomNumberGeneratorExtensions.cs b/src/Renci.SshNet/Abstractions/RandomNumberGeneratorExtensions.cs new file mode 100644 index 000000000..e1df68686 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/RandomNumberGeneratorExtensions.cs @@ -0,0 +1,22 @@ +#nullable enable +namespace System.Security.Cryptography +{ + internal static class RandomNumberGeneratorExtensions + { +#if !NET + private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create(); +#endif + + extension(RandomNumberGenerator) + { +#if !NET + public static byte[] GetBytes(int length) + { + var random = new byte[length]; + Randomizer.GetBytes(random); + return random; + } +#endif + } + } +} diff --git a/src/Renci.SshNet/Abstractions/SHA1Extensions.cs b/src/Renci.SshNet/Abstractions/SHA1Extensions.cs new file mode 100644 index 000000000..fcf779b38 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/SHA1Extensions.cs @@ -0,0 +1,18 @@ +namespace System.Security.Cryptography +{ + internal static class SHA1Extensions + { + extension(SHA1) + { +#if !NET + public static byte[] HashData(byte[] source) + { + using (var sha1 = SHA1.Create()) + { + return sha1.ComputeHash(source); + } + } +#endif + } + } +} diff --git a/src/Renci.SshNet/Abstractions/SHA256Extensions.cs b/src/Renci.SshNet/Abstractions/SHA256Extensions.cs new file mode 100644 index 000000000..4d50a4003 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/SHA256Extensions.cs @@ -0,0 +1,19 @@ +#nullable enable +namespace System.Security.Cryptography +{ + internal static class SHA256Extensions + { + extension(SHA256) + { +#if !NET + public static byte[] HashData(byte[] source) + { + using (var sha256 = SHA256.Create()) + { + return sha256.ComputeHash(source); + } + } +#endif + } + } +} diff --git a/src/Renci.SshNet/Abstractions/SHA384Extensions.cs b/src/Renci.SshNet/Abstractions/SHA384Extensions.cs new file mode 100644 index 000000000..917dc8fb7 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/SHA384Extensions.cs @@ -0,0 +1,19 @@ +#nullable enable +namespace System.Security.Cryptography +{ + internal static class SHA384Extensions + { + extension(SHA384) + { +#if !NET + public static byte[] HashData(byte[] source) + { + using (var sha384 = SHA384.Create()) + { + return sha384.ComputeHash(source); + } + } +#endif + } + } +} diff --git a/src/Renci.SshNet/Abstractions/SHA512Extensions.cs b/src/Renci.SshNet/Abstractions/SHA512Extensions.cs new file mode 100644 index 000000000..78f0f3183 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/SHA512Extensions.cs @@ -0,0 +1,19 @@ +#nullable enable +namespace System.Security.Cryptography +{ + internal static class SHA512Extensions + { + extension(SHA512) + { +#if !NET + public static byte[] HashData(byte[] source) + { + using (var sha512 = SHA512.Create()) + { + return sha512.ComputeHash(source); + } + } +#endif + } + } +} diff --git a/src/Renci.SshNet/Common/HostKeyEventArgs.cs b/src/Renci.SshNet/Common/HostKeyEventArgs.cs index 37fe829a5..8ebb67ea6 100644 --- a/src/Renci.SshNet/Common/HostKeyEventArgs.cs +++ b/src/Renci.SshNet/Common/HostKeyEventArgs.cs @@ -1,7 +1,7 @@ #nullable enable using System; +using System.Security.Cryptography; -using Renci.SshNet.Abstractions; using Renci.SshNet.Security; namespace Renci.SshNet.Common @@ -104,9 +104,9 @@ public HostKeyEventArgs(KeyHostAlgorithm host) HostKeyName = host.Name; KeyLength = host.Key.KeyLength; - _lazyFingerPrint = new Lazy(() => CryptoAbstraction.HashMD5(HostKey)); + _lazyFingerPrint = new Lazy(() => MD5.HashData(HostKey)); - _lazyFingerPrintSHA256 = new Lazy(() => Convert.ToBase64String(CryptoAbstraction.HashSHA256(HostKey)).TrimEnd('=')); + _lazyFingerPrintSHA256 = new Lazy(() => Convert.ToBase64String(SHA256.HashData(HostKey)).TrimEnd('=')); _lazyFingerPrintMD5 = new Lazy(() => { diff --git a/src/Renci.SshNet/Messages/Message.cs b/src/Renci.SshNet/Messages/Message.cs index ea8f6a9b5..96815378c 100644 --- a/src/Renci.SshNet/Messages/Message.cs +++ b/src/Renci.SshNet/Messages/Message.cs @@ -1,6 +1,6 @@ using System.IO; +using System.Security.Cryptography; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Compression; @@ -83,7 +83,7 @@ internal byte[] GetPacket(byte paddingMultiplier, Compressor compressor, bool ex var paddingLength = GetPaddingLength(paddingMultiplier, excludePacketLengthFieldWhenPadding ? packetLength - 4 : packetLength); // add padding bytes - var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength); + var paddingBytes = RandomNumberGenerator.GetBytes(paddingLength); sshDataStream.Write(paddingBytes, 0, paddingLength); var packetDataLength = GetPacketDataLength(messageLength, paddingLength); @@ -127,7 +127,7 @@ internal byte[] GetPacket(byte paddingMultiplier, Compressor compressor, bool ex WriteBytes(sshDataStream); // add padding bytes - var paddingBytes = CryptoAbstraction.GenerateRandom(paddingLength); + var paddingBytes = RandomNumberGenerator.GetBytes(paddingLength); sshDataStream.Write(paddingBytes, 0, paddingLength); return sshDataStream.ToArray(); diff --git a/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs b/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs index a0e7979ec..d846e86f9 100644 --- a/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs +++ b/src/Renci.SshNet/Messages/Transport/KeyExchangeInitMessage.cs @@ -1,4 +1,4 @@ -using Renci.SshNet.Abstractions; +using System.Security.Cryptography; namespace Renci.SshNet.Messages.Transport { @@ -12,7 +12,7 @@ public class KeyExchangeInitMessage : Message, IKeyExchangedAllowed /// public KeyExchangeInitMessage() { - Cookie = CryptoAbstraction.GenerateRandom(16); + Cookie = RandomNumberGenerator.GetBytes(16); } #region Message Properties diff --git a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs index 34c46c90c..118f98733 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs @@ -9,7 +9,6 @@ using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Security; using Renci.SshNet.Security.Cryptography.Ciphers; @@ -103,7 +102,7 @@ public Key Parse() cipherKey = keyData.Take(32); cipherIV = new byte[16]; - macKey = CryptoAbstraction.HashSHA1(Encoding.UTF8.GetBytes("putty-private-key-file-mac-key" + _passPhrase)).Take(20); + macKey = SHA1.HashData(Encoding.UTF8.GetBytes("putty-private-key-file-mac-key" + _passPhrase)).Take(20); hmac = new HMACSHA1(macKey); break; @@ -124,7 +123,7 @@ public Key Parse() hmac = new HMACSHA256(Array.Empty()); break; case "2": - var macKey = CryptoAbstraction.HashSHA1(Encoding.UTF8.GetBytes("putty-private-key-file-mac-key")); + var macKey = SHA1.HashData(Encoding.UTF8.GetBytes("putty-private-key-file-mac-key")); hmac = new HMACSHA1(macKey); break; default: diff --git a/src/Renci.SshNet/Security/Certificate.cs b/src/Renci.SshNet/Security/Certificate.cs index ccc358fc6..5a412a5b8 100644 --- a/src/Renci.SshNet/Security/Certificate.cs +++ b/src/Renci.SshNet/Security/Certificate.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Numerics; +using System.Security.Cryptography; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; namespace Renci.SshNet.Security @@ -228,7 +228,7 @@ public string CertificateAuthorityKeyFingerPrint { get { - return Convert.ToBase64String(CryptoAbstraction.HashSHA256(CertificateAuthorityKey)).TrimEnd('='); + return Convert.ToBase64String(SHA256.HashData(CertificateAuthorityKey)).TrimEnd('='); } } diff --git a/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs b/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs index 558278873..b7f13cfb0 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECCurve25519.cs @@ -1,4 +1,6 @@ -using Org.BouncyCastle.Crypto.Agreement; +using System.Security.Cryptography; + +using Org.BouncyCastle.Crypto.Agreement; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; @@ -70,7 +72,7 @@ public override void Finish() /// protected override byte[] Hash(byte[] hashData) { - return CryptoAbstraction.HashSHA256(hashData); + return SHA256.HashData(hashData); } private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs e) diff --git a/src/Renci.SshNet/Security/KeyExchangeECDH256.cs b/src/Renci.SshNet/Security/KeyExchangeECDH256.cs index 1272ec9f4..584546699 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECDH256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECDH256.cs @@ -1,7 +1,7 @@ -using Org.BouncyCastle.Asn1.Sec; -using Org.BouncyCastle.Asn1.X9; +using System.Security.Cryptography; -using Renci.SshNet.Abstractions; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; namespace Renci.SshNet.Security { @@ -59,7 +59,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - return CryptoAbstraction.HashSHA256(hashData); + return SHA256.HashData(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeECDH384.cs b/src/Renci.SshNet/Security/KeyExchangeECDH384.cs index 0bd964707..9c587058d 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECDH384.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECDH384.cs @@ -1,7 +1,7 @@ -using Org.BouncyCastle.Asn1.Sec; -using Org.BouncyCastle.Asn1.X9; +using System.Security.Cryptography; -using Renci.SshNet.Abstractions; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; namespace Renci.SshNet.Security { @@ -59,7 +59,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - return CryptoAbstraction.HashSHA384(hashData); + return SHA384.HashData(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeECDH521.cs b/src/Renci.SshNet/Security/KeyExchangeECDH521.cs index a73eedd6e..a97c658df 100644 --- a/src/Renci.SshNet/Security/KeyExchangeECDH521.cs +++ b/src/Renci.SshNet/Security/KeyExchangeECDH521.cs @@ -1,7 +1,7 @@ -using Org.BouncyCastle.Asn1.Sec; -using Org.BouncyCastle.Asn1.X9; +using System.Security.Cryptography; -using Renci.SshNet.Abstractions; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Asn1.X9; namespace Renci.SshNet.Security { @@ -59,7 +59,7 @@ protected override int HashSize /// protected override byte[] Hash(byte[] hashData) { - return CryptoAbstraction.HashSHA512(hashData); + return SHA512.HashData(hashData); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs index 469a53738..d860c9222 100644 --- a/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs +++ b/src/Renci.SshNet/Security/KeyExchangeMLKem768X25519Sha256.cs @@ -1,5 +1,6 @@ using System.Globalization; using System.Linq; +using System.Security.Cryptography; using Org.BouncyCastle.Crypto.Agreement; using Org.BouncyCastle.Crypto.Generators; @@ -86,7 +87,7 @@ public override void Finish() /// protected override byte[] Hash(byte[] hashData) { - return CryptoAbstraction.HashSHA256(hashData); + return SHA256.HashData(hashData); } private void Session_KeyExchangeHybridReplyMessageReceived(object sender, MessageEventArgs e) @@ -128,7 +129,7 @@ private void HandleServerHybridReply(byte[] hostKey, byte[] serverExchangeValue, var x25519PublicKey = new X25519PublicKeyParameters(serverExchangeValue, _mlkemDecapsulator.EncapsulationLength); _x25519Agreement.CalculateAgreement(x25519PublicKey, secret, _mlkemDecapsulator.SecretLength); - SharedKey = CryptoAbstraction.HashSHA256(secret); + SharedKey = SHA256.HashData(secret); } } } diff --git a/src/Renci.SshNet/Security/KeyExchangeSNtruP761X25519Sha512.cs b/src/Renci.SshNet/Security/KeyExchangeSNtruP761X25519Sha512.cs index 1b327f56c..b7db01165 100644 --- a/src/Renci.SshNet/Security/KeyExchangeSNtruP761X25519Sha512.cs +++ b/src/Renci.SshNet/Security/KeyExchangeSNtruP761X25519Sha512.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Linq; +using System.Security.Cryptography; using Org.BouncyCastle.Crypto.Agreement; using Org.BouncyCastle.Crypto.Generators; @@ -86,7 +87,7 @@ public override void Finish() /// protected override byte[] Hash(byte[] hashData) { - return CryptoAbstraction.HashSHA512(hashData); + return SHA512.HashData(hashData); } private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs e) @@ -129,7 +130,7 @@ private void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, b Array.Resize(ref secret, sntrup761SecretLength + _x25519Agreement.AgreementSize); _x25519Agreement.CalculateAgreement(x25519PublicKey, secret, sntrup761SecretLength); - SharedKey = CryptoAbstraction.HashSHA512(secret); + SharedKey = SHA512.HashData(secret); } } } diff --git a/test/Renci.SshNet.Tests/Classes/AbstractionsTest.cs b/test/Renci.SshNet.Tests/Classes/AbstractionsTest.cs index e79eb8561..97f8e6888 100644 --- a/test/Renci.SshNet.Tests/Classes/AbstractionsTest.cs +++ b/test/Renci.SshNet.Tests/Classes/AbstractionsTest.cs @@ -2,6 +2,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Threading; +using System.Security.Cryptography; namespace Renci.SshNet.Tests.Classes { @@ -17,7 +18,7 @@ public void SocketAbstraction_CanWrite_ShouldReturnFalseWhenSocketIsNull() [TestMethod] public void CryptoAbstraction_GenerateRandom_ShouldPerformNoOpWhenDataIsZeroLength() { - Assert.AreEqual(0, CryptoAbstraction.GenerateRandom(0).Length); + Assert.AreEqual(0, RandomNumberGenerator.GetBytes(0).Length); } [TestMethod] @@ -25,8 +26,8 @@ public void CryptoAbstraction_GenerateRandom_ShouldGenerateRandomSequenceOfValue { var dataLength = new Random().Next(1, 100); - var dataA = CryptoAbstraction.GenerateRandom(dataLength); - var dataB = CryptoAbstraction.GenerateRandom(dataLength); + var dataA = RandomNumberGenerator.GetBytes(dataLength); + var dataB = RandomNumberGenerator.GetBytes(dataLength); Assert.AreEqual(dataLength, dataA.Length); Assert.AreEqual(dataLength, dataB.Length); diff --git a/test/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelDataMessageTest.cs b/test/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelDataMessageTest.cs index 2f96b11d8..031135b78 100644 --- a/test/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelDataMessageTest.cs +++ b/test/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelDataMessageTest.cs @@ -1,9 +1,9 @@ using System; using System.Linq; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Messages.Connection; using Renci.SshNet.Tests.Common; @@ -101,7 +101,7 @@ public void GetBytes() var random = new Random(); var localChannelNumber = (uint)random.Next(0, int.MaxValue); - var data = CryptoAbstraction.GenerateRandom(random.Next(10, 20)); + var data = RandomNumberGenerator.GetBytes(random.Next(10, 20)); var offset = random.Next(0, data.Length - 1); var size = random.Next(0, data.Length - offset); @@ -135,7 +135,7 @@ public void Load() var random = new Random(); var localChannelNumber = (uint)random.Next(0, int.MaxValue); - var data = CryptoAbstraction.GenerateRandom(random.Next(10, 20)); + var data = RandomNumberGenerator.GetBytes(random.Next(10, 20)); var offset = random.Next(0, data.Length - 1); var size = random.Next(0, data.Length - offset); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_EndLStatThrowsSshException.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_EndLStatThrowsSshException.cs index 77e226b3c..be27ed6e5 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_EndLStatThrowsSshException.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_EndLStatThrowsSshException.cs @@ -1,11 +1,11 @@ using System; +using System.Security.Cryptography; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Sftp; @@ -31,7 +31,7 @@ private void SetupData() _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1, int.MaxValue); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsAlmostSixTimesGreaterThanChunkSize.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsAlmostSixTimesGreaterThanChunkSize.cs index a869f48f8..148b12e96 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsAlmostSixTimesGreaterThanChunkSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsAlmostSixTimesGreaterThanChunkSize.cs @@ -1,10 +1,10 @@ using System; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Sftp; using Renci.SshNet.Tests.Common; @@ -32,7 +32,7 @@ private void SetupData() _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1000, 5000); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsEqualToChunkSize.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsEqualToChunkSize.cs index 29a0c9c71..da84d512b 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsEqualToChunkSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsEqualToChunkSize.cs @@ -1,10 +1,10 @@ using System; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Sftp; using Renci.SshNet.Tests.Common; @@ -32,7 +32,7 @@ private void SetupData() _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1000, int.MaxValue); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsExactlyFiveTimesGreaterThanChunkSize.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsExactlyFiveTimesGreaterThanChunkSize.cs index 47a446c17..af95d4f14 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsExactlyFiveTimesGreaterThanChunkSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsExactlyFiveTimesGreaterThanChunkSize.cs @@ -1,10 +1,10 @@ using System; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Sftp; using Renci.SshNet.Tests.Common; @@ -32,7 +32,7 @@ private void SetupData() _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1000, 5000); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLessThanChunkSize.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLessThanChunkSize.cs index b2202b183..d7410adb4 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLessThanChunkSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLessThanChunkSize.cs @@ -1,10 +1,10 @@ using System; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Sftp; using Renci.SshNet.Tests.Common; @@ -32,7 +32,7 @@ private void SetupData() _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1000, int.MaxValue); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLittleMoreThanFiveTimesGreaterThanChunkSize.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLittleMoreThanFiveTimesGreaterThanChunkSize.cs index c0439cba9..5f14aee1d 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLittleMoreThanFiveTimesGreaterThanChunkSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsLittleMoreThanFiveTimesGreaterThanChunkSize.cs @@ -1,10 +1,10 @@ using System; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Sftp; using Renci.SshNet.Tests.Common; @@ -32,7 +32,7 @@ private void SetupData() _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1000, 5000); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsMoreThanMaxPendingReadsTimesChunkSize.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsMoreThanMaxPendingReadsTimesChunkSize.cs index 105085a25..53a57f5f3 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsMoreThanMaxPendingReadsTimesChunkSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsMoreThanMaxPendingReadsTimesChunkSize.cs @@ -1,10 +1,10 @@ using System; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Sftp; using Renci.SshNet.Tests.Common; @@ -34,7 +34,7 @@ private void SetupData() _maxPendingReads = 100; _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1000, 5000); diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs index 068865800..39fb6a89d 100644 --- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs +++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs @@ -1,10 +1,10 @@ using System; +using System.Security.Cryptography; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Sftp; using Renci.SshNet.Tests.Common; @@ -32,7 +32,7 @@ private void SetupData() _bufferSize = (uint)random.Next(1, int.MaxValue); _openAsyncResult = new SftpOpenAsyncResult(null, null); - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _statAsyncResult = new SFtpStatAsyncResult(null, null); _fileName = random.Next().ToString(); _chunkSize = (uint)random.Next(1, int.MaxValue); diff --git a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs index 957bf2ece..d425afdb3 100644 --- a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs +++ b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectingBase.cs @@ -10,7 +10,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Common; using Renci.SshNet.Compression; using Renci.SshNet.Connection; @@ -174,7 +173,7 @@ protected virtual void SetupData() var serviceAcceptMessage = ServiceAcceptMessageBuilder.Create(ServiceName.UserAuthentication) .Build(ServerOutboundPacketSequence); - var hash = CryptoAbstraction.HashSHA256(serviceAcceptMessage); + var hash = SHA256.HashData(serviceAcceptMessage); var packet = new byte[serviceAcceptMessage.Length - 4 + hash.Length]; diff --git a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs index 50125eb7f..5a7fd28a7 100644 --- a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs +++ b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Sftp; @@ -78,10 +78,10 @@ private void SetupData() #endregion SftpSession.Connect() - _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10)); + _handle = RandomNumberGenerator.GetBytes(random.Next(1, 10)); _offset = (uint)random.Next(1, 5); _length = (uint)random.Next(30, 50); - _data = CryptoAbstraction.GenerateRandom((int)_length); + _data = RandomNumberGenerator.GetBytes((int)_length); _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion) .WithRequestId(2) .WithHandle(_handle) diff --git a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs index 45bf5c020..762436ebb 100644 --- a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs +++ b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs @@ -1,4 +1,5 @@ using System; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -6,7 +7,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Sftp; @@ -81,10 +81,10 @@ private void SetupData() #endregion SftpSession.Connect() _path = random.Next().ToString(); - _handle = CryptoAbstraction.GenerateRandom(4); + _handle = RandomNumberGenerator.GetBytes(4); _offset = (uint)random.Next(1, 5); _length = (uint)random.Next(30, 50); - _data = CryptoAbstraction.GenerateRandom(200); + _data = RandomNumberGenerator.GetBytes(200); _sftpOpenRequestBytes = new SftpOpenRequestBuilder().WithProtocolVersion(_protocolVersion) .WithRequestId(2) .WithFileName(_path) diff --git a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs index e0e809af8..e2a6cf58f 100644 --- a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs +++ b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs @@ -1,4 +1,5 @@ using System; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -6,7 +7,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Sftp; @@ -81,10 +81,10 @@ private void SetupData() #endregion SftpSession.Connect() _path = random.Next().ToString(); - _handle = CryptoAbstraction.GenerateRandom(4); + _handle = RandomNumberGenerator.GetBytes(4); _offset = (uint)random.Next(1, 5); _length = (uint)random.Next(30, 50); - _data = CryptoAbstraction.GenerateRandom(200); + _data = RandomNumberGenerator.GetBytes(200); _sftpOpenRequestBytes = new SftpOpenRequestBuilder().WithProtocolVersion(_protocolVersion) .WithRequestId(2) .WithFileName(_path) diff --git a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs index 88aad7e6b..3e8e28903 100644 --- a/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs +++ b/test/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs @@ -1,4 +1,5 @@ using System; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -6,7 +7,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Sftp; @@ -76,10 +76,10 @@ private void SetupData() #endregion SftpSession.Connect() - _handle = CryptoAbstraction.GenerateRandom(4); + _handle = RandomNumberGenerator.GetBytes(4); _offset = (uint)random.Next(1, 5); _length = (uint)random.Next(30, 50); - _data = CryptoAbstraction.GenerateRandom(200); + _data = RandomNumberGenerator.GetBytes(200); _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion) .WithRequestId(2) .WithHandle(_handle) diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs index b4b071707..377214c76 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -10,7 +11,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -94,7 +94,7 @@ public void Read_Bytes_Span() public void Channel_DataReceived_MoreThanBufferSize() { // Test buffer resizing - byte[] expectedData = CryptoAbstraction.GenerateRandom(BufferSize * 3); + byte[] expectedData = RandomNumberGenerator.GetBytes(BufferSize * 3); _channelSessionStub.Receive(expectedData); byte[] actualData = new byte[expectedData.Length + 1]; diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs index 54e97d594..f46fe9f93 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs @@ -1,12 +1,12 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -51,7 +51,7 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _data = CryptoAbstraction.GenerateRandom(_bufferSize - 10); + _data = RandomNumberGenerator.GetBytes(_bufferSize - 10); _offset = random.Next(1, 5); _count = _data.Length - _offset - random.Next(1, 10); } diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs index 977f47817..7bdb2f6be 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -55,7 +55,7 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _data = CryptoAbstraction.GenerateRandom((_bufferSize * 2) + 10); + _data = RandomNumberGenerator.GetBytes((_bufferSize * 2) + 10); _offset = 0; _count = _data.Length; diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs index e14dcc106..52377bd06 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -52,7 +52,7 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _data = CryptoAbstraction.GenerateRandom(_bufferSize); + _data = RandomNumberGenerator.GetBytes(_bufferSize); _offset = 0; _count = _data.Length; } diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs index 08ec7a654..967015533 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -53,8 +53,8 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _bufferData = CryptoAbstraction.GenerateRandom(_bufferSize); - _data = CryptoAbstraction.GenerateRandom(_bufferSize - 10); + _bufferData = RandomNumberGenerator.GetBytes(_bufferSize); + _data = RandomNumberGenerator.GetBytes(_bufferSize - 10); _offset = 0; _count = _data.Length; } diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs index c5928291f..d43ac979a 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -53,7 +53,7 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _bufferData = CryptoAbstraction.GenerateRandom(_bufferSize); + _bufferData = RandomNumberGenerator.GetBytes(_bufferSize); _data = new byte[0]; _offset = 0; _count = _data.Length; diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs index f4739bd2e..2993609f8 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -53,8 +53,8 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _bufferData = CryptoAbstraction.GenerateRandom(_bufferSize - 60); - _data = CryptoAbstraction.GenerateRandom(_bufferSize + 100); + _bufferData = RandomNumberGenerator.GetBytes(_bufferSize - 60); + _data = RandomNumberGenerator.GetBytes(_bufferSize + 100); _offset = 0; _count = _bufferSize - _bufferData.Length - random.Next(1, 10); } diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs index 30de20fb5..3aa6b65c2 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Tests.Common; @@ -55,8 +55,8 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _bufferData = CryptoAbstraction.GenerateRandom(_bufferSize - 60); - _data = CryptoAbstraction.GenerateRandom(_bufferSize - _bufferData.Length + random.Next(1, 10)); + _bufferData = RandomNumberGenerator.GetBytes(_bufferSize - 60); + _data = RandomNumberGenerator.GetBytes(_bufferSize - _bufferData.Length + random.Next(1, 10)); _offset = 0; _count = _data.Length; diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs index 23c82bfc0..18a9156d5 100644 --- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs +++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +8,6 @@ using Moq; -using Renci.SshNet.Abstractions; using Renci.SshNet.Channels; using Renci.SshNet.Common; @@ -53,7 +53,7 @@ private void SetupData() _terminalModes = new Dictionary(); _bufferSize = random.Next(100, 1000); - _bufferData = CryptoAbstraction.GenerateRandom(_bufferSize - 60); + _bufferData = RandomNumberGenerator.GetBytes(_bufferSize - 60); _data = new byte[0]; _offset = 0; _count = _data.Length; From f85fe5c3f93ff967762a88cb4b6bec60487fb0a7 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 9 May 2025 22:56:03 +0200 Subject: [PATCH 14/16] use extension member for DateTime.UnixEpoch --- .../Abstractions/DateTimeExtensions.cs | 19 +++++++++++++++++++ src/Renci.SshNet/ScpClient.cs | 8 -------- 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 src/Renci.SshNet/Abstractions/DateTimeExtensions.cs diff --git a/src/Renci.SshNet/Abstractions/DateTimeExtensions.cs b/src/Renci.SshNet/Abstractions/DateTimeExtensions.cs new file mode 100644 index 000000000..5cf7cfad3 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/DateTimeExtensions.cs @@ -0,0 +1,19 @@ +#nullable enable +namespace System +{ + internal static class DateTimeExtensions + { + extension(DateTime) + { +#if !NET + public static DateTime UnixEpoch + { + get + { + return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + } + } +#endif + } + } +} diff --git a/src/Renci.SshNet/ScpClient.cs b/src/Renci.SshNet/ScpClient.cs index 35ce5f5c8..b95f361d0 100644 --- a/src/Renci.SshNet/ScpClient.cs +++ b/src/Renci.SshNet/ScpClient.cs @@ -675,11 +675,7 @@ private string ReadString(Stream stream) /// The file or directory to upload. private void UploadTimes(IChannelSession channel, Stream input, FileSystemInfo fileOrDirectory) { -#if NET var zeroTime = DateTime.UnixEpoch; -#else - var zeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); -#endif var modificationSeconds = (long)(fileOrDirectory.LastWriteTimeUtc - zeroTime).TotalSeconds; var accessSeconds = (long)(fileOrDirectory.LastAccessTimeUtc - zeroTime).TotalSeconds; SendData(channel, string.Format(CultureInfo.InvariantCulture, "T{0} 0 {1} 0\n", modificationSeconds, accessSeconds)); @@ -856,11 +852,7 @@ private void InternalDownload(IChannelSession channel, Stream input, FileSystemI var mtime = long.Parse(match.Result("${mtime}"), CultureInfo.InvariantCulture); var atime = long.Parse(match.Result("${atime}"), CultureInfo.InvariantCulture); -#if NET var zeroTime = DateTime.UnixEpoch; -#else - var zeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); -#endif modifiedTime = zeroTime.AddSeconds(mtime); accessedTime = zeroTime.AddSeconds(atime); continue; From cda5b8faff758753d80a64eb4c6dd84aea5d1db4 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 9 May 2025 23:02:59 +0200 Subject: [PATCH 15/16] use extension members for string.Join etc --- .../Abstractions/StringExtensions.cs | 35 ++++++++++++++++ src/Renci.SshNet/ClientAuthentication.cs | 7 +--- src/Renci.SshNet/Common/Extensions.cs | 9 +--- src/Renci.SshNet/Common/SshData.cs | 4 -- .../Messages/Authentication/FailureMessage.cs | 4 -- src/Renci.SshNet/Security/KeyExchange.cs | 42 +++++++++---------- src/Renci.SshNet/ServiceFactory.cs | 2 +- src/Renci.SshNet/Sftp/SftpSession.cs | 8 ---- 8 files changed, 60 insertions(+), 51 deletions(-) create mode 100644 src/Renci.SshNet/Abstractions/StringExtensions.cs diff --git a/src/Renci.SshNet/Abstractions/StringExtensions.cs b/src/Renci.SshNet/Abstractions/StringExtensions.cs new file mode 100644 index 000000000..900a37e3c --- /dev/null +++ b/src/Renci.SshNet/Abstractions/StringExtensions.cs @@ -0,0 +1,35 @@ +#nullable enable +#if NETSTANDARD2_0 || NETFRAMEWORK +using System.Collections.Generic; +#endif + +namespace System +{ + internal static class StringExtensions + { + extension(string text) + { +#if NETSTANDARD2_0 || NETFRAMEWORK + public static string Join(char separator, params string?[] value) + { + return string.Join(separator.ToString(), value); + } + + public static string Join(char separator, IEnumerable value) + { + return string.Join(separator.ToString(), value); + } + + public static string Join(char separator, string?[] value, int startIndex, int count) + { + return string.Join(separator.ToString(), value, startIndex, count); + } + + public int IndexOf(char value, StringComparison comparisonType) + { + return text.IndexOf(value.ToString(), comparisonType); + } +#endif + } + } +} diff --git a/src/Renci.SshNet/ClientAuthentication.cs b/src/Renci.SshNet/ClientAuthentication.cs index 7f998caf1..af4743f72 100644 --- a/src/Renci.SshNet/ClientAuthentication.cs +++ b/src/Renci.SshNet/ClientAuthentication.cs @@ -105,12 +105,7 @@ private bool TryAuthenticate(ISession session, { authenticationException = new SshAuthenticationException(string.Format(CultureInfo.InvariantCulture, "No suitable authentication method found to complete authentication ({0}).", -#if NET - string.Join(',', allowedAuthenticationMethods))) -#else - string.Join(",", allowedAuthenticationMethods))) -#endif - ; + string.Join(',', allowedAuthenticationMethods))); return false; } diff --git a/src/Renci.SshNet/Common/Extensions.cs b/src/Renci.SshNet/Common/Extensions.cs index 89ac0b402..f6449f68b 100644 --- a/src/Renci.SshNet/Common/Extensions.cs +++ b/src/Renci.SshNet/Common/Extensions.cs @@ -1,5 +1,7 @@ using System; +#if !NET using System.Collections.Generic; +#endif using System.Globalization; #if !NET using System.IO; @@ -339,13 +341,6 @@ internal static bool IsConnected(this Socket socket) return socket.Connected; } - internal static string Join(this IEnumerable values, string separator) - { - // Used to avoid analyzers asking to "use an overload with a char parameter" - // which is not available on all targets. - return string.Join(separator, values); - } - #if !NET internal static bool TryAdd(this Dictionary dictionary, TKey key, TValue value) { diff --git a/src/Renci.SshNet/Common/SshData.cs b/src/Renci.SshNet/Common/SshData.cs index ff50a2148..e91dccd3b 100644 --- a/src/Renci.SshNet/Common/SshData.cs +++ b/src/Renci.SshNet/Common/SshData.cs @@ -386,11 +386,7 @@ protected void Write(BigInteger data) /// name-list data to write. protected void Write(string[] data) { -#if NET Write(string.Join(',', data), Ascii); -#else - Write(string.Join(",", data), Ascii); -#endif } /// diff --git a/src/Renci.SshNet/Messages/Authentication/FailureMessage.cs b/src/Renci.SshNet/Messages/Authentication/FailureMessage.cs index bcb4f6b89..85716980c 100644 --- a/src/Renci.SshNet/Messages/Authentication/FailureMessage.cs +++ b/src/Renci.SshNet/Messages/Authentication/FailureMessage.cs @@ -55,11 +55,7 @@ protected override void LoadData() PartialSuccess = ReadBoolean(); if (PartialSuccess) { -#if NET Message = string.Join(',', AllowedAuthentications); -#else - Message = string.Join(",", AllowedAuthentications); -#endif } } diff --git a/src/Renci.SshNet/Security/KeyExchange.cs b/src/Renci.SshNet/Security/KeyExchange.cs index 834b71e24..a9e6917cd 100644 --- a/src/Renci.SshNet/Security/KeyExchange.cs +++ b/src/Renci.SshNet/Security/KeyExchange.cs @@ -91,17 +91,17 @@ from a in message.ServerHostKeyAlgorithms { _logger.LogTrace("[{SessionId}] Host key algorithm: we offer {WeOffer}", Session.SessionIdHex, - session.ConnectionInfo.HostKeyAlgorithms.Keys.Join(",")); + string.Join(',', session.ConnectionInfo.HostKeyAlgorithms.Keys)); _logger.LogTrace("[{SessionId}] Host key algorithm: they offer {TheyOffer}", Session.SessionIdHex, - message.ServerHostKeyAlgorithms.Join(",")); + string.Join(',', message.ServerHostKeyAlgorithms)); } if (hostKeyAlgorithmName is null) { throw new SshConnectionException( - $"No matching host key algorithm (server offers {message.ServerHostKeyAlgorithms.Join(",")})", + $"No matching host key algorithm (server offers {string.Join(',', message.ServerHostKeyAlgorithms)})", DisconnectReason.KeyExchangeFailed); } @@ -118,17 +118,17 @@ from a in message.EncryptionAlgorithmsClientToServer { _logger.LogTrace("[{SessionId}] Encryption client to server: we offer {WeOffer}", Session.SessionIdHex, - session.ConnectionInfo.Encryptions.Keys.Join(",")); + string.Join(',', session.ConnectionInfo.Encryptions.Keys)); _logger.LogTrace("[{SessionId}] Encryption client to server: they offer {TheyOffer}", Session.SessionIdHex, - message.EncryptionAlgorithmsClientToServer.Join(",")); + string.Join(',', message.EncryptionAlgorithmsClientToServer)); } if (clientEncryptionAlgorithmName is null) { throw new SshConnectionException( - $"No matching client encryption algorithm (server offers {message.EncryptionAlgorithmsClientToServer.Join(",")})", + $"No matching client encryption algorithm (server offers {string.Join(',', message.EncryptionAlgorithmsClientToServer)})", DisconnectReason.KeyExchangeFailed); } @@ -145,17 +145,17 @@ from a in message.EncryptionAlgorithmsServerToClient { _logger.LogTrace("[{SessionId}] Encryption server to client: we offer {WeOffer}", Session.SessionIdHex, - session.ConnectionInfo.Encryptions.Keys.Join(",")); + string.Join(',', session.ConnectionInfo.Encryptions.Keys)); _logger.LogTrace("[{SessionId}] Encryption server to client: they offer {TheyOffer}", Session.SessionIdHex, - message.EncryptionAlgorithmsServerToClient.Join(",")); + string.Join(',', message.EncryptionAlgorithmsServerToClient)); } if (serverDecryptionAlgorithmName is null) { throw new SshConnectionException( - $"No matching server encryption algorithm (server offers {message.EncryptionAlgorithmsServerToClient.Join(",")})", + $"No matching server encryption algorithm (server offers {string.Join(',', message.EncryptionAlgorithmsServerToClient)})", DisconnectReason.KeyExchangeFailed); } @@ -174,17 +174,17 @@ from a in message.MacAlgorithmsClientToServer { _logger.LogTrace("[{SessionId}] MAC client to server: we offer {WeOffer}", Session.SessionIdHex, - session.ConnectionInfo.HmacAlgorithms.Keys.Join(",")); + string.Join(',', session.ConnectionInfo.HmacAlgorithms.Keys)); _logger.LogTrace("[{SessionId}] MAC client to server: they offer {TheyOffer}", Session.SessionIdHex, - message.MacAlgorithmsClientToServer.Join(",")); + string.Join(',', message.MacAlgorithmsClientToServer)); } if (clientHmacAlgorithmName is null) { throw new SshConnectionException( - $"No matching client MAC algorithm (server offers {message.MacAlgorithmsClientToServer.Join(",")})", + $"No matching client MAC algorithm (server offers {string.Join(',', message.MacAlgorithmsClientToServer)})", DisconnectReason.KeyExchangeFailed); } @@ -204,17 +204,17 @@ from a in message.MacAlgorithmsServerToClient { _logger.LogTrace("[{SessionId}] MAC server to client: we offer {WeOffer}", Session.SessionIdHex, - session.ConnectionInfo.HmacAlgorithms.Keys.Join(",")); + string.Join(',', session.ConnectionInfo.HmacAlgorithms.Keys)); _logger.LogTrace("[{SessionId}] MAC server to client: they offer {TheyOffer}", Session.SessionIdHex, - message.MacAlgorithmsServerToClient.Join(",")); + string.Join(',', message.MacAlgorithmsServerToClient)); } if (serverHmacAlgorithmName is null) { throw new SshConnectionException( - $"No matching server MAC algorithm (server offers {message.MacAlgorithmsServerToClient.Join(",")})", + $"No matching server MAC algorithm (server offers {string.Join(',', message.MacAlgorithmsServerToClient)})", DisconnectReason.KeyExchangeFailed); } @@ -232,17 +232,17 @@ from a in message.CompressionAlgorithmsClientToServer { _logger.LogTrace("[{SessionId}] Compression client to server: we offer {WeOffer}", Session.SessionIdHex, - session.ConnectionInfo.CompressionAlgorithms.Keys.Join(",")); + string.Join(',', session.ConnectionInfo.CompressionAlgorithms.Keys)); _logger.LogTrace("[{SessionId}] Compression client to server: they offer {TheyOffer}", Session.SessionIdHex, - message.CompressionAlgorithmsClientToServer.Join(",")); + string.Join(',', message.CompressionAlgorithmsClientToServer)); } if (compressionAlgorithmName is null) { throw new SshConnectionException( - $"No matching client compression algorithm (server offers {message.CompressionAlgorithmsClientToServer.Join(",")})", + $"No matching client compression algorithm (server offers {string.Join(',', message.CompressionAlgorithmsClientToServer)})", DisconnectReason.KeyExchangeFailed); } @@ -259,17 +259,17 @@ from a in message.CompressionAlgorithmsServerToClient { _logger.LogTrace("[{SessionId}] Compression server to client: we offer {WeOffer}", Session.SessionIdHex, - session.ConnectionInfo.CompressionAlgorithms.Keys.Join(",")); + string.Join(',', session.ConnectionInfo.CompressionAlgorithms.Keys)); _logger.LogTrace("[{SessionId}] Compression server to client: they offer {TheyOffer}", Session.SessionIdHex, - message.CompressionAlgorithmsServerToClient.Join(",")); + string.Join(',', message.CompressionAlgorithmsServerToClient)); } if (decompressionAlgorithmName is null) { throw new SshConnectionException( - $"No matching server compression algorithm (server offers {message.CompressionAlgorithmsServerToClient.Join(",")})", + $"No matching server compression algorithm (server offers {string.Join(',', message.CompressionAlgorithmsServerToClient)})", DisconnectReason.KeyExchangeFailed); } diff --git a/src/Renci.SshNet/ServiceFactory.cs b/src/Renci.SshNet/ServiceFactory.cs index 8e8d721c1..16837e1cd 100644 --- a/src/Renci.SshNet/ServiceFactory.cs +++ b/src/Renci.SshNet/ServiceFactory.cs @@ -98,7 +98,7 @@ from s in serverAlgorithms if (keyExchangeAlgorithmFactory is null) { - throw new SshConnectionException($"No matching key exchange algorithm (server offers {serverAlgorithms.Join(",")})", DisconnectReason.KeyExchangeFailed); + throw new SshConnectionException($"No matching key exchange algorithm (server offers {string.Join(',', serverAlgorithms)})", DisconnectReason.KeyExchangeFailed); } return keyExchangeAlgorithmFactory(); diff --git a/src/Renci.SshNet/Sftp/SftpSession.cs b/src/Renci.SshNet/Sftp/SftpSession.cs index 9a6c401b5..cd18dabff 100644 --- a/src/Renci.SshNet/Sftp/SftpSession.cs +++ b/src/Renci.SshNet/Sftp/SftpSession.cs @@ -137,22 +137,14 @@ public string GetCanonicalPath(string path) if (fullPath.EndsWith("/.", StringComparison.OrdinalIgnoreCase) || fullPath.EndsWith("/..", StringComparison.OrdinalIgnoreCase) || fullPath.Equals("/", StringComparison.OrdinalIgnoreCase) || -#if NET fullPath.IndexOf('/', StringComparison.OrdinalIgnoreCase) < 0) -#else - fullPath.IndexOf('/') < 0) -#endif { return fullPath; } var pathParts = fullPath.Split('/'); -#if NET var partialFullPath = string.Join('/', pathParts, 0, pathParts.Length - 1); -#else - var partialFullPath = string.Join("/", pathParts, 0, pathParts.Length - 1); -#endif if (string.IsNullOrEmpty(partialFullPath)) { From 34bbd2ff98ab9e5f55fb9205c047f6347f04aee5 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 9 May 2025 23:08:18 +0200 Subject: [PATCH 16/16] use extension members for Convert.To/FromHexString --- .../Abstractions/ConvertExtensions.cs | 34 +++++++++++++++++++ src/Renci.SshNet/PrivateKeyFile.PKCS1.cs | 5 +-- src/Renci.SshNet/PrivateKeyFile.PuTTY.cs | 10 ++---- src/Renci.SshNet/Session.cs | 28 ++------------- .../Security/Cryptography/RsaKeyTest.cs | 4 --- 5 files changed, 39 insertions(+), 42 deletions(-) create mode 100644 src/Renci.SshNet/Abstractions/ConvertExtensions.cs diff --git a/src/Renci.SshNet/Abstractions/ConvertExtensions.cs b/src/Renci.SshNet/Abstractions/ConvertExtensions.cs new file mode 100644 index 000000000..595bc2ec6 --- /dev/null +++ b/src/Renci.SshNet/Abstractions/ConvertExtensions.cs @@ -0,0 +1,34 @@ +#nullable enable +#if !NET +using System.Text; +#endif + +namespace System +{ + internal static class ConvertExtensions + { + extension(Convert) + { +#if !NET + public static byte[] FromHexString(string s) + { + return Org.BouncyCastle.Utilities.Encoders.Hex.Decode(s); + } + + public static string ToHexString(byte[] inArray) + { + ArgumentNullException.ThrowIfNull(inArray); + + var builder = new StringBuilder(inArray.Length * 2); + + foreach (var b in inArray) + { + builder.Append(b.ToString("X2")); + } + + return builder.ToString(); + } +#endif + } + } +} diff --git a/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs b/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs index f63fe05d0..9f27a8d70 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PKCS1.cs @@ -42,11 +42,8 @@ public Key Parse() { throw new SshPassPhraseNullOrEmptyException("Private key is encrypted but passphrase is empty."); } -#if NET + var binarySalt = Convert.FromHexString(_salt); -#else - var binarySalt = Org.BouncyCastle.Utilities.Encoders.Hex.Decode(_salt); -#endif CipherInfo cipher; switch (_cipherName) { diff --git a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs index 118f98733..9c1fcc1b5 100644 --- a/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs +++ b/src/Renci.SshNet/PrivateKeyFile.PuTTY.cs @@ -82,11 +82,7 @@ public Key Parse() Convert.ToInt32(_argon2Iterations), Convert.ToInt32(_argon2Memory), Convert.ToInt32(_argon2Parallelism), -#if NET Convert.FromHexString(_argon2Salt), -#else - Org.BouncyCastle.Utilities.Encoders.Hex.Decode(_argon2Salt), -#endif _passPhrase); cipherKey = keyData.Take(32); @@ -152,11 +148,9 @@ public Key Parse() { macValue = hmac.ComputeHash(macData); } -#if NET + var reference = Convert.FromHexString(_mac); -#else - var reference = Org.BouncyCastle.Utilities.Encoders.Hex.Decode(_mac); -#endif + if (!macValue.SequenceEqual(reference)) { throw new SshException("MAC verification failed for PuTTY key file"); diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index 06f94a0bf..2d332bb5b 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -5,9 +5,6 @@ using System.Linq; using System.Net.Sockets; using System.Security.Cryptography; -#if !NET -using System.Text; -#endif using System.Threading; using System.Threading.Tasks; @@ -310,7 +307,7 @@ public byte[] SessionId private set { _sessionId = value; - SessionIdHex = ToHex(value); + SessionIdHex = value == null ? null : Convert.ToHexString(value); } } @@ -1592,7 +1589,7 @@ internal void OnNewKeysReceived(NewKeysMessage message) { System.IO.File.AppendAllText( path, - $"{ToHex(ClientInitMessage.Cookie)} SHARED_SECRET {ToHex(kex.SharedKey)}{Environment.NewLine}"); + $"{Convert.ToHexString(ClientInitMessage.Cookie)} SHARED_SECRET {Convert.ToHexString(kex.SharedKey)}{Environment.NewLine}"); } #endif @@ -1861,27 +1858,6 @@ private Message LoadMessage(byte[] data, int offset, int count) return message; } - private static string ToHex(byte[] bytes) - { - if (bytes is null) - { - return null; - } - -#if NET - return Convert.ToHexString(bytes); -#else - var builder = new StringBuilder(bytes.Length * 2); - - foreach (var b in bytes) - { - builder.Append(b.ToString("X2")); - } - - return builder.ToString(); -#endif - } - /// /// Gets a value indicating whether the socket is connected. /// diff --git a/test/Renci.SshNet.Tests/Classes/Security/Cryptography/RsaKeyTest.cs b/test/Renci.SshNet.Tests/Classes/Security/Cryptography/RsaKeyTest.cs index 3dd739cb4..4db84a145 100644 --- a/test/Renci.SshNet.Tests/Classes/Security/Cryptography/RsaKeyTest.cs +++ b/test/Renci.SshNet.Tests/Classes/Security/Cryptography/RsaKeyTest.cs @@ -24,11 +24,7 @@ private static RsaKey GetRsaKey(string fileName, string passPhrase = null) // This is just to line up any differences in the assertion message. private static void AssertEqual(byte[] actualBytes, string expectedHex) { -#if NET string actualHex = Convert.ToHexString(actualBytes); -#else - string actualHex = BitConverter.ToString(actualBytes).Replace("-", ""); -#endif Assert.AreEqual(expectedHex, actualHex, $"{Environment.NewLine}Expected: {expectedHex}{Environment.NewLine} Actual: {actualHex}");