Skip to content

Commit

Permalink
Merge branch 'develop' into nbgvprops
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob-Hague authored Dec 18, 2024
2 parents dab149f + 021ee99 commit 1a7905a
Show file tree
Hide file tree
Showing 54 changed files with 1,037 additions and 230 deletions.
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ dotnet_diagnostic.S2971.severity = none
# This is rather harmless.
dotnet_diagnostic.S3218.severity = none

# S3236: Remove this argument from the method call; it hides the caller information.
dotnet_diagnostic.S3236.severity = none

# S3267: Loops should be simplified with "LINQ" expressions
# https://rules.sonarsource.com/csharp/RSPEC-3267
#
Expand Down Expand Up @@ -701,6 +704,9 @@ dotnet_code_quality.CA1828.api_surface = all
# Similar to MA0053, but does not support public types and types that define (new) virtual members.
dotnet_diagnostic.CA1852.severity = none

# CA1848: don't enforce LoggerMessage pattern
dotnet_diagnostic.CA1848.severity = suggestion

# CA1859: Change return type for improved performance
#
# By default, this diagnostic is only reported for private members.
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,39 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x

- name: Build Unit Tests .NET
run: dotnet build -f net8.0 test/Renci.SshNet.Tests/
run: dotnet build -f net9.0 test/Renci.SshNet.Tests/

- name: Build IntegrationTests .NET
run: dotnet build -f net8.0 test/Renci.SshNet.IntegrationTests/
run: dotnet build -f net9.0 test/Renci.SshNet.IntegrationTests/

- name: Build IntegrationTests .NET Framework
run: dotnet build -f net48 test/Renci.SshNet.IntegrationTests/

- name: Run Unit Tests .NET
run: |
dotnet test \
-f net8.0 \
-f net9.0 \
--no-build \
--logger "console;verbosity=normal" \
--logger GitHubActions \
-p:CollectCoverage=true \
-p:CoverletOutputFormat=cobertura \
-p:CoverletOutput=../../coverlet/linux_unit_test_net_8_coverage.xml \
-p:CoverletOutput=../../coverlet/linux_unit_test_net_9_coverage.xml \
test/Renci.SshNet.Tests/
- name: Run Integration Tests .NET
run: |
dotnet test \
-f net8.0 \
-f net9.0 \
--no-build \
--logger "console;verbosity=normal" \
--logger GitHubActions \
-p:CollectCoverage=true \
-p:CoverletOutputFormat=cobertura \
-p:CoverletOutput=../../coverlet/linux_integration_test_net_8_coverage.xml \
-p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage.xml \
test/Renci.SshNet.IntegrationTests/
# Also run a subset of the integration tests targeting netfx using mono. This is a temporary measure to get
Expand Down Expand Up @@ -111,13 +111,13 @@ jobs:
- name: Run Unit Tests .NET
run: |
dotnet test `
-f net8.0 `
-f net9.0 `
--no-build `
--logger "console;verbosity=normal" `
--logger GitHubActions `
-p:CollectCoverage=true `
-p:CoverletOutputFormat=cobertura `
-p:CoverletOutput=../../coverlet/windows_unit_test_net_8_coverage.xml `
-p:CoverletOutput=../../coverlet/windows_unit_test_net_9_coverage.xml `
test/Renci.SshNet.Tests/
- name: Run Unit Tests .NET Framework
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ The repository makes use of continuous integration (CI) with GitHub Actions to v

## Good to know

### TraceSource logging
### Logging

The Debug build of SSH.NET contains rudimentary logging functionality via `System.Diagnostics.TraceSource`. See `Renci.SshNet.Abstractions.DiagnosticAbstraction` for usage examples.
The tests always log to the console. See the [Logging documentation](https://sshnet.github.io/SSH.NET/logging.html) on how to set a custom `ILoggerFactory`.

### Wireshark

Expand Down
5 changes: 4 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.4.0" />
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.5.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1">
Expand All @@ -15,6 +15,9 @@
<PackageVersion Include="Meziantou.Analyzer" Version="2.0.163" />
<!-- Must be kept at version 1.0.0 or higher, see https://github.com/sshnet/SSH.NET/pull/1288 for details. -->
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="1.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageVersion Include="MSTest.TestAdapter" Version="3.6.2" />
<PackageVersion Include="MSTest.TestFramework" Version="3.6.2" />
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ The main types provided by this library are:
## Additional Documentation

* [Further examples](https://sshnet.github.io/SSH.NET/examples.html)
* [Logging](https://sshnet.github.io/SSH.NET/logging.html)
* [API browser](https://sshnet.github.io/SSH.NET/api/Renci.SshNet.html)

## Encryption Methods
Expand Down Expand Up @@ -101,17 +102,21 @@ The main types provided by this library are:
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
* ssh.com format ("BEGIN SSH2 ENCRYPTED PRIVATE KEY")
* OpenSSH key format ("BEGIN OPENSSH PRIVATE KEY")
* PuTTY private key format ("PuTTY-User-Key-File-2", "PuTTY-User-Key-File-3")
* DSA in
* OpenSSL traditional PEM format ("BEGIN DSA PRIVATE KEY")
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
* ssh.com format ("BEGIN SSH2 ENCRYPTED PRIVATE KEY")
* PuTTY private key format ("PuTTY-User-Key-File-2", "PuTTY-User-Key-File-3")
* ECDSA 256/384/521 in
* OpenSSL traditional PEM format ("BEGIN EC PRIVATE KEY")
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
* OpenSSH key format ("BEGIN OPENSSH PRIVATE KEY")
* PuTTY private key format ("PuTTY-User-Key-File-2", "PuTTY-User-Key-File-3")
* ED25519 in
* OpenSSL PKCS#8 PEM format ("BEGIN PRIVATE KEY", "BEGIN ENCRYPTED PRIVATE KEY")
* OpenSSH key format ("BEGIN OPENSSH PRIVATE KEY")
* PuTTY private key format ("PuTTY-User-Key-File-2", "PuTTY-User-Key-File-3")

Private keys in OpenSSL traditional PEM format can be encrypted using one of the following cipher methods:
* DES-EDE3-CBC
Expand All @@ -123,7 +128,7 @@ Private keys in OpenSSL traditional PEM format can be encrypted using one of the

Private keys in OpenSSL PKCS#8 PEM format can be encrypted using any cipher method BouncyCastle supports.

Private keys in ssh.com format can be encrypted using one of the following cipher methods:
Private keys in ssh.com format can be encrypted using the following cipher method:
* 3des-cbc

Private keys in OpenSSH key format can be encrypted using one of the following cipher methods:
Expand All @@ -138,6 +143,9 @@ Private keys in OpenSSH key format can be encrypted using one of the following c
* aes256-gcm<span></span>@openssh.com
* chacha20-poly1305<span></span>@openssh.com

Private keys in PuTTY private key format can be encrypted using the following cipher method:
* aes256-cbc

## Host Key Algorithms

**SSH.NET** supports the following host key algorithms:
Expand Down
5 changes: 0 additions & 5 deletions appveyor.yml

This file was deleted.

15 changes: 15 additions & 0 deletions docfx/logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Logging
=================

SSH.NET uses the [Microsoft.Extensions.Logging](https://learn.microsoft.com/dotnet/core/extensions/logging) API to log diagnostic messages. In order to access the log messages of SSH.NET in your own application for diagnosis, register your own `ILoggerFactory` before using the SSH.NET APIs, for example:

```cs
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Debug);
builder.AddConsole();
});

Renci.SshNet.SshNetLoggingConfiguration.InitializeLogging(loggerFactory);

All messages by SSH.NET are logged under the `Renci.SshNet` category.
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.100",
"version": "9.0.100",
"rollForward": "latestMajor"
}
}
69 changes: 0 additions & 69 deletions src/Renci.SshNet/Abstractions/DiagnosticAbstraction.cs

This file was deleted.

9 changes: 6 additions & 3 deletions src/Renci.SshNet/BaseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
using System.Threading;
using System.Threading.Tasks;

using Renci.SshNet.Abstractions;
using Microsoft.Extensions.Logging;

using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;

Expand All @@ -20,6 +21,7 @@ public abstract class BaseClient : IBaseClient
/// </summary>
private readonly bool _ownsConnectionInfo;

private readonly ILogger _logger;
private readonly IServiceFactory _serviceFactory;
private readonly object _keepAliveLock = new object();
private TimeSpan _keepAliveInterval;
Expand Down Expand Up @@ -190,6 +192,7 @@ private protected BaseClient(ConnectionInfo connectionInfo, bool ownsConnectionI
_connectionInfo = connectionInfo;
_ownsConnectionInfo = ownsConnectionInfo;
_serviceFactory = serviceFactory;
_logger = SshNetLoggingConfiguration.LoggerFactory.CreateLogger(GetType());
_keepAliveInterval = Timeout.InfiniteTimeSpan;
}

Expand Down Expand Up @@ -343,7 +346,7 @@ public async Task ConnectAsync(CancellationToken cancellationToken)
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
public void Disconnect()
{
DiagnosticAbstraction.Log("Disconnecting client.");
_logger.LogInformation("Disconnecting client.");

CheckDisposed();

Expand Down Expand Up @@ -442,7 +445,7 @@ protected virtual void Dispose(bool disposing)

if (disposing)
{
DiagnosticAbstraction.Log("Disposing client.");
_logger.LogDebug("Disposing client.");

Disconnect();

Expand Down
11 changes: 7 additions & 4 deletions src/Renci.SshNet/Channels/Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
using System.Net.Sockets;
using System.Threading;

using Renci.SshNet.Abstractions;
using Microsoft.Extensions.Logging;

using Renci.SshNet.Common;
using Renci.SshNet.Messages;
using Renci.SshNet.Messages.Connection;
Expand All @@ -14,10 +15,11 @@ namespace Renci.SshNet.Channels
/// </summary>
internal abstract class Channel : IChannel
{
private readonly object _serverWindowSizeLock = new object();
private readonly object _messagingLock = new object();
private readonly Lock _serverWindowSizeLock = new Lock();
private readonly Lock _messagingLock = new Lock();
private readonly uint _initialWindowSize;
private readonly ISession _session;
private readonly ILogger _logger;
private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(initialState: false);
private EventWaitHandle _channelServerWindowAdjustWaitHandle = new ManualResetEvent(initialState: false);
private uint? _remoteWindowSize;
Expand Down Expand Up @@ -81,6 +83,7 @@ protected Channel(ISession session, uint localChannelNumber, uint localWindowSiz
LocalChannelNumber = localChannelNumber;
LocalPacketSize = localPacketSize;
LocalWindowSize = localWindowSize;
_logger = SshNetLoggingConfiguration.LoggerFactory.CreateLogger(GetType());

session.ChannelWindowAdjustReceived += OnChannelWindowAdjust;
session.ChannelDataReceived += OnChannelData;
Expand Down Expand Up @@ -555,7 +558,7 @@ protected virtual void Close()
var closeWaitResult = _session.TryWait(_channelClosedWaitHandle, ConnectionInfo.ChannelCloseTimeout);
if (closeWaitResult != WaitResult.Success)
{
DiagnosticAbstraction.Log(string.Format("Wait for channel close not successful: {0:G}.", closeWaitResult));
_logger.LogInformation("Wait for channel close not successful: {CloseWaitResult}", closeWaitResult);
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions src/Renci.SshNet/Channels/ChannelDirectTcpip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Net.Sockets;
using System.Threading;

using Microsoft.Extensions.Logging;

using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Messages.Connection;
Expand All @@ -14,8 +16,8 @@ namespace Renci.SshNet.Channels
/// </summary>
internal sealed class ChannelDirectTcpip : ClientChannel, IChannelDirectTcpip
{
private readonly object _socketLock = new object();

private readonly Lock _socketLock = new Lock();
private readonly ILogger _logger;
private EventWaitHandle _channelOpen = new AutoResetEvent(initialState: false);
private EventWaitHandle _channelData = new AutoResetEvent(initialState: false);
private IForwardedPort _forwardedPort;
Expand All @@ -31,6 +33,7 @@ internal sealed class ChannelDirectTcpip : ClientChannel, IChannelDirectTcpip
public ChannelDirectTcpip(ISession session, uint localChannelNumber, uint localWindowSize, uint localPacketSize)
: base(session, localChannelNumber, localWindowSize, localPacketSize)
{
_logger = SshNetLoggingConfiguration.LoggerFactory.CreateLogger<ChannelDirectTcpip>();
}

/// <summary>
Expand Down Expand Up @@ -157,8 +160,7 @@ private void ShutdownSocket(SocketShutdown how)
}
catch (SocketException ex)
{
// TODO: log as warning
DiagnosticAbstraction.Log("Failure shutting down socket: " + ex);
_logger.LogInformation(ex, "Failure shutting down socket");
}
}
}
Expand Down
Loading

0 comments on commit 1a7905a

Please sign in to comment.