All Versions
20
Latest Version
Avg Release Cycle
180 days
Latest Release
228 days ago

Changelog History
Page 1

  • v2025.1.0 Changes

    October 27, 2025

    Highlights

    • โž• Add DownloadFileAsync and UploadFileAsync to SftpClient (#1634)
    • ๐ŸŽ Much improved performance of SftpFileStream in consecutive read (e.g. SftpFileStream.CopyTo) scenarios (#1705)

    ๐Ÿ’ฅ Breaking changes:

    • ๐Ÿ”€ SftpFileStream previously had some incomplete synchronisation for multi-threaded access, but was not advertised nor fully functioning as thread safe. This synchronisation was removed in #1705. When accessing an SftpFileStream instance from multiple threads simultaneously, ensure there exists appropriate synchronisation.
    • SftpClient.CreateText and WriteAll{Bytes/Text/Lines} were changed in #1686 to truncate the file before writing if it exists, to align with the equivalent methods on System.IO.File. Given that the prior behaviour was 14 years old, the change treads the line between breaking change and bug fix.
    • โšก๏ธ IEnumerable<string> ReadLines on SftpClient was updated in #1681 to download and yield lines during enumeration rather than reading them all up front and returning the result. This means that the connection must be active during enumeration. When storing the result of ReadLines for later use, consider using string[] ReadAllLines instead.

    What's Changed

    • ๐Ÿ”– Version 2025.0.0 by @Rob-Hague in #1631
    • โž• Add a debug helper for reading traffic with Wireshark by @Rob-Hague in #1627
    • โšก๏ธ Update docs and remove a leftover DSA certificate algorithm by @Rob-Hague in #1632
    • Override more methods in PipeStream, ShellStream by @Rob-Hague in #1637
    • Read the underlying buffer in SshDataStream by @Rob-Hague in #1638
    • โž• Add UploadFileAsync and DownloadFileAsync methods by @sdt-ndelarosa in #1634
    • ๐Ÿ›  fix IDE0350 warnings with .NET SDK 9.0.300 by @mus65 in #1645
    • Re-introduce ChangeWindow method on ShellStream by @Rasmus715 in #1646
    • ๐Ÿ›  Fix hang in SftpClient.UploadFile upon error by @Rob-Hague in #1643
    • โฌ‡๏ธ Drop netstandard2.1 target by @mus65 in #1647
    • โž• Added GetAttributesAsync to SftpClient by @deckertron9000 in #1648
    • โฌ†๏ธ Bump alpine from 3.21 to 3.22 in /test/Renci.SshNet.IntegrationTests by @dependabot[bot] in #1651
    • โฌ†๏ธ Bump dependencies by @dependabot[bot] in #1652
    • Check host key algorithms before continuing key exchange by @Rob-Hague in #1642
    • ๐Ÿ‘‰ Use an array buffer for the sftp packet stream by @Rob-Hague in #1649
    • ๐Ÿ‘‰ Use ArraySegment for channel data by @Rob-Hague in #1650
    • scp: add flag to notify for uploading finished when uploaded an empty file by @thegame4craft in #1658
    • ๐Ÿ›  Fixes spelling errors by @jacobslusser in #1668
    • โšก๏ธ Bump the dependencies group with 5 updates by @dependabot[bot] in #1663
    • ๐Ÿ”จ Refactor logging to allow a loggerfactory per session by @desdesdes in #1673
    • Adapt InternalUploadFile for async by @Rob-Hague in #1653
    • ๐Ÿ‘‰ Use BouncyCastle for Diffie-Hellman key exchange by @Rob-Hague in #1654
    • โœ‚ Remove unnecessary SftpFileStream unit tests and dedup Open{Async} by @Rob-Hague in #1680
    • โฌ†๏ธ Bump Vampire/setup-wsl from 5.0.1 to 6.0.0 by @dependabot[bot] in #1683
    • ๐Ÿ‘‰ Use ReadExactly in ReadAllBytes and yield in ReadLines by @Rob-Hague in #1681
    • โšก๏ธ Bump the dependencies group with 4 updates by @dependabot[bot] in #1682
    • Truncate existing file in CreateText by @Rob-Hague in #1686
    • ๐Ÿ›  Fix key material extension during key exchange by @Rob-Hague in #1689
    • โฌ†๏ธ Bump actions/checkout from 4 to 5 by @dependabot[bot] in #1693
    • ๐Ÿ Use BCL Curve25519 for Windows 10+ by @scott-xu in #1702
    • โœ‚ Remove calls to Socket.Poll and use SocketShutdown.Both by @Rob-Hague in #1706
    • ๐Ÿ›  Fix SftpFileAttributes file type detection by @Rob-Hague in #1688
    • ๐Ÿ CI: add Windows Integration Tests for .NET by @mus65 in #1704
    • โฑ Avoid rounding issues when checking Timeout values (#1700) by @nikolamilekic in #1712
    • ๐Ÿ— Build the read-ahead mechanism into SftpFileStream by @Rob-Hague in #1705
    • โž• Add SftpException and SftpPathNotFoundException.Path by @Rob-Hague in #1716
    • Internal cleanup in SftpSession by @Rob-Hague in #1717
    • Override WriteAsync in ShellStream by @Rob-Hague in #1711
    • ๐Ÿ›  Fix typos in comments: "lenght" โ†’ "length" and "occured" โ†’ "occurred" by @Copilot in #1719
    • Automatically publish tags to NuGet with Trusted Publishing by @mus65 in #1715
    • Set version to 2025.1.0 stable by @Rob-Hague in #1722

    ๐Ÿ†• New Contributors

    Full Changelog : 2025.0.0...2025.1.0

    API diff

    namespace Renci.SshNet
      {
          public class ConnectionInfo
          {+ public Microsoft.Extensions.Logging.ILoggerFactory? LoggerFactory { get; set; }}
          public interface ISftpClient : Renci.SshNet.IBaseClient
          {+ System.Threading.Tasks.Task DownloadFileAsync(string path, System.IO.Stream output, System.Threading.CancellationToken cancellationToken = default);+ System.Threading.Tasks.Task\<Renci.SshNet.Sftp.SftpFileAttributes\> GetAttributesAsync(string path, System.Threading.CancellationToken cancellationToken);+ System.Threading.Tasks.Task UploadFileAsync(System.IO.Stream input, string path, System.Threading.CancellationToken cancellationToken = default);}
          public class SftpClient : Renci.SshNet.BaseClient, Renci.SshNet.ISftpClient, Renci.SshNet.IBaseClient
          {+ public System.Threading.Tasks.Task DownloadFileAsync(string path, System.IO.Stream output, System.Threading.CancellationToken cancellationToken = default);+ public System.Threading.Tasks.Task\<Renci.SshNet.Sftp.SftpFileAttributes\> GetAttributesAsync(string path, System.Threading.CancellationToken cancellationToken);+ public System.Threading.Tasks.Task UploadFileAsync(System.IO.Stream input, string path, System.Threading.CancellationToken cancellationToken = default);}
          public sealed class ShellStream
          {+ public void ChangeWindowSize(uint columns, uint rows, uint width, uint height);}
      }
      namespace Renci.SshNet.Common
      {
          public class SftpPathNotFoundException : Renci.SshNet.Common.SftpException
          {+ public SftpPathNotFoundException(string? message, string? path, System.Exception? innerException);+ public SftpPathNotFoundException(string? message, string? path);+ public string? Path { get; }}+ public class SftpException : Renci.SshNet.Common.SshException+ {+ public SftpException(Renci.SshNet.Sftp.StatusCode statusCode, string? message, System.Exception? innerException);+ public SftpException(Renci.SshNet.Sftp.StatusCode statusCode, string? message);+ public SftpException(Renci.SshNet.Sftp.StatusCode statusCode);+ public Renci.SshNet.Sftp.StatusCode StatusCode { get; }+ }}
      namespace Renci.SshNet.Security
      {+ public class KeyExchangeDiffieHellman : Renci.SshNet.Security.KeyExchange+ {+ public KeyExchangeDiffieHellman(string name, Org.BouncyCastle.Crypto.Parameters.DHParameters parameters, System.Security.Cryptography.HashAlgorithmName hashAlgorithm);+ public override void Start(Renci.SshNet.Session session, Renci.SshNet.Messages.Transport.KeyExchangeInitMessage message, bool sendClientInitMessage);+ public override string Name { get; }+ }+ public class KeyExchangeDiffieHellmanGroupExchange : Renci.SshNet.Security.KeyExchange+ {+ public KeyExchangeDiffieHellmanGroupExchange(string name, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, uint minimumGroupSize, uint preferredGroupSize, uint maximumGroupSize);+ public KeyExchangeDiffieHellmanGroupExchange(string name, System.Security.Cryptography.HashAlgorithmName hashAlgorithm);+ public override void Start(Renci.SshNet.Session session, Renci.SshNet.Messages.Transport.KeyExchangeInitMessa...
    
  • v2025.0.0 Changes

    April 18, 2025

    Highlights

    • โž• Add support for post-quantum key exchange methods sntrup761x25519-sha512 and mlkem768x25519-sha256
    • โž• Add support for PuTTY private key files
    • โž• Add logging capability via Microsoft.Extensions.Logging

    ๐Ÿ’ฅ Breaking changes

    • ๐Ÿ‘Œ Support for DSA was dropped in #1558
    • CipherPadding was deleted in #1546 and uses replaced with Org.BouncyCastle.Crypto.Paddings.IBlockCipherPadding
    • ๐Ÿ‘€ See the full API diff at the end

    What's Changed

    • โฌ†๏ธ Bump version by @Rob-Hague in #1533
    • ๐Ÿ›  fix Package Downgrade Warning with .NET 9 SDK by @mus65 in #1538
    • โšก๏ธ Update PrivateKeyFile.cs by @scott-xu in #1541
    • ๐Ÿ– Handle lower-case hex in private key's salt field by @RiJo in #179
    • Split PrivateKeyFile into different implementations. by @scott-xu in #1542
    • Migrate from AppVeyor to GitHub Actions by @mus65 in #1539
    • โž• Add .NET 9 target by @mus65 in #1480
    • โœ‚ Remove appveyor.yml by @mus65 in #1547
    • ๐ŸŒฒ Replace DiagnosticAbstration with Microsoft.Extensions.Logging.Abstractions by @mus65 in #1509
    • ๐Ÿ‘ [Private Key] Add support for PuTTY private key file format (V3 and V2) by @scott-xu in #1543
    • ๐Ÿ›  fix newline characters in comment by @Varorbc in #1550
    • ๐Ÿง Pin Alpine Linux image to 3.20 by @Rob-Hague in #1554
    • ๐Ÿ›  Fix consumption of NBGV version properties in build by @Rob-Hague in #1544
    • โฌ‡๏ธ Drop net7.0 target by @Rob-Hague in #1468
    • โž• Add padding when encrypt and remove padding when decrypt by @scott-xu in #1545
    • ๐Ÿ”’ Use System.Security.Cryptography for TripleDesCipher by @scott-xu in #1546
    • ๐Ÿ‘ [PQC] Add support for sntrup761x25519-sha512 key exchange method by @scott-xu in #1562
    • โฌ‡๏ธ Drop DSA by @Rob-Hague in #1558
    • ๐Ÿณ Create dependabot.yml for docker image by @Rob-Hague in #1559
    • ๐Ÿ›  Fix hang/unhandled exception in SshCommand upon disconnect by @Rob-Hague in #1565
    • โฌ†๏ธ Bump alpine from 3.20 to 3.21 in /test/Renci.SshNet.IntegrationTests by @dependabot in #1567
    • ๐Ÿ‘ [PQC] Add support for mlkem768x25519-sha256 key exchange method by @scott-xu in #1563
    • ๐Ÿšš Move IDisposable implementation declaration from inheritees to parent by @bad-samaritan in #746
    • โšก๏ธ Update bound port on ForwardedPortDynamic after connection (in case original was passed as zero) by @timyhac in #1577
    • โšก๏ธ Configure Dependabot to also update NuGet and GitHub Actions by @mus65 in #1581
    • โฌ†๏ธ Bump Microsoft.NET.Test.Sdk from 17.11.1 to 17.12.0 by @dependabot in #1585
    • โฌ†๏ธ Bump actions/configure-pages from 4 to 5 by @dependabot in #1582
    • ๐Ÿ›  fix: UnhandledException: System.ObjectDisposedException. by @SoftStoneDevelop in #1590
    • โฌ†๏ธ Bump test dependencies by @dependabot in #1583
    • ๐ŸŒฒ Tweak logging.md by @Rob-Hague in #1601
    • Reply to global requests when want_reply is true by @Rob-Hague in #1600
    • Don't dispose channel when completing SshCommand by @Rob-Hague in #1596
    • โฌ‡๏ธ Drop net6.0 target by @mus65 in #1580
    • โœ‚ remove Reverse extension to avoid source-breaking change with .NET 10 by @mus65 in #1606
    • โšก๏ธ Bump the dependencies group with 7 updates by @dependabot in #1607
    • ๐Ÿ CI: run .NET Framework Integration Tests on Windows by @mus65 in #1615
    • ๐Ÿ›  Fix API break on KeyExchange by @Rob-Hague in #1609
    • โž• Add a Stream buffer validation helper by @Rob-Hague in #1605
    • โž• Add an OrderedDictionary implementation for algorithm priorities by @Rob-Hague in #1611
    • ๐Ÿ”’ lock SendData to fix random connection failures by @mus65 in #1623
    • ๐Ÿš€ Only enable TreatWarningsAsErrors in Release by @mus65 in #1624
    • โœ‚ Remove unused bcrypt password hashing code by @mus65 in #1626
    • โšก๏ธ Bump the dependencies group with 5 updates by @dependabot in #1625
    • โž• Added ExistsAsync and GetAsync to ISftpClient by @Maarty in #1628

    ๐Ÿ†• New Contributors

    Full Changelog : 2024.2.0...2025.0.0

    API diff

    namespace Renci.SshNet
      {
          public abstract class AuthenticationMethod
          {+ public void Dispose();+ protected virtual void Dispose(bool disposing);}
          public class ConnectionInfo
          {- public System.Collections.Generic.IDictionary\<string, System.Func\<Renci.SshNet.Compression.Compressor\>\> CompressionAlgorithms { get; }+ public Renci.SshNet.IOrderedDictionary\<string, System.Func\<Renci.SshNet.Compression.Compressor\>\> CompressionAlgorithms { get; }- public System.Collections.Generic.IDictionary\<string, Renci.SshNet.CipherInfo\> Encryptions { get; }+ public Renci.SshNet.IOrderedDictionary\<string, Renci.SshNet.CipherInfo\> Encryptions { get; }- public System.Collections.Generic.IDictionary\<string, Renci.SshNet.HashInfo\> HmacAlgorithms { get; }+ public Renci.SshNet.IOrderedDictionary\<string, Renci.SshNet.HashInfo\> HmacAlgorithms { get; }- public System.Collections.Generic.IDictionary\<string, System.Func\<byte[], Renci.SshNet.Security.KeyHostAlgorithm\>\> HostKeyAlgorithms { get; }+ public Renci.SshNet.IOrderedDictionary\<string, System.Func\<byte[], Renci.SshNet.Security.KeyHostAlgorithm\>\> HostKeyAlgorithms { get; }- public System.Collections.Generic.IDictionary\<string, System.Func\<Renci.SshNet.Security.IKeyExchange\>\> KeyExchangeAlgorithms { get; }+ public Renci.SshNet.IOrderedDictionary\<string, System.Func\<Renci.SshNet.Security.IKeyExchange\>\> KeyExchangeAlgorithms { get; }}
          public interface ISftpClient : Renci.SshNet.IBaseClient
          {+ System.Threading.Tasks.Task\<bool\> ExistsAsync(string path, System.Threading.CancellationToken cancellationToken = null);+ System.Threading.Tasks.Task\<Renci.SshNet.Sftp.ISftpFile\> GetAsync(string path, System.Threading.CancellationToken cancellationToken);}
          public class KeyboardInteractiveAuthenticationMethod : Renci.SshNet.AuthenticationMethod
          {- public void Dispose();- protected virtual void Dispose(bool disposing);+ protected override void Dispose(bool disposing);}
          public class NoneAuthenticationMethod : Renci.SshNet.AuthenticationMethod
          {- public void Dispose();- protected virtual void Dispose(bool disposing);+ protected override void Dispose(bool disposing);}
          public class PasswordAuthenticationMethod : Renci.SshNet.AuthenticationMethod
          {- public void Dispose();- protected virtual void Dispose(bool disposing);+ protected override void Dispose(bool disposing);}
          public class PrivateKeyAuthenticationMethod : Renci.SshNet.AuthenticationMethod
          {- public void Dispose();- protected virtual void Dispose(bool disposing);+ protected override void Dispose(bool disposing);}+ public interface IOrderedDictionary\<TKey, TValue\> : IDictionary\<TKey, TValue\>, IReadOnlyDictionary\<TKey, TValue\>+ {+ bool ContainsKey(TKey key);+ bool ContainsValue(TValue value);+ System.Collections.Generic.KeyValuePair\<TKey, TValue\> GetAt(int index);+ int IndexOf(TKey key);+ void Insert(int index, TKey key, TValue value);+ bool Remove(TKey key, out TValue value);+ void RemoveAt(int index);+ void SetAt(int index, TKey key, TValue value);+ void SetAt(int index, TValue value);+ void SetPosition(TKey key, int newIndex);+ void SetPosition(int index, int newIndex);+ bool TryAdd(TKey key, TValue value, out int index);+ bool TryAdd(TKey key, TValue value);+ bool TryGetValue(TKey key, out TValue value, out int index);+ bool TryGetValue(TKey key, out TValue value);+ int Count { get; }+ TValue this[TKey key] { get; set; }+ ...
    
  • v2024.2.0 Changes

    November 11, 2024

    ๐Ÿ†• New features

    • โž• Add support for PKCS#8 private key files
    • โž• Add additional async overloads on SftpClient
    • โž• Add support for OpenSSH certificates
    • โž• Add support for chacha20-poly1305@openssh.com cipher algorithm
    • ๐Ÿ‘ Increase support for aes*-gcm@openssh.com and zlib@openssh.com on lower targets

    ๐Ÿš€ This release takes a dependency on BouncyCastle in an effort to eliminate primitive crypto code from the library. It also takes a dependency on System.Formats.Asn1 on lower targets.

    ๐Ÿ’ฅ Breaking changes

    • A number of legacy algorithms were dropped in #1442
    • ๐Ÿ‘€ The implementation of DSA was changed from using handwritten code to using System.Cryptography in #1458. See the PR description for behaviour changes this could cause.
    • Renci.SshNet.Common.BigInteger was deleted and its uses replaced with System.Numerics.BigInteger in #1469
    • Renci.SshNet.Common.DerData and Renci.SshNet.Common.ObjectIdentifier were deleted in #1490 and uses replaced with System.Formats.Asn1
    • ๐Ÿ‘€ See the full API diff at the end

    What's Changed

    • ๐Ÿ‘‰ Make ZlibOpenSsh public by @Rob-Hague in #1433
    • ๐Ÿ“„ Docs updates by @Rob-Hague in #1432
    • Ref System.Memory for net462 and netstandard2.0 by @scott-xu in #1417
    • โœ‚ Remove some #ifdefs with System.Memory by @Rob-Hague in #1434
    • ๐Ÿ‘ Allow empty softwareversion string (#822) by @doerig in #1441
    • โš  .NET 9: don't treat NuGet audit Warnings as Errors and fix warning by @mus65 in #1443
    • โœ… Stabilise some more tests by @Rob-Hague in #1438
    • ๐Ÿ“ฆ Replace internal BouncyCastle with NuGet package by @mus65 in #1370
    • โฌ‡๏ธ Drop legacy algorithms part 1 by @Rob-Hague in #1442
    • Clean up Abstractions / use HashData by @mus65 in #1451
    • [Curve25519] Use BouncyCastle instead of Chaos.NaCl by @scott-xu in #1447
    • [Ed25519] Use BouncyCastle instead of Chaos.NaCl by @scott-xu in #1448
    • โœ‚ Remove Chaos.Nacl by @scott-xu in #1455
    • ๐Ÿ‘ [Zlib] Falls back to use BouncyCastle if BCL doesn't support by @scott-xu in #1453
    • โž• Add support for AEAD ChaCha20Poly1305 Cipher by @scott-xu in #1416
    • โ†” Integrate with Nerdbank.GitVersioning by @scott-xu in #1299
    • ๐Ÿ‘‰ Use BCL ECDiffieHellman for KeyExchange instead of BouncyCastle (.NET 8.0 onward only) by @scott-xu in #1371
    • โœ… Enable all net48 integration tests and stabilise tests by @scott-xu in #1456
    • โช Revert mono/.NET Framework integration tests by @Rob-Hague in #1462
    • โž• Add another allowed SocketError value in tests by @Rob-Hague in #1457
    • ๐Ÿ”’ Use System.Security.Cryptography for DSA by @Rob-Hague in #1458
    • ๐Ÿ‘‰ Use ExceptionDispatchInfo to retain call stack in AsyncResult.EndInvoke() by @scott-xu in #1470
    • โœ… Port shared tests folder by @Rob-Hague in #1467
    • ๐Ÿ‘ [AesGcm] Falls back to use BouncyCastle if BCL doesn't support by @scott-xu in #1450
    • ๐Ÿ— another .NET 9 SDK Build fix by @mus65 in #1475
    • ๐Ÿ‘ [ECDsa] Falls back to use BouncyCastle if BCL (Mono) doesn't support by @scott-xu in #1461
    • ๐Ÿ‘‰ Use System.Numerics.BigInteger by @Rob-Hague in #1469
    • โœ‚ Remove unnecessary finalizers by @Rob-Hague in #1209
    • ๐Ÿ›  fix "client not connected" after SFTP reconnect by @mus65 in #1484
    • ๐Ÿ‘ [Private Key] Support more ciphers for OpenSSH private key decryption by @scott-xu in #1487
    • ๐Ÿ“ฆ Migrate to NuGet Central Package Management by @mus65 in #1488
    • ๐Ÿ“ฆ Ref System.Formats.Asn1 nuget package by @scott-xu in #1490
    • โšก๏ธ Update dependencies by @mus65 in #1492
    • Miscellaneous cleanup/throw helpers by @Rob-Hague in #1491
    • โšก๏ธ Update SonarAnalyzer.CSharp by @mus65 in #1494
    • โž• Add support for OpenSSL PKCS#8 private key format by @scott-xu in #1496
    • โž• Add interface to SshClient by @eugencowie in #1499
    • โž• Added ExistsAsync and GetAsync to SftpClient by @snargledorf in #1501
    • ๐Ÿ›  fix ConnectAsync not respecting the connection timeout by @mus65 in #1502
    • โž• Added ChangeDirectoryAsync to SftpClient by @snargledorf in #1504
    • โž• Added CreateDirectoryAsync to SftpClient by @snargledorf in #1505
    • โž• Added support for deleting directories asynchronously by @snargledorf in #1503
    • ๐Ÿ›  Fix sftp async methods not observing error conditions by @Rob-Hague in #1510
    • โž• Add support for OpenSSH certificates by @Rob-Hague in #1498
    • Swallow ObjectDisposed on SFTP wait handle when receiving late response by @Rob-Hague in #1531
    • โฌ†๏ธ Bump test dependencies by @Rob-Hague in #1532

    ๐Ÿ†• New Contributors

    Full Changelog : 2024.1.0...2024.2.0

    API diff

    namespace Renci.SshNet
    {
         public interface IBaseClient : System.IDisposable
         {+ event System.EventHandler\<Renci.SshNet.Common.SshIdentificationEventArgs\>? ServerIdentificationReceived;}
    
         public interface ISftpClient : Renci.SshNet.IBaseClient, System.IDisposable
         {+ System.Threading.Tasks.Task ChangeDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default);+ System.Threading.Tasks.Task CreateDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default);+ System.Threading.Tasks.Task DeleteAsync(string path, System.Threading.CancellationToken cancellationToken = default);+ System.Threading.Tasks.Task DeleteDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default);}+ public interface ISshClient : Renci.SshNet.IBaseClient, System.IDisposable+ {+ System.Collections.Generic.IEnumerable\<Renci.SshNet.ForwardedPort\> ForwardedPorts { get; }+ void AddForwardedPort(Renci.SshNet.ForwardedPort port);+ Renci.SshNet.SshCommand CreateCommand(string commandText);+ Renci.SshNet.SshCommand CreateCommand(string commandText, System.Text.Encoding encoding);+ Renci.SshNet.Shell CreateShell(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput);+ Renci.SshNet.Shell CreateShell(System.Text.Encoding encoding, string input, System.IO.Stream output, System.IO.Stream extendedOutput);+ Renci.SshNet.Shell CreateShell(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary\<Renci.SshNet.Common.TerminalModes, uint\> terminalModes);+ Renci.SshNet.Shell CreateShell(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary\<Renci.SshNet.Common.TerminalModes, uint\>? terminalModes, int bufferSize);+ Renci.SshNet.Shell CreateShell(System.Text.Encoding encoding, string input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary\<Renci.SshNet.Common.TerminalModes, uint\> terminalModes);+ Renci.SshNet.Shell CreateShell(System.Text.Encoding encoding, string input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary\<Renci.SshNet.Common.TerminalModes, uint\>? terminalModes, int bufferSize);+ Renci.SshNet.Shell CreateShellNoTerminal(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput, int bufferSize = -1);+ Renci.SshNet.ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize);+ Renci.SshNet.ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize, System.Collections.Generic.IDictionary\<Renci.SshNet.Common.TerminalModes, uint\>? terminalModeValues);+ Renci.SshNet.ShellStream CreateShellStreamNoTerminal(int bufferSize = -1);+ void RemoveForwardedPort(Renci.SshNet.ForwardedPort port);+ Renci.SshNet.SshCommand RunCommand(string commandText);+ }public class PrivateKeyConnectionInfo : ...
    
  • v2024.1.0 Changes

    June 28, 2024

    ๐Ÿ†• New features:

    • โž• Add support for aes*-gcm@openssh.com cipher algorithms on .NET 6+
    • โž• Add cancellation of SshCommand via signals
    • โž• Add SshCommand.ExecuteAsync
    • โž• Add support for zlib@openssh.com compression algorithm on .NET 6+

    ๐Ÿ’ฅ Breaking changes:

    • SshCommand.ExitStatus was changed in #1423 from returning int to returning int? to reflect the fact that an exit status may not always be returned.
    • PipeStream (which provides the implementation of SshCommand.OutputStream and ExtendedOutputStream) was rewritten in #1399 to fix a number of bugs and become more "stream-like". As such:

      • It may now block where previously it may have returned 0 prematurely
      • It may now return partial data where previously it may have blocked until a certain amount of data was available.
      • The properties BlockLastReadBuffer and MaxBufferLength have been removed.
    • CommandAsyncResult was deleted in #1426

    • RsaCipher, AsymmetricCipher and CipherDigitalSignature were deleted in #1373

    • ๐Ÿšš Encrypt/DecryptBlock were moved down from SymmetricCipher to BlockCipher in #1369

    • The previously nonfunctional ZlibStream was deleted and the API of Compressor was changed in #1326

    • SftpFileSytemInformation was renamed to SftpFileSystemInformation in #1425

    • ๐Ÿ‘€ See the full API diff at the end

    What's Changed

    • ๐Ÿ›  Fix ShellStream when receiving data larger than buffer length by @Rob-Hague in #1337
    • ๐Ÿ›  fix link to tests in README by @mus65 in #1338
    • โœ‚ Remove feature binary serialization by @scott-xu in #1325
    • ๐Ÿ”„ Changed Private Key Regex to be more tolerant regarding new lines at end of key file by @staecthSICKAG in #1344
    • ๐Ÿ— Use latest .NET 8 SDK in Ubuntu build by @Rob-Hague in #1352
    • โฑ Use BCL Timeout by @scott-xu in #1353
    • ๐Ÿ›  Fix CancelAsync Cause Deadlock by @zeotuan in #1345
    • โš  Cleanup and muting of analyzer warnings by @jscarle in #1357
    • SftpClient: handle the SFTP session being closed by the server by @mus65 in #1362
    • ๐Ÿ– Handle unknown channel messages correctly by @mus65 in #1363
    • โœ‚ Remove enormous array allocations in tests causing instability in CI by @Rob-Hague in #1367
    • โž• Add Rob-Hague to CODEOWNERS by @WojciechNagorski in #1376
    • enable nullable on BaseClient and SftpClient by @mus65 in #1339
    • โž• Added support for GitHub pages using docfx by @jscarle in #1358
    • โž• Add support for Zlib compression (.NET 6.0 onward only) by @scott-xu in #1326
    • git: checkout cs files with crlf by @mus65 in #1372
    • ๐Ÿ›  Fix nullable error in build by @Rob-Hague in #1377
    • โž• Add support for AEAD AES 128/256 GCM Ciphers (.NET 6.0 onward only) by @scott-xu in #1369
    • โž• Add an AOT compatibility test app by @Rob-Hague in #1378
    • Implement OpenSSH strict key exchange extension by @scott-xu in #1366
    • ๐Ÿ›  Fix potential side-channel timing attack issue by @scott-xu in #1375
    • โฑ Handle timeout correctly on Socks5 Proxy by @BoronBGP in #1342
    • ๐Ÿ›  Fix ArgumentException usage in BlockCipher by @IgorMilavec in #818
    • ๐Ÿ›  Fix SocketAsyncEventArgsAwaitable calling continuation multiple times by @IgorMilavec in #918
    • gitattributes: set diff=csharp on cs files by @mus65 in #1393
    • โฌ‡๏ธ drop obsolete #if directives by @mus65 in #1394
    • ๐Ÿ”’ Use System.Security.Cryptography for RSA by @Rob-Hague in #1373
    • โœ… Tweak AsyncSocketListener in tests by @Rob-Hague in #1382
    • ๐Ÿ“š Documentation updates by @Rob-Hague in #1395
    • ๐Ÿ’… Cleanup formatting and style and enforce it in CI by @mus65 in #1380
    • ๐Ÿ›  fix flaky Connectivity Tests by @mus65 in #1403
    • ๐Ÿ›  fix flaky ReceiveOnServerSocketShouldReturnZero test by @mus65 in #1404
    • ๐Ÿ›  fix flaky Sftp_BeginUploadFile test by @mus65 in #1402
    • More AsyncSocketListener patchwork by @Rob-Hague in #1408
    • ๐Ÿ‘‰ use Regex Source Generator for .NET 7+ by @mus65 in #1401
    • Enable nullable on NetConf/Scp/SshClient by @mus65 in #1392
    • โœ… make ConnectShouldActivateKeepAliveIfSessionIs test less flaky by @mus65 in #1410
    • โœ‚ Delete CountdownEventTests by @Rob-Hague in #1409
    • ๐Ÿ‘ท dotnet pack in CI by @Rob-Hague in #1400
    • ๐Ÿ˜Œ Relax the RSA/DSA decision for SSH2 keys by @Rob-Hague in #1190
    • ๐Ÿ›  Fix a few issues with PipeStream by @Rob-Hague in #1399
    • ๐Ÿ›  fix flaky SFTP file time tests by @mus65 in #1414
    • โšก๏ธ doc: Update examples.md by @lupaulus in #1421
    • ๐Ÿ›  A couple of changes/fixes in SshCommand by @Rob-Hague in #1423
    • ๐Ÿ“‡ Rename SftpFileSytemInformation to SftpFileSystemInformation by @fndejan in #1425
    • ๐Ÿ‘Œ Support creating Shell(Stream) without PTY by @scott-xu in #1419
    • ๐Ÿ›  fix build with .NET 9.0 SDK by @mus65 in #1427
    • โšก๏ธ Updated NETCONF framing protocol detection to check both client & server capabilities by @declspec in #639
    • ๐Ÿ›  Fix netconf framing protocol by @schaveyt in #946
    • On SOCKS5 proxy: set hostname, not always IP by @jjvaca in #1072
    • โœ‚ Remove unnecessary DNS lookup in Connect by @Rob-Hague in #1412
    • โž• Add SshCommand.ExecuteAsync by @Rob-Hague in #1426
    • Set version to 2024.1.0 by @Rob-Hague in #1429

    ๐Ÿ†• New Contributors

    Full Changelog : 2024.0.0...2024.1.0

    API diff

    namespace Renci.SshNet
    {
         public abstract class BaseClient : Renci.SshNet.IBaseClient, System.IDisposable
         {- public bool IsConnected { get; }+ public virtual bool IsConnected { get; }- public event System.EventHandler\<Renci.SshNet.Common.ExceptionEventArgs\> ErrorOccurred;+ public event System.EventHandler\<Renci.SshNet.Common.ExceptionEventArgs\>? ErrorOccurred;- public event System.EventHandler\<Renci.SshNet.Common.HostKeyEventArgs\> HostKeyReceived;+ public event System.EventHandler\<Renci.SshNet.Common.HostKeyEventArgs\>? HostKeyReceived;- public event System.EventHandler\<Renci.SshNet.Common.SshIdentificationEventArgs\> ServerIdentificationReceived;+ public event System.EventHandler\<Renci.SshNet.Common.SshIdentificationEventArgs\>? ServerIdentificationReceived;}
    
         public class CipherInfo
         {- public CipherInfo(int keySize, System.Func\<byte[], byte[], Renci.SshNet.Security.Cryptography.Cipher\> cipher) { }+ public CipherInfo(int keySize, System.Func\<byte[], byte[], Renci.SshNet.Security.Cryptography.Cipher\> cipher, bool isAead = false) { }+ public bool IsAead { get; }}- public class CommandAsyncResult : System.IAsyncResult- {- public object AsyncState { get; }- public System.Threading.WaitHandle AsyncWaitHandle { get; }- public int BytesReceived { get; set; }- public int BytesSent { get; set; }- public bool CompletedSynchronously { get; }- public bool IsCompleted { get; }- }public interface ISftpClient : Renci.SshNet.IBaseClient, System.IDisposable
         {- System.IAsyncResult BeginDownloadFile(string path, System.IO.Stream output, System.AsyncCallback asyncCallback);+ System.IAsyncResult BeginDownloadFile(string path, System.IO.Stream output, System.AsyncCallback? asyncCallback);- System.IAsyncResult BeginListDirectory(string path, System.AsyncCallback asyncCallback, object state, System.Action\<int\> listCallback = null);+ System.IAsyncResult BeginListDirectory(string path, System.AsyncCallback? asyncCallback, object? state, System.Action\<int\>? listCallb...
    
  • v2024.0.0 Changes

    February 21, 2024

    ๐Ÿ†• New features:

    • ๐ŸŽ ShellStream has been completely rewritten, all bugs fixed and performance improved.
    • ๐Ÿ‘ Allow writing to stdin of SshCommand
    • ๐Ÿ‘Œ Support for Trimming and AOT
    • โž• Add new MAC algorithms:

      • 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
    • โฌ‡๏ธ Drop old MAC algorithms:

      • hmac-ripemd160
      • hmac-ripemd160@openssh.com

    The list of changes:

    ๐Ÿ†• New Contributors

    Full Changelog : 2023.0.1...2024.0.0

  • v2023.0.1 Changes

    December 29, 2023

    ๐Ÿ†• New features:

    • ๐Ÿ‘Œ Improve SFTP performance on medium/high latency connections
    • ๐Ÿ”’ Use System.Security.Cryptography in AesCipher
    • ๐Ÿ‘‰ Use hardware-accelerated AES
    • โž• Add support for .NET 8.0
    • โฌ‡๏ธ Reduces heap allocations
    • And many more.

    The list of changes:

    ๐Ÿ†• New Contributors

    Full Changelog : 2023.0.0...2023.0.1

  • v2023.0.0 Changes

    October 10, 2023

    ๐Ÿ†• New features:

    • ๐Ÿ‘Œ Support for .NET 6, 7, and .NET Standard 2.1
    • ๐Ÿ‘Œ Support for RSA-SHA256/512 signature algorithms
    • ๐Ÿ‘Œ Support for parsing OpenSSH keys with ECDSA 256/384/521 and RSA
    • ๐Ÿ‘Œ Support for SHA256 and MD5 fingerprints for host key validation
    • โž• Added async support to SftpClient and SftpFileStream
    • โž• Added ISftpFile interface to SftpFile
    • โœ‚ Removed support for old target frameworks
    • ๐Ÿ‘Œ Improved performance and stability
    • โž• Added the ability to set the last write and access time for Sftp files

    The list of changes:

    ๐Ÿ†• New Contributors

    Thank you to all of our contributors for making SSH.NET the best SSH library for .NET!

    Full Changelog : 2020.0.1...2023.0.0

    API listing follows standard diff formatting.
    Lines preceded by a '+' are additions and a '-' indicates removal.

    Renci.SshNet

    namespace Renci.SshNet {- public abstract class BaseClient : IDisposable {+ public abstract class BaseClient : IBaseClient, IDisposable {+ public Task ConnectAsync(CancellationToken cancellationToken);}+ public interface IBaseClient+ public interface IPrivateKeySource- public interface ISftpClient {+ public interface ISftpClient : IBaseClient, IDisposable {+ Task DeleteFileAsync(string path, CancellationToken cancellationToken);- IEnumerable\<SftpFile\> EndListDirectory(IAsyncResult asyncResult);+ IEnumerable\<ISftpFile\> EndListDirectory(IAsyncResult asyncResult);- SftpFile Get(string path);+ ISftpFile Get(string path);+ Task\<SftpFileSytemInformation\> GetStatusAsync(string path, CancellationToken cancellationToken);- IEnumerable\<SftpFile\> ListDirectory(string path, Action\<int\> listCallback = null);+ IEnumerable\<ISftpFile\> ListDirectory(string path, Action\<int\> listCallback = null);+ IAsyncEnumerable\<ISftpFile\> ListDirectoryAsync(string path, CancellationToken cancellationToken);+ Task\<SftpFileStream\> OpenAsync(string path, FileMode mode, FileAccess access, CancellationToken cancellationToken);+ Task RenameFileAsync(string oldPath, string newPath, CancellationToken cancellationToken);+ void SetLastAccessTime(string path, DateTime lastAccessTime);+ void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc);+ void SetLastWriteTime(string path, DateTime lastWriteTime);+ void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc);}
         public class NetConfClient : BaseClient {+ public NetConfClient(string host, int port, string username, params IPrivateKeySource[] keyFiles);- public NetConfClient(string host, int port, string username, params PrivateKeyFile[] keyFiles);+ public NetConfClient(string host, string username, params IPrivateKeySource[] keyFiles);- public NetConfClient(string host, string username, params PrivateKeyFile[] keyFiles);}
         public class PrivateKeyAuthenticationMethod : AuthenticationMethod, IDisposable {+ public PrivateKeyAuthenticationMethod(string username, params IPrivateKeySource[] keyFiles);- public PrivateKeyAuthenticationMethod(string username, params PrivateKeyFile[] keyFiles);- public ICollection\<PrivateKeyFile\> KeyFiles { get; private set; }+ public ICollection\<IPrivateKeySource\> KeyFiles { get; private set; }}
         public class PrivateKeyConnectionInfo : ConnectionInfo, IDisposable {+ public PrivateKeyConnectionInfo(string host, int port, string username, params IPrivateKeySource[] keyFiles);- public PrivateKeyConnectionInfo(string host, int port, string username, params PrivateKeyFile[] keyFiles);+ public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params IPrivateKeySource[] keyFiles);- public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params PrivateKeyFile[] keyFiles);+ public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IPrivateKeySource[] keyFiles);- public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, st...
    
  • v2020.0.2 Changes

    May 29, 2022

    This release fixes a security vulnerability in our X25519 key exchange that could allow an attacker to eavesdrop the
    communications to decrypt them.

    ๐Ÿ”’ More information is available in advisory CVE-2022-29245.

  • v2020.0.1 Changes

    January 24, 2021

    ๐Ÿ›  Fixes

    General

    • ๐Ÿ‘Œ Support LF as line ending for banner and identification string

    Feedback

    ๐Ÿ‘ Target framework support

    While our list of supported target frameworks is impressive, it does come with a cost. Some of these target frameworks are no longer supported by Microsoft and even required software that is no longer available for download.

    ๐Ÿ‘ We'd like to gather feedback from our users through this issue to learn how important it is to continue supporting all these target frameworks.

    Twitter

    Do you want to keep track of general progress and annoucements for SSH.NET? You can now follow us on Twitter.

    ๐Ÿ‘Œ 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 through GitHub Sponsors.

  • v2020.0.0 Changes

    December 31, 2020

    ๐Ÿ”„ Changes

    ๐Ÿ‘ Target framework support

    This release of SSH.NET adds support for .NET Standard 2.0.
    ๐Ÿ‘ This brings the full list of the supported target frameworks to:

    • .NET Framework 3.5
    • .NET Framework 4.0 (and higher)
    • .NET Standard 1.3
    • .NET Standard 2.0
    • Silverlight 4
    • Silverlight 5
    • ๐Ÿ Windows Phone 7.1
    • ๐Ÿ Windows Phone 8.0
    • ๐Ÿ Universal Windows Platform 10

    ๐Ÿ›  Fixes issue #357, #436 and #474.

    Key exchange algorithms

    SSH.NET now supports the following additional key exchange algorithms:

    • curve25519-sha256
    • curve25519-sha256@libssh.org
    • ecdh-sha2-nistp256
    • ecdh-sha2-nistp384
    • ecdh-sha2-nistp521
    • diffie-hellman-group14-sha256
    • diffie-hellman-group16-sha512

    ๐Ÿ›  Fixes issue #53, #406 and #504.

    Host key algorithms

    ๐Ÿ‘ The following additional host key algorithms are now supported:

    • ssh-ed25519
    • ecdsa-sha2-nistp256
    • ecdsa-sha2-nistp384
    • ecdsa-sha2-nistp521

    Public key authentication

    SSH.NET now 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
    • ED25519 in OpenSSH key format

    ๐Ÿ›  Fixes issue #485.

    Troubleshooting

    Until now any issue related to Protocol Version Exchange would be reported using a single message:

    Server response does not contain SSH protocol identification.
    

    ๐Ÿš€ As of this release, we identify - and report - three distinct issues:

    • The server immediately closed the connections upon reception of our SSH identification string.

    • The identification string of the server contains a null character (which is prohibited).

    • The server response does not contain an SSH identification string.

    โฑ Channel close timeout

    A ChannelCloseTimeout property has been introduced on ConnectionInfo that controls the timeout to apply when waiting for a server to acknowledge closing a channel. The default value is 1 second.

    If a server does not report to our SSH_MSG_CHANNEL_CLOSE message with a SSH_MSG_CHANNEL_CLOSE message before the specified timeout elapses, we'll stop waiting and consider the channel to be closed.

    ๐Ÿ›  Fixes issue #335.

    SftpClient

    • SftpClient now implements ISftpClient to allow for each testing (issue #193).

    ๐Ÿ’ฅ Breaking changes

    ScpClient

    CVE-2018-20685 caused OpenSSH to implement more strict validation of file paths. ScpClient was updated to correctly deal with these changes.

    In case of a recursive directory upload, ScpClient cannot fully absorb the impact of these changes and as such Upload(DirectoryInfo directoryInfo, string path) now fails if path does not exist on the remote host. For the same reason, the mode and modification/access time will also no longer be set on path.

    The mode and modification/access time continue to be set on any files or subdirectories that are uploaded.

    ๐Ÿ›  Fixes

    General

    • ๐Ÿ‘‰ Use big endian byte order for port number in SOCKS request (issue #125 and #447).
    • Connect() times out when server rejects initializing subsystem (issue #308).
    • Keep-alives are not activated if connection is already opened (issue #334).
    • Connection cannot be re-established when subsystem cannot be executed (issue #338).
    • Closed event on Channel is not deterministic (issue #319).
    • Disconnect() and Dispose() may block indefinitely on .NET Core (issue #355 and #686).
    • ๐Ÿ”€ EAP implementation does not correctly deal with a socket operation that is completed synchronously (issue #377 and #571).
    • Identification string is not immediately sent when connection is established (issue #689 and #505).
    • ๐Ÿ“œ Minor protocol version parsing bug (issue #749).

    SftpClient

    • ๐Ÿ›  Fix UTC time handling in case of DST shifts (issue #356)

    Feedback

    ๐Ÿ‘ Target framework support

    While our list of supported target frameworks is impressive, it does come with a cost. Some of these target frameworks are no longer supported by Microsoft and even required software that is no longer available for download.

    ๐Ÿ‘ We'd like to gather feedback from our users through this issue to learn how important it is to continue supporting all these target frameworks.

    Twitter

    Do you want to keep track of general progress and annoucements for SSH.NET? You can now follow us on Twitter.

    ๐Ÿ‘Œ 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 through GitHub Sponsors.

    Thanks

    ๐Ÿš€ This release wouldn't have been possible without contributions from:
    @darinkes, @AtosNicoS, @dancret, @menees, @ericbrumfield

    ๐Ÿฑ Special thanks for @Filini producing our new logo assets!