Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b219168
Integrate `ZLibStream` from .NET 6.0+ with SSH.NET.
scott-xu Feb 17, 2024
beafd82
OpenSSH server does not support zlib (pre-auth); OpenSSH client still…
scott-xu Feb 17, 2024
37dc55c
Correct compression algorithm name; Update README.md
scott-xu Feb 17, 2024
8fb67f7
Integrate `ZLibStream` from .NET 6.0+ with SSH.NET.
scott-xu Feb 17, 2024
7762748
OpenSSH server does not support zlib (pre-auth); OpenSSH client still…
scott-xu Feb 17, 2024
e7cdd32
Correct compression algorithm name; Update README.md
scott-xu Feb 17, 2024
684298c
Merge branch 'develop' into zlib
scott-xu Feb 18, 2024
bcd275f
Merge branch 'develop' into zlib
scott-xu Feb 19, 2024
903e35c
Merge branch 'develop' into zlib
scott-xu Feb 21, 2024
6a6503e
Merge branch 'zlib' of https://github.com/scott-xu/SSH.NET into zlib
scott-xu Mar 16, 2024
38f7485
Merge branch 'sshnet:develop' into zlib
scott-xu Mar 16, 2024
a4c97b2
Merge branch 'zlib' of https://github.com/scott-xu/SSH.NET into zlib
scott-xu Mar 16, 2024
e7fcad3
Test the compression by upload/download file
scott-xu Mar 16, 2024
29f502c
Refactor compression.
scott-xu Mar 21, 2024
e2b6975
Move delayed compression logic to base class.
scott-xu Mar 21, 2024
3667296
seal Zlib
scott-xu Mar 21, 2024
cb98229
update unit test
scott-xu Mar 21, 2024
e7ff21e
update unit test to see if it can trigger integration test
scott-xu Mar 23, 2024
7ebf78c
Flush zlibStream
scott-xu Mar 23, 2024
16b0745
Fix integration test
scott-xu Mar 24, 2024
d5d74a1
update test
scott-xu Mar 24, 2024
8243215
Merge branch 'develop' into zlib
scott-xu Mar 24, 2024
8ef8583
Merge branch 'develop' of https://github.com/scott-xu/SSH.NET into zlib
scott-xu Apr 4, 2024
722f507
Merge branch 'develop' into zlib
scott-xu Apr 4, 2024
86ce319
Update ConnectionInfo.cs
scott-xu Apr 5, 2024
77c475d
Update README.md
scott-xu Apr 5, 2024
acbb217
Merge branch 'develop' into zlib
scott-xu Apr 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ Private keys can be encrypted using one of the following cipher methods:
* hmac-sha2-256-etm<span></span>@openssh.com
* hmac-sha2-512-etm<span></span>@openssh.com


## Compression

**SSH.NET** supports the following compression algorithms:
* none (default)
* zlib<span></span>@openssh.com (.NET 6 and higher)
* zlib (.NET 6 and higher)

## Framework Support
**SSH.NET** supports the following target frameworks:
* .NETFramework 4.6.2 (and higher)
Expand Down
4 changes: 2 additions & 2 deletions src/Renci.SshNet/Compression/ZlibOpenSsh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Renci.SshNet.Compression
{
/// <summary>
/// Represents "zlib@openssh.org" compression implementation.
/// Represents "zlib@openssh.com" compression implementation.
/// </summary>
public class ZlibOpenSsh : Compressor
{
Expand All @@ -12,7 +12,7 @@ public class ZlibOpenSsh : Compressor
/// </summary>
public override string Name
{
get { return "zlib@openssh.org"; }
get { return "zlib@openssh.com"; }
}

/// <summary>
Expand Down
47 changes: 21 additions & 26 deletions src/Renci.SshNet/Compression/ZlibStream.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,40 @@
using System.IO;

#pragma warning disable S125 // Sections of code should not be commented out
#pragma warning disable SA1005 // Single line comments should begin with single space

namespace Renci.SshNet.Compression
{
/// <summary>
/// Implements Zlib compression algorithm.
/// </summary>
#pragma warning disable CA1711 // Identifiers should not have incorrect suffix
#pragma warning disable CA1001 // Types that own disposable fields should be disposable
public class ZlibStream
#pragma warning restore CA1001 // Types that own disposable fields should be disposable
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
//private readonly Ionic.Zlib.ZlibStream _baseStream;
#if NET6_0_OR_GREATER
private readonly System.IO.Compression.ZLibStream _baseStream;
#endif

/// <summary>
/// Initializes a new instance of the <see cref="ZlibStream" /> class.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="mode">The mode.</param>
#pragma warning disable IDE0060 // Remove unused parameter
public ZlibStream(Stream stream, CompressionMode mode)
#pragma warning restore IDE0060 // Remove unused parameter
{
//switch (mode)
//{
// case CompressionMode.Compress:
// this._baseStream = new Ionic.Zlib.ZlibStream(stream, Ionic.Zlib.CompressionMode.Compress, Ionic.Zlib.CompressionLevel.Default);
// break;
// case CompressionMode.Decompress:
// this._baseStream = new Ionic.Zlib.ZlibStream(stream, Ionic.Zlib.CompressionMode.Decompress, Ionic.Zlib.CompressionLevel.Default);
// break;
// default:
// break;
//}

//this._baseStream.FlushMode = Ionic.Zlib.FlushType.Partial;
#if NET6_0_OR_GREATER
switch (mode)
{
case CompressionMode.Compress:
_baseStream = new System.IO.Compression.ZLibStream(stream, System.IO.Compression.CompressionMode.Compress);
break;
case CompressionMode.Decompress:
_baseStream = new System.IO.Compression.ZLibStream(stream, System.IO.Compression.CompressionMode.Decompress);
break;
default:
break;
}
#endif
}

/// <summary>
Expand All @@ -44,15 +43,11 @@ public ZlibStream(Stream stream, CompressionMode mode)
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The offset.</param>
/// <param name="count">The count.</param>
#pragma warning disable IDE0060 // Remove unused parameter
public void Write(byte[] buffer, int offset, int count)
#pragma warning restore IDE0060 // Remove unused parameter
{
//this._baseStream.Write(buffer, offset, count);
#if NET6_0_OR_GREATER
_baseStream.Write(buffer, offset, count);
#endif
}
#pragma warning restore SA1005 // Single line comments should begin with single space
}
}

#pragma warning restore SA1005 // Single line comments should begin with single space
#pragma warning restore S125 // Sections of code should not be commented out
4 changes: 4 additions & 0 deletions src/Renci.SshNet/ConnectionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,10 @@ public ConnectionInfo(string host, int port, string username, ProxyTypes proxyTy
CompressionAlgorithms = new Dictionary<string, Func<Compressor>>
{
{ "none", null },
#if NET6_0_OR_GREATER
{ "[email protected]", () => new ZlibOpenSsh() },
{ "zlib", () => new Zlib() },
#endif
};

ChannelRequests = new Dictionary<string, RequestInfo>
Expand Down
4 changes: 2 additions & 2 deletions src/Renci.SshNet/Security/KeyExchange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ from a in message.MacAlgorithmsServerToClient
var compressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
from a in message.CompressionAlgorithmsClientToServer
where a == b
select a).LastOrDefault();
select a).FirstOrDefault();
if (string.IsNullOrEmpty(compressionAlgorithmName))
{
throw new SshConnectionException("Compression algorithm not found", DisconnectReason.KeyExchangeFailed);
Expand All @@ -136,7 +136,7 @@ from a in message.CompressionAlgorithmsClientToServer
var decompressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys
from a in message.CompressionAlgorithmsServerToClient
where a == b
select a).LastOrDefault();
select a).FirstOrDefault();
if (string.IsNullOrEmpty(decompressionAlgorithmName))
{
throw new SshConnectionException("Decompression algorithm not found", DisconnectReason.KeyExchangeFailed);
Expand Down
42 changes: 42 additions & 0 deletions test/Renci.SshNet.IntegrationTests/CompressionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Renci.SshNet.Compression;

namespace Renci.SshNet.IntegrationTests
{
[TestClass]
public class CompressionTests : IntegrationTestBase
{
private IConnectionInfoFactory _connectionInfoFactory;

[TestInitialize]
public void SetUp()
{
_connectionInfoFactory = new LinuxVMConnectionFactory(SshServerHostName, SshServerPort);
}

[TestMethod]
public void None()
{
DoTest(new KeyValuePair<string, Func<Compressor>>("none", null));
}

#if NET6_0_OR_GREATER
[TestMethod]
public void ZlibOpenSsh()
{
DoTest(new KeyValuePair<string, Func<Compressor>>("[email protected]", () => new ZlibOpenSsh()));
}
#endif

private void DoTest(KeyValuePair<string, Func<Compressor>> compressor)
{
using (var client = new SshClient(_connectionInfoFactory.Create()))
{
client.ConnectionInfo.CompressionAlgorithms.Clear();
client.ConnectionInfo.CompressionAlgorithms.Add(compressor);

client.Connect();
client.Disconnect();
}
}
}
}