From cd6715d392b5fd6108a91641b52a38792be954ff Mon Sep 17 00:00:00 2001 From: Jean-Sebastien Carle <29762210+jscarle@users.noreply.github.com> Date: Fri, 15 Mar 2024 15:56:46 -0400 Subject: [PATCH 1/3] Added support for GitHub pages using docfx --- .github/workflows/docs.yml | 48 +++++++ .gitignore | 9 ++ README.md | 4 + docfx/docfx.json | 124 ++++++++++++++++++ docfx/docs/features.md | 102 ++++++++++++++ docfx/docs/foreword.md | 14 ++ docfx/docs/toc.yml | 6 + docfx/docs/usage.md | 34 +++++ docfx/images/icon.png | Bin 0 -> 35449 bytes docfx/images/logo.png | Bin 0 -> 7574 bytes docfx/index.md | 19 +++ docfx/toc.yml | 14 ++ ...yncResult{TResult}.cs => AsyncResult`1.cs} | 2 + 13 files changed, 376 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 docfx/docfx.json create mode 100644 docfx/docs/features.md create mode 100644 docfx/docs/foreword.md create mode 100644 docfx/docs/toc.yml create mode 100644 docfx/docs/usage.md create mode 100644 docfx/images/icon.png create mode 100644 docfx/images/logo.png create mode 100644 docfx/index.md create mode 100644 docfx/toc.yml rename src/Renci.SshNet/Common/{AsyncResult{TResult}.cs => AsyncResult`1.cs} (92%) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..ebcbc7387 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,48 @@ +name: Docs + +on: + push: + branches: ["master"] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Setup .NET 8.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + + - name: Setup docfx + run: dotnet tool update -g docfx + + - name: Build documentation + run: docfx ./docfx/docfx.json + + - name: Upload documentation + uses: actions/upload-pages-artifact@v3 + with: + path: './docfx/_site' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 5311c022d..b174a53f6 100644 --- a/.gitignore +++ b/.gitignore @@ -485,3 +485,12 @@ $RECYCLE.BIN/ # Build outputs build/target/ + +# Docs +docfx/_site/** +docfx/net462/** +docfx/netstandard2.0/** +docfx/netstandard2.1/** +docfx/net6.0/** +docfx/net7.0/** +docfx/net8.0/** diff --git a/README.md b/README.md index 84e665bd9..fd869601d 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,13 @@ SSH.NET is a Secure Shell (SSH-2) library for .NET, optimized for parallelism. [![Build status](https://ci.appveyor.com/api/projects/status/ih77qu6tap3o92gu/branch/develop?svg=true)](https://ci.appveyor.com/api/projects/status/ih77qu6tap3o92gu/branch/develop) ## Introduction + This project was inspired by **Sharp.SSH** library which was ported from java and it seems like was not supported for quite some time. This library is a complete rewrite, without any third party dependencies, using parallelism to achieve the best performance possible. ## Documentation + There is MSDN-style class documentation in a .chm file for each release, which you can find in the Assets section of the [latest release](https://github.com/sshnet/SSH.NET/releases/latest) page. Please note that you will need to [right-click and "unblock"](https://support.microsoft.com/en-us/help/2021383/some-chm-files-may-not-render-properly-on-windows-vista-and-windows-7) @@ -26,6 +28,7 @@ invited to read the source, Luke, and highly encouraged to generate a pull reque the missing test once you figure things out. 🤓 ## Features + * Execution of SSH command using both synchronous and asynchronous methods * Return command execution exit status and other information * Provide SFTP functionality for both synchronous and asynchronous operations @@ -121,6 +124,7 @@ Private keys can be encrypted using one of the following cipher methods: * hmac-sha2-512-etm@openssh.com ## Framework Support + **SSH.NET** supports the following target frameworks: * .NETFramework 4.6.2 (and higher) * .NET Standard 2.0 and 2.1 diff --git a/docfx/docfx.json b/docfx/docfx.json new file mode 100644 index 000000000..1911fe923 --- /dev/null +++ b/docfx/docfx.json @@ -0,0 +1,124 @@ +{ + "metadata": [ + { + "src": [ + { + "src": "../src", + "files": [ + "**/*.csproj" + ] + } + ], + "outputFormat": "apiPage", + "dest": "net462", + "properties": { + "TargetFramework": "net462" + } + }, + { + "src": [ + { + "src": "../src", + "files": [ + "**/*.csproj" + ] + } + ], + "outputFormat": "apiPage", + "dest": "netstandard2.0", + "properties": { + "TargetFramework": "netstandard2.0" + } + }, + { + "src": [ + { + "src": "../src", + "files": [ + "**/*.csproj" + ] + } + ], + "outputFormat": "apiPage", + "dest": "netstandard2.1", + "properties": { + "TargetFramework": "netstandard2.1" + } + }, + { + "src": [ + { + "src": "../src", + "files": [ + "**/*.csproj" + ] + } + ], + "outputFormat": "apiPage", + "dest": "net6.0", + "properties": { + "TargetFramework": "net6.0" + } + }, + { + "src": [ + { + "src": "../src", + "files": [ + "**/*.csproj" + ] + } + ], + "outputFormat": "apiPage", + "dest": "net7.0", + "properties": { + "TargetFramework": "net7.0" + } + }, + { + "src": [ + { + "src": "../src", + "files": [ + "**/*.csproj" + ] + } + ], + "outputFormat": "apiPage", + "dest": "net8.0", + "properties": { + "TargetFramework": "net8.0" + } + } + ], + "build": { + "content": [ + { + "files": "**/*.{md,yml}", + "exclude": [ + "_site/**" + ] + } + ], + "resource": [ + { + "files": [ + "images/**" + ] + } + ], + "output": "_site", + "template": [ + "default", + "modern" + ], + "globalMetadata": { + "_appName": "SSH.NET", + "_appTitle": "SSH.NET - A Secure Shell (SSH) library for .NET, optimized for parallelism", + "_appLogoPath": "images/logo.png", + "_appFaviconPath": "images/icon.png", + "_appFooter": "Copyright (c) Renci, Oleg Kapeljushnik, Gert Driesen and contributors", + "_enableSearch": true + } + } +} diff --git a/docfx/docs/features.md b/docfx/docs/features.md new file mode 100644 index 000000000..229296f53 --- /dev/null +++ b/docfx/docs/features.md @@ -0,0 +1,102 @@ +# Features + +* Execution of SSH command using both synchronous and asynchronous methods +* Return command execution exit status and other information +* Provide SFTP functionality for both synchronous and asynchronous operations +* Provides SCP functionality +* Provide status report for upload and download sftp operations to allow accurate progress bar implementation +* Remote, dynamic and local port forwarding +* Shell/Terminal implementation +* Specify key file pass phrase +* Use multiple key files to authenticate +* Supports publickey, password and keyboard-interactive authentication methods +* Supports two-factor or higher authentication +* Supports SOCKS4, SOCKS5 and HTTP Proxy + +## Encryption Method + +**SSH.NET** supports the following encryption methods: +* aes256-ctr +* 3des-cbc +* aes128-cbc +* aes192-cbc +* aes256-cbc +* blowfish-cbc +* twofish-cbc +* twofish192-cbc +* twofish128-cbc +* twofish256-cbc +* arcfour +* arcfour128 +* arcfour256 +* cast128-cbc +* aes128-ctr +* aes192-ctr + +## Key Exchange Method + +**SSH.NET** supports the following key exchange methods: +* curve25519-sha256 +* curve25519-sha256@libssh.org +* ecdh-sha2-nistp256 +* ecdh-sha2-nistp384 +* ecdh-sha2-nistp521 +* diffie-hellman-group-exchange-sha256 +* diffie-hellman-group-exchange-sha1 +* diffie-hellman-group16-sha512 +* diffie-hellman-group14-sha256 +* diffie-hellman-group14-sha1 +* diffie-hellman-group1-sha1 + +## Public Key Authentication + +**SSH.NET** supports the following private key formats: +* RSA in OpenSSL PEM and ssh.com format +* DSA in OpenSSL PEM and ssh.com format +* ECDSA 256/384/521 in OpenSSL PEM format +* ECDSA 256/384/521, ED25519 and RSA in OpenSSH key format + +Private keys can be encrypted using one of the following cipher methods: +* DES-EDE3-CBC +* DES-EDE3-CFB +* DES-CBC +* AES-128-CBC +* AES-192-CBC +* AES-256-CBC + +## Host Key Algorithms + +**SSH.NET** supports the following host key algorithms: +* ssh-ed25519 +* ecdsa-sha2-nistp256 +* ecdsa-sha2-nistp384 +* ecdsa-sha2-nistp521 +* rsa-sha2-512 +* rsa-sha2-256 +* ssh-rsa +* ssh-dss + +## Message Authentication Code + +**SSH.NET** supports the following MAC algorithms: +* hmac-md5 +* hmac-md5-96 +* hmac-sha1 +* hmac-sha1-96 +* hmac-sha2-256 +* hmac-sha2-256-96 +* hmac-sha2-512 +* hmac-sha2-512-96 +* hmac-md5-etm@openssh.com +* hmac-md5-96-etm@openssh.com +* hmac-sha1-etm@openssh.com +* hmac-sha1-96-etm@openssh.com +* hmac-sha2-256-etm@openssh.com +* hmac-sha2-512-etm@openssh.com + +## Framework Support + +**SSH.NET** supports the following target frameworks: +* .NETFramework 4.6.2 (and higher) +* .NET Standard 2.0 and 2.1 +* .NET 6 (and higher) diff --git a/docfx/docs/foreword.md b/docfx/docs/foreword.md new file mode 100644 index 000000000..574c20572 --- /dev/null +++ b/docfx/docs/foreword.md @@ -0,0 +1,14 @@ +# Foreword + +There is MSDN-style class documentation in a .chm file for each release, which you can find in the Assets section +of the [latest release](https://github.com/sshnet/SSH.NET/releases/latest) page. Please note that you will need +to [right-click and "unblock"](https://support.microsoft.com/en-us/help/2021383/some-chm-files-may-not-render-properly-on-windows-vista-and-windows-7) +the CHM file after you download it. + +Currently (4/18/2020), the documentation is very sparse. Fortunately, there are a large number of tests in +[Renci.SshNet.Tests](https://github.com/sshnet/SSH.NET/tree/develop/test/Renci.SshNet.Tests) that demonstrate +usage with working code. + +If the test for the functionality you would like to see documented is not complete, then you are cordially +invited to read the source, Luke, and highly encouraged to generate a pull request for the implementation of +the missing test once you figure things out. 🤓 diff --git a/docfx/docs/toc.yml b/docfx/docs/toc.yml new file mode 100644 index 000000000..35a71c825 --- /dev/null +++ b/docfx/docs/toc.yml @@ -0,0 +1,6 @@ +- name: Foreword + href: foreword.md +- name: Features + href: features.md +- name: Usage + href: usage.md diff --git a/docfx/docs/usage.md b/docfx/docs/usage.md new file mode 100644 index 000000000..e7d9bec03 --- /dev/null +++ b/docfx/docs/usage.md @@ -0,0 +1,34 @@ +# Usage + +## Multi-factor authentication + +Establish a SFTP connection using both password and public-key authentication: + +```cs +var connectionInfo = new ConnectionInfo("sftp.foo.com", + "guest", + new PasswordAuthenticationMethod("guest", "pwd"), + new PrivateKeyAuthenticationMethod("rsa.key")); +using (var client = new SftpClient(connectionInfo)) +{ + client.Connect(); +} + +``` + +## Verify host identify + +Establish a SSH connection using user name and password, and reject the connection if the fingerprint of the server does not match the expected fingerprint: + +```cs +string expectedFingerPrint = "LKOy5LvmtEe17S4lyxVXqvs7uPMy+yF79MQpHeCs/Qo"; + +using (var client = new SshClient("sftp.foo.com", "guest", "pwd")) +{ + client.HostKeyReceived += (sender, e) => + { + e.CanTrust = expectedFingerPrint.Equals(e.FingerPrintSHA256); + }; + client.Connect(); +} +``` diff --git a/docfx/images/icon.png b/docfx/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3e993a7494f5fc64219927e8aed6ec08323317c8 GIT binary patch literal 35449 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 Pn#w@uET#x;8~(ol)-^gs literal 0 HcmV?d00001 diff --git a/docfx/index.md b/docfx/index.md new file mode 100644 index 000000000..da3c1be30 --- /dev/null +++ b/docfx/index.md @@ -0,0 +1,19 @@ +--- +_layout: landing +--- + +SSH.NET is a Secure Shell (SSH-2) library for .NET, optimized for parallelism. + +[![Version](https://img.shields.io/nuget/vpre/SSH.NET.svg)](https://www.nuget.org/packages/SSH.NET) +[![NuGet download count](https://img.shields.io/nuget/dt/SSH.NET.svg)](https://www.nuget.org/packages/SSH.NET) +[![Build status](https://ci.appveyor.com/api/projects/status/ih77qu6tap3o92gu/branch/develop?svg=true)](https://ci.appveyor.com/api/projects/status/ih77qu6tap3o92gu/branch/develop) + +## Introduction + +This project was inspired by **Sharp.SSH** library which was ported from java and it seems like was not supported +for quite some time. This library is a complete rewrite, without any third party dependencies, using parallelism +to achieve the best performance possible. + +## Supporting SSH.NET + +Do you or your company rely on **SSH.NET** in your projects? If you want to encourage us to keep on going and show us that you appreciate our work, please consider becoming a [sponsor](https://github.com/sponsors/sshnet) through GitHub Sponsors. diff --git a/docfx/toc.yml b/docfx/toc.yml new file mode 100644 index 000000000..575116eeb --- /dev/null +++ b/docfx/toc.yml @@ -0,0 +1,14 @@ +- name: Docs + href: docs/ +- name: .NET Framework 4.6.2 + href: net462/ +- name: .NET Standard 2.0 + href: netstandard2.0/ +- name: .NET Standard 2.1 + href: netstandard2.1/ +- name: .NET 6.0 + href: net6.0/ +- name: .NET 7.0 + href: net7.0/ +- name: .NET 8.0 + href: net8.0/ diff --git a/src/Renci.SshNet/Common/AsyncResult{TResult}.cs b/src/Renci.SshNet/Common/AsyncResult`1.cs similarity index 92% rename from src/Renci.SshNet/Common/AsyncResult{TResult}.cs rename to src/Renci.SshNet/Common/AsyncResult`1.cs index b5ab54122..bac2c4cd9 100644 --- a/src/Renci.SshNet/Common/AsyncResult{TResult}.cs +++ b/src/Renci.SshNet/Common/AsyncResult`1.cs @@ -6,7 +6,9 @@ namespace Renci.SshNet.Common /// Base class to encapsulates the results of an asynchronous operation that returns result. /// /// The type of the result. +#pragma warning disable SA1649 // Normal convention is to name generic files `1, naming this AsyncResult{TResult}.cs breaks docfx. public abstract class AsyncResult : AsyncResult +#pragma warning restore SA1649 { // Field set when operation completes private TResult _result; From cd2b1b1136a4cfc5eff1c724f6a157f2d1f351d0 Mon Sep 17 00:00:00 2001 From: Jean-Sebastien Carle <29762210+jscarle@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:01:23 -0400 Subject: [PATCH 2/3] Fixed StyleCop warning. --- src/Renci.SshNet/Common/AsyncResult`1.cs | 2 -- stylecop.json | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Renci.SshNet/Common/AsyncResult`1.cs b/src/Renci.SshNet/Common/AsyncResult`1.cs index bac2c4cd9..b5ab54122 100644 --- a/src/Renci.SshNet/Common/AsyncResult`1.cs +++ b/src/Renci.SshNet/Common/AsyncResult`1.cs @@ -6,9 +6,7 @@ namespace Renci.SshNet.Common /// Base class to encapsulates the results of an asynchronous operation that returns result. /// /// The type of the result. -#pragma warning disable SA1649 // Normal convention is to name generic files `1, naming this AsyncResult{TResult}.cs breaks docfx. public abstract class AsyncResult : AsyncResult -#pragma warning restore SA1649 { // Field set when operation completes private TResult _result; diff --git a/stylecop.json b/stylecop.json index ff7c9dbfb..ba2a35715 100644 --- a/stylecop.json +++ b/stylecop.json @@ -3,7 +3,8 @@ "settings": { "documentationRules": { "xmlHeader": false, - "documentInternalElements": false + "documentInternalElements": false, + "fileNamingConvention": "metadata" }, "layoutRules": { "newlineAtEndOfFile": "require" From 8efa73dabfda21d6d25b3d5f415df2186982f150 Mon Sep 17 00:00:00 2001 From: Jean-Sebastien Carle <29762210+jscarle@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:40:40 -0400 Subject: [PATCH 3/3] Fixed other StyleCop warnings. --- src/Renci.SshNet/{MessageEventArgs.cs => MessageEventArgs`1.cs} | 0 .../Common/{ArrayBuilder.cs => ArrayBuilder`1.cs} | 0 .../Common/{ArrayBuilder.cs => ArrayBuilder`1.cs} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/Renci.SshNet/{MessageEventArgs.cs => MessageEventArgs`1.cs} (100%) rename test/Renci.SshNet.IntegrationTests/Common/{ArrayBuilder.cs => ArrayBuilder`1.cs} (100%) rename test/Renci.SshNet.Tests/Common/{ArrayBuilder.cs => ArrayBuilder`1.cs} (100%) diff --git a/src/Renci.SshNet/MessageEventArgs.cs b/src/Renci.SshNet/MessageEventArgs`1.cs similarity index 100% rename from src/Renci.SshNet/MessageEventArgs.cs rename to src/Renci.SshNet/MessageEventArgs`1.cs diff --git a/test/Renci.SshNet.IntegrationTests/Common/ArrayBuilder.cs b/test/Renci.SshNet.IntegrationTests/Common/ArrayBuilder`1.cs similarity index 100% rename from test/Renci.SshNet.IntegrationTests/Common/ArrayBuilder.cs rename to test/Renci.SshNet.IntegrationTests/Common/ArrayBuilder`1.cs diff --git a/test/Renci.SshNet.Tests/Common/ArrayBuilder.cs b/test/Renci.SshNet.Tests/Common/ArrayBuilder`1.cs similarity index 100% rename from test/Renci.SshNet.Tests/Common/ArrayBuilder.cs rename to test/Renci.SshNet.Tests/Common/ArrayBuilder`1.cs