Improvements after #1177 (#1180)

This commit is contained in:
Wojciech Nagórski
2023-09-23 08:33:10 +02:00
committed by GitHub
parent 8732d3d7ef
commit 18e6673031
18 changed files with 74 additions and 110 deletions
@@ -21,7 +21,8 @@ namespace Renci.SshNet.Benchmarks.Security.Cryptography.Ciphers
using (var s = typeof(RsaCipherBenchmarks).Assembly.GetManifestResourceStream("Renci.SshNet.Benchmarks.Data.Key.RSA.txt"))
{
_privateKey = (RsaKey)((KeyHostAlgorithm) new PrivateKeyFile(s).HostKey).Key;
_privateKey = (RsaKey)new PrivateKeyFile(s).Key;
// The implementations of RsaCipher.Encrypt/Decrypt differ based on whether the supplied RsaKey has private key information
// or only public. So we extract out the public key information to a separate variable.
@@ -21,7 +21,7 @@ namespace Renci.SshNet.Benchmarks.Security.Cryptography
using (var s = typeof(ED25519DigitalSignatureBenchmarks).Assembly.GetManifestResourceStream("Renci.SshNet.Benchmarks.Data.Key.OPENSSH.ED25519.txt"))
{
_key = (ED25519Key) ((KeyHostAlgorithm) new PrivateKeyFile(s).HostKey).Key;
_key = (ED25519Key) new PrivateKeyFile(s).Key;
}
_signature = new ED25519DigitalSignature(_key).Sign(_data);
}
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -140,7 +141,7 @@ namespace Renci.SshNet.Tests.Classes
using (var s = executingAssembly.GetManifestResourceStream(string.Format("Renci.SshNet.Tests.Data.{0}", "Key.RSA.txt")))
{
var privateKey = new PrivateKeyFile(s);
return (KeyHostAlgorithm) privateKey.HostKey;
return (KeyHostAlgorithm) privateKey.HostKeyAlgorithms.First();
}
}
@@ -89,7 +89,7 @@ namespace Renci.SshNet.Tests.Classes.Common
using (var s = executingAssembly.GetManifestResourceStream(string.Format("Renci.SshNet.Tests.Data.{0}", "Key.RSA.txt")))
{
var privateKey = new PrivateKeyFile(s);
return (KeyHostAlgorithm)privateKey.HostKey;
return (KeyHostAlgorithm)privateKey.HostKeyAlgorithms.First();
}
}
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
@@ -113,7 +114,7 @@ namespace Renci.SshNet.Tests.Classes
using (var s = executingAssembly.GetManifestResourceStream(string.Format("Renci.SshNet.Tests.Data.{0}", "Key.RSA.txt")))
{
var privateKey = new PrivateKeyFile(s);
return (KeyHostAlgorithm)privateKey.HostKey;
return (KeyHostAlgorithm)privateKey.HostKeyAlgorithms.First();
}
}
}
@@ -1,9 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Renci.SshNet.Common;
using Renci.SshNet.Security;
using Renci.SshNet.Tests.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -412,7 +410,7 @@ namespace Renci.SshNet.Tests.Classes
using (var stream = GetData("Key.RSA.Encrypted.Aes.128.CBC.12345.txt"))
{
var privateKeyFile = new PrivateKeyFile(stream, "12345");
Assert.IsNotNull(privateKeyFile.HostKey);
TestRsaKeyFile(privateKeyFile);
}
}
@@ -430,7 +428,7 @@ namespace Renci.SshNet.Tests.Classes
using (var fs = File.Open(_temporaryFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var privateKeyFile = new PrivateKeyFile(_temporaryFile, "12345");
Assert.IsNotNull(privateKeyFile.HostKey);
TestRsaKeyFile(privateKeyFile);
fs.Close();
}
@@ -498,7 +496,7 @@ namespace Renci.SshNet.Tests.Classes
}
var privateKeyFile = new PrivateKeyFile(_temporaryFile, "12345");
Assert.IsNotNull(privateKeyFile.HostKey);
TestRsaKeyFile(privateKeyFile);
}
/// <summary>
@@ -510,7 +508,7 @@ namespace Renci.SshNet.Tests.Classes
using (var stream = GetData("Key.RSA.txt"))
{
var privateKeyFile = new PrivateKeyFile(stream);
Assert.IsNotNull(privateKeyFile.HostKey);
TestRsaKeyFile(privateKeyFile);
}
}
@@ -526,7 +524,7 @@ namespace Renci.SshNet.Tests.Classes
using (var fs = File.Open(_temporaryFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var privateKeyFile = new PrivateKeyFile(_temporaryFile);
Assert.IsNotNull(privateKeyFile.HostKey);
TestRsaKeyFile(privateKeyFile);
fs.Close();
}
@@ -544,7 +542,7 @@ namespace Renci.SshNet.Tests.Classes
using (var fs = File.Open(_temporaryFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var privateKeyFile = new PrivateKeyFile(_temporaryFile, "12345");
Assert.IsNotNull(privateKeyFile.HostKey);
TestRsaKeyFile(privateKeyFile);
fs.Close();
}
@@ -684,15 +682,14 @@ namespace Renci.SshNet.Tests.Classes
private static void TestRsaKeyFile(PrivateKeyFile rsaPrivateKeyFile)
{
Assert.AreEqual(3, rsaPrivateKeyFile.HostAlgorithms.Count);
Assert.IsNotNull(rsaPrivateKeyFile.HostKeyAlgorithms);
Assert.AreEqual(3, rsaPrivateKeyFile.HostKeyAlgorithms.Count);
List<KeyHostAlgorithm> algorithms = rsaPrivateKeyFile.HostAlgorithms.Cast<KeyHostAlgorithm>().ToList();
var algorithms = rsaPrivateKeyFile.HostKeyAlgorithms.ToList();
Assert.AreEqual("rsa-sha2-512", algorithms[0].Name);
Assert.AreEqual("rsa-sha2-256", algorithms[1].Name);
Assert.AreEqual("ssh-rsa", algorithms[2].Name);
Assert.AreSame(algorithms[0], rsaPrivateKeyFile.HostKey);
}
}
}
@@ -164,7 +164,7 @@ namespace Renci.SshNet.Tests.Classes.Security.Cryptography
{
using (var stream = GetData("Key.RSA.txt"))
{
return (RsaKey) ((KeyHostAlgorithm) new PrivateKeyFile(stream).HostKey).Key;
return (RsaKey) new PrivateKeyFile(stream).Key;
}
}
@@ -1,4 +1,4 @@
using System.Security.Cryptography;
using System.Security.Cryptography;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -176,7 +176,7 @@ namespace Renci.SshNet.Tests.Classes.Security
{
using (var stream = GetData("Key.RSA.txt"))
{
return (RsaKey) ((KeyHostAlgorithm) new PrivateKeyFile(stream).HostKey).Key;
return (RsaKey) new PrivateKeyFile(stream).Key;
}
}
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
@@ -122,7 +123,7 @@ namespace Renci.SshNet.Tests.Classes
using (var s = executingAssembly.GetManifestResourceStream(string.Format("Renci.SshNet.Tests.Data.{0}", "Key.RSA.txt")))
{
var privateKey = new PrivateKeyFile(s);
return (KeyHostAlgorithm)privateKey.HostKey;
return (KeyHostAlgorithm)privateKey.HostKeyAlgorithms.First();
}
}
}
@@ -1,21 +0,0 @@
using System.Collections.Generic;
using Renci.SshNet.Security;
namespace Renci.SshNet
{
/// <summary>
/// Represents a collection of host algorithms.
/// </summary>
public interface IHostAlgorithmsProvider
{
/// <summary>
/// The host algorithms provided by this <see cref="IHostAlgorithmsProvider"/>.
/// </summary>
/// <remarks>
/// In situations where there is a preferred order of usage of the host algorithms,
/// the collection should be ordered from most preferred to least.
/// </remarks>
IReadOnlyCollection<HostAlgorithm> HostAlgorithms { get; }
}
}
+8 -13
View File
@@ -1,5 +1,4 @@
using System;
using System.ComponentModel;
using System.Collections.Generic;
using Renci.SshNet.Security;
@@ -8,19 +7,15 @@ namespace Renci.SshNet
/// <summary>
/// Represents private key source interface.
/// </summary>
/// <remarks>
/// This interface has been replaced by <see cref="IHostAlgorithmsProvider"/>
/// and is obsolete.
/// </remarks>
[Obsolete($"Use {nameof(IHostAlgorithmsProvider)} instead. " +
$"{nameof(IPrivateKeySource)} may be removed in a future release. " +
$"See https://github.com/sshnet/SSH.NET/issues/1174 for details.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IPrivateKeySource : IHostAlgorithmsProvider
public interface IPrivateKeySource
{
/// <summary>
/// Gets the host key.
/// Gets the host keys algorithms.
/// </summary>
HostAlgorithm HostKey { get; }
/// <remarks>
/// In situations where there is a preferred order of usage of the host algorithms,
/// the collection should be ordered from most preferred to least.
/// </remarks>
IReadOnlyCollection<HostAlgorithm> HostKeyAlgorithms { get; }
}
}
+2 -2
View File
@@ -107,7 +107,7 @@ namespace Renci.SshNet
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
public NetConfClient(string host, int port, string username, params IHostAlgorithmsProvider[] keyFiles)
public NetConfClient(string host, int port, string username, params IPrivateKeySource[] keyFiles)
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true)
{
}
@@ -120,7 +120,7 @@ namespace Renci.SshNet
/// <param name="keyFiles">Authentication private key file(s) .</param>
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
public NetConfClient(string host, string username, params IHostAlgorithmsProvider[] keyFiles)
public NetConfClient(string host, string username, params IPrivateKeySource[] keyFiles)
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
{
}
@@ -31,7 +31,7 @@ namespace Renci.SshNet
/// <summary>
/// Gets the key files used for authentication.
/// </summary>
public ICollection<IHostAlgorithmsProvider> KeyFiles { get; private set; }
public ICollection<IPrivateKeySource> KeyFiles { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="PrivateKeyAuthenticationMethod"/> class.
@@ -39,7 +39,7 @@ namespace Renci.SshNet
/// <param name="username">The username.</param>
/// <param name="keyFiles">The key files.</param>
/// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
public PrivateKeyAuthenticationMethod(string username, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyAuthenticationMethod(string username, params IPrivateKeySource[] keyFiles)
: base(username)
{
if (keyFiles is null)
@@ -47,7 +47,7 @@ namespace Renci.SshNet
throw new ArgumentNullException(nameof(keyFiles));
}
KeyFiles = new Collection<IHostAlgorithmsProvider>(keyFiles);
KeyFiles = new Collection<IPrivateKeySource>(keyFiles);
}
/// <summary>
@@ -65,7 +65,7 @@ namespace Renci.SshNet
session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK");
var hostAlgorithms = KeyFiles.SelectMany(x => x.HostAlgorithms).ToList();
var hostAlgorithms = KeyFiles.SelectMany(x => x.HostKeyAlgorithms).ToList();
try
{
+9 -9
View File
@@ -17,7 +17,7 @@ namespace Renci.SshNet
/// <summary>
/// Gets the key files used for authentication.
/// </summary>
public ICollection<IHostAlgorithmsProvider> KeyFiles { get; private set; }
public ICollection<IPrivateKeySource> KeyFiles { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="PrivateKeyConnectionInfo"/> class.
@@ -41,7 +41,7 @@ namespace Renci.SshNet
/// <param name="port">Connection port.</param>
/// <param name="username">Connection username.</param>
/// <param name="keyFiles">Connection key files.</param>
public PrivateKeyConnectionInfo(string host, int port, string username, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyConnectionInfo(string host, int port, string username, params IPrivateKeySource[] keyFiles)
: this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles)
{
}
@@ -56,7 +56,7 @@ namespace Renci.SshNet
/// <param name="proxyHost">The proxy host.</param>
/// <param name="proxyPort">The proxy port.</param>
/// <param name="keyFiles">The key files.</param>
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params IPrivateKeySource[] keyFiles)
: this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles)
{
}
@@ -72,7 +72,7 @@ namespace Renci.SshNet
/// <param name="proxyPort">The proxy port.</param>
/// <param name="proxyUsername">The proxy username.</param>
/// <param name="keyFiles">The key files.</param>
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IPrivateKeySource[] keyFiles)
: this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
{
}
@@ -86,7 +86,7 @@ namespace Renci.SshNet
/// <param name="proxyHost">The proxy host.</param>
/// <param name="proxyPort">The proxy port.</param>
/// <param name="keyFiles">The key files.</param>
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params IPrivateKeySource[] keyFiles)
: this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles)
{
}
@@ -101,7 +101,7 @@ namespace Renci.SshNet
/// <param name="proxyPort">The proxy port.</param>
/// <param name="proxyUsername">The proxy username.</param>
/// <param name="keyFiles">The key files.</param>
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IPrivateKeySource[] keyFiles)
: this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
{
}
@@ -117,7 +117,7 @@ namespace Renci.SshNet
/// <param name="proxyUsername">The proxy username.</param>
/// <param name="proxyPassword">The proxy password.</param>
/// <param name="keyFiles">The key files.</param>
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IPrivateKeySource[] keyFiles)
: this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, keyFiles)
{
}
@@ -134,10 +134,10 @@ namespace Renci.SshNet
/// <param name="proxyUsername">The proxy username.</param>
/// <param name="proxyPassword">The proxy password.</param>
/// <param name="keyFiles">The key files.</param>
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IHostAlgorithmsProvider[] keyFiles)
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IPrivateKeySource[] keyFiles)
: base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, new PrivateKeyAuthenticationMethod(username, keyFiles))
{
KeyFiles = new Collection<IHostAlgorithmsProvider>(keyFiles);
KeyFiles = new Collection<IPrivateKeySource>(keyFiles);
}
/// <summary>
+23 -34
View File
@@ -65,11 +65,7 @@ namespace Renci.SshNet
/// </list>
/// </para>
/// </remarks>
public class PrivateKeyFile : IHostAlgorithmsProvider,
#pragma warning disable CS0618 // Type or member is obsolete
IPrivateKeySource,
#pragma warning restore CS0618 // Type or member is obsolete
IDisposable
public class PrivateKeyFile : IPrivateKeySource, IDisposable
{
private static readonly Regex PrivateKeyRegex = new Regex(@"^-+ *BEGIN (?<keyName>\w+( \w+)*) PRIVATE KEY *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?<cipherName>[A-Z0-9-]+),(?<salt>[A-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?<data>([a-zA-Z0-9/+=]{1,80}\r?\n)+)-+ *END \k<keyName> PRIVATE KEY *-+",
RegexOptions.Compiled | RegexOptions.Multiline);
@@ -78,29 +74,10 @@ namespace Renci.SshNet
private Key _key;
private bool _isDisposed;
/// <summary>
/// Gets the host key.
/// </summary>
/// <remarks>
/// This property returns the first item in <see cref="HostAlgorithms"/>.
/// </remarks>
public HostAlgorithm HostKey
{
get
{
return _hostAlgorithms[0];
}
private set
{
Debug.Assert(_hostAlgorithms.Count == 0, $"Only expected to set {nameof(HostKey)} at most once.");
_hostAlgorithms.Add(value);
}
}
/// <summary>
/// The supported host algorithms for this key file.
/// </summary>
public IReadOnlyCollection<HostAlgorithm> HostAlgorithms
public IReadOnlyCollection<HostAlgorithm> HostKeyAlgorithms
{
get
{
@@ -108,13 +85,25 @@ namespace Renci.SshNet
}
}
/// <summary>
/// Gets the key.
/// </summary>
public Key Key
{
get
{
return _key;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="PrivateKeyFile"/> class.
/// </summary>
/// <param name="key">The key.</param>
public PrivateKeyFile(Key key)
{
HostKey = new KeyHostAlgorithm(key.ToString(), key);
_key = key;
_hostAlgorithms.Add(new KeyHostAlgorithm(key.ToString(), key));
}
/// <summary>
@@ -124,7 +113,7 @@ namespace Renci.SshNet
public PrivateKeyFile(Stream privateKey)
{
Open(privateKey, passPhrase: null);
Debug.Assert(_hostAlgorithms.Count > 0, $"{nameof(HostKey)} is not set.");
Debug.Assert(_hostAlgorithms.Count > 0, $"{nameof(HostKeyAlgorithms)} is not set.");
}
/// <summary>
@@ -161,7 +150,7 @@ namespace Renci.SshNet
Open(keyFile, passPhrase);
}
Debug.Assert(_hostAlgorithms.Count > 0, $"{nameof(HostKey)} is not set.");
Debug.Assert(_hostAlgorithms.Count > 0, $"{nameof(HostKeyAlgorithms)} is not set.");
}
/// <summary>
@@ -173,7 +162,8 @@ namespace Renci.SshNet
public PrivateKeyFile(Stream privateKey, string passPhrase)
{
Open(privateKey, passPhrase);
Debug.Assert(_hostAlgorithms.Count > 0, $"{nameof(HostKey)} is not set.");
Debug.Assert(_hostAlgorithms.Count > 0, $"{nameof(HostKeyAlgorithms)} is not set.");
}
/// <summary>
@@ -266,11 +256,11 @@ namespace Renci.SshNet
break;
case "DSA":
_key = new DsaKey(decryptedData);
HostKey = new KeyHostAlgorithm("ssh-dss", _key);
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-dss", _key));
break;
case "EC":
_key = new EcdsaKey(decryptedData);
HostKey = new KeyHostAlgorithm(_key.ToString(), _key);
_hostAlgorithms.Add(new KeyHostAlgorithm(_key.ToString(), _key));
break;
case "OPENSSH":
_key = ParseOpenSshV1Key(decryptedData, passPhrase);
@@ -282,9 +272,8 @@ namespace Renci.SshNet
}
else
{
HostKey = new KeyHostAlgorithm(_key.ToString(), _key);
_hostAlgorithms.Add(new KeyHostAlgorithm(_key.ToString(), _key));
}
break;
case "SSH2 ENCRYPTED":
var reader = new SshDataReader(decryptedData);
@@ -358,7 +347,7 @@ namespace Renci.SshNet
var y = reader.ReadBigIntWithBits();
var x = reader.ReadBigIntWithBits();
_key = new DsaKey(p, q, g, y, x);
HostKey = new KeyHostAlgorithm("ssh-dss", _key);
_hostAlgorithms.Add(new KeyHostAlgorithm("ssh-dss", _key));
}
else
{
+2 -2
View File
@@ -146,7 +146,7 @@ namespace Renci.SshNet
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
public ScpClient(string host, int port, string username, params IHostAlgorithmsProvider[] keyFiles)
public ScpClient(string host, int port, string username, params IPrivateKeySource[] keyFiles)
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true)
{
}
@@ -159,7 +159,7 @@ namespace Renci.SshNet
/// <param name="keyFiles">Authentication private key file(s) .</param>
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
public ScpClient(string host, string username, params IHostAlgorithmsProvider[] keyFiles)
public ScpClient(string host, string username, params IPrivateKeySource[] keyFiles)
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
{
}
+2 -2
View File
@@ -218,7 +218,7 @@ namespace Renci.SshNet
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid. <para>-or-</para> <paramref name="username"/> is nu<b>null</b>ll or contains only whitespace characters.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
public SftpClient(string host, int port, string username, params IHostAlgorithmsProvider[] keyFiles)
public SftpClient(string host, int port, string username, params IPrivateKeySource[] keyFiles)
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true)
{
}
@@ -231,7 +231,7 @@ namespace Renci.SshNet
/// <param name="keyFiles">Authentication private key file(s) .</param>
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <b>null</b>.</exception>
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid. <para>-or-</para> <paramref name="username"/> is <b>null</b> or contains only whitespace characters.</exception>
public SftpClient(string host, string username, params IHostAlgorithmsProvider[] keyFiles)
public SftpClient(string host, string username, params IPrivateKeySource[] keyFiles)
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
{
}
+2 -2
View File
@@ -103,7 +103,7 @@ namespace Renci.SshNet
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
public SshClient(string host, int port, string username, params IHostAlgorithmsProvider[] keyFiles)
public SshClient(string host, int port, string username, params IPrivateKeySource[] keyFiles)
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true)
{
}
@@ -120,7 +120,7 @@ namespace Renci.SshNet
/// </example>
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
public SshClient(string host, string username, params IHostAlgorithmsProvider[] keyFiles)
public SshClient(string host, string username, params IPrivateKeySource[] keyFiles)
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
{
}