From be269df757cbb4d1b7da2bace7b87b5c17c7d60d Mon Sep 17 00:00:00 2001 From: Stefan Rinkes Date: Sun, 14 Mar 2021 15:43:12 +0100 Subject: [PATCH] Add IPrivateKeyFile So Extension can add own PrivateKeyFiles, e.g. PuttyKeyFile. --- src/Renci.SshNet/IPrivateKeyFile.cs | 15 +++++++++++++++ src/Renci.SshNet/NetConfClient.cs | 6 +++--- .../PrivateKeyAuthenticationMethod.cs | 6 +++--- src/Renci.SshNet/PrivateKeyConnectionInfo.cs | 16 ++++++++-------- src/Renci.SshNet/PrivateKeyFile.cs | 6 +++--- src/Renci.SshNet/ScpClient.cs | 4 ++-- src/Renci.SshNet/SftpClient.cs | 10 +++++----- src/Renci.SshNet/SshClient.cs | 4 ++-- 8 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 src/Renci.SshNet/IPrivateKeyFile.cs diff --git a/src/Renci.SshNet/IPrivateKeyFile.cs b/src/Renci.SshNet/IPrivateKeyFile.cs new file mode 100644 index 000000000..61693804f --- /dev/null +++ b/src/Renci.SshNet/IPrivateKeyFile.cs @@ -0,0 +1,15 @@ +using Renci.SshNet.Security; + +namespace Renci.SshNet +{ + /// + /// Represents private key file interface. + /// + public interface IPrivateKeyFile + { + /// + /// Gets the host key. + /// + HostAlgorithm HostKey { get; set; } + } +} \ No newline at end of file diff --git a/src/Renci.SshNet/NetConfClient.cs b/src/Renci.SshNet/NetConfClient.cs index b1877c601..0c0802215 100644 --- a/src/Renci.SshNet/NetConfClient.cs +++ b/src/Renci.SshNet/NetConfClient.cs @@ -103,7 +103,7 @@ public NetConfClient(string host, string username, string password) /// is invalid, -or- is null or contains only whitespace characters. /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] - public NetConfClient(string host, int port, string username, params PrivateKeyFile[] keyFiles) + public NetConfClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true) { } @@ -116,7 +116,7 @@ public NetConfClient(string host, int port, string username, params PrivateKeyFi /// Authentication private key file(s) . /// is null. /// is invalid, -or- is null or contains only whitespace characters. - public NetConfClient(string host, string username, params PrivateKeyFile[] keyFiles) + public NetConfClient(string host, string username, params IPrivateKeyFile[] keyFiles) : this(host, ConnectionInfo.DefaultPort, username, keyFiles) { } @@ -163,7 +163,7 @@ internal NetConfClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, I /// /// The NetConf server capabilities. /// - public XmlDocument ServerCapabilities + public XmlDocument ServerCapabilities { get { return _netConfSession.ServerCapabilities; } } diff --git a/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs b/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs index 93ebbe19d..100af4ae0 100644 --- a/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs +++ b/src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs @@ -28,7 +28,7 @@ public override string Name /// /// Gets the key files used for authentication. /// - public ICollection KeyFiles { get; private set; } + public ICollection KeyFiles { get; private set; } /// /// Initializes a new instance of the class. @@ -36,13 +36,13 @@ public override string Name /// The username. /// The key files. /// is whitespace or null. - public PrivateKeyAuthenticationMethod(string username, params PrivateKeyFile[] keyFiles) + public PrivateKeyAuthenticationMethod(string username, params IPrivateKeyFile[] keyFiles) : base(username) { if (keyFiles == null) throw new ArgumentNullException("keyFiles"); - KeyFiles = new Collection(keyFiles); + KeyFiles = new Collection(keyFiles); } /// diff --git a/src/Renci.SshNet/PrivateKeyConnectionInfo.cs b/src/Renci.SshNet/PrivateKeyConnectionInfo.cs index 7f0c4f658..ddcdf5104 100644 --- a/src/Renci.SshNet/PrivateKeyConnectionInfo.cs +++ b/src/Renci.SshNet/PrivateKeyConnectionInfo.cs @@ -15,7 +15,7 @@ public class PrivateKeyConnectionInfo : ConnectionInfo, IDisposable /// /// Gets the key files used for authentication. /// - public ICollection KeyFiles { get; private set; } + public ICollection KeyFiles { get; private set; } /// /// Initializes a new instance of the class. @@ -40,7 +40,7 @@ public PrivateKeyConnectionInfo(string host, string username, params PrivateKeyF /// Connection port. /// Connection username. /// Connection key files. - public PrivateKeyConnectionInfo(string host, int port, string username, params PrivateKeyFile[] keyFiles) + public PrivateKeyConnectionInfo(string host, int port, string username, params IPrivateKeyFile[] keyFiles) : this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles) { } @@ -55,7 +55,7 @@ public PrivateKeyConnectionInfo(string host, int port, string username, params P /// The proxy host. /// The proxy port. /// The key files. - 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, params IPrivateKeyFile[] keyFiles) : this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles) { } @@ -71,7 +71,7 @@ public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTyp /// The proxy port. /// The proxy username. /// The key files. - public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params PrivateKeyFile[] keyFiles) + public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IPrivateKeyFile[] keyFiles) : this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles) { } @@ -100,7 +100,7 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy /// The proxy port. /// The proxy username. /// The key files. - public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params PrivateKeyFile[] keyFiles) + public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IPrivateKeyFile[] keyFiles) : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles) { } @@ -116,7 +116,7 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy /// The proxy username. /// The proxy password. /// The key files. - public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles) + public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IPrivateKeyFile[] keyFiles) : this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, keyFiles) { } @@ -133,10 +133,10 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy /// The proxy username. /// The proxy password. /// The key files. - public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles) + public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IPrivateKeyFile[] keyFiles) : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, new PrivateKeyAuthenticationMethod(username, keyFiles)) { - KeyFiles = new Collection(keyFiles); + KeyFiles = new Collection(keyFiles); } #region IDisposable Members diff --git a/src/Renci.SshNet/PrivateKeyFile.cs b/src/Renci.SshNet/PrivateKeyFile.cs index fb33a60cf..6d3a8157a 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -63,7 +63,7 @@ namespace Renci.SshNet /// /// /// - public class PrivateKeyFile : IDisposable + public class PrivateKeyFile : IPrivateKeyFile, IDisposable { private static readonly Regex PrivateKeyRegex = new Regex(@"^-+ *BEGIN (?\w+( \w+)*) PRIVATE KEY *-+\r?\n((Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: (?[A-Z0-9-]+),(?[A-F0-9]+)\r?\n\r?\n)|(Comment: ""?[^\r\n]*""?\r?\n))?(?([a-zA-Z0-9/+=]{1,80}\r?\n)+)-+ *END \k PRIVATE KEY *-+", #if FEATURE_REGEX_COMPILE @@ -77,7 +77,7 @@ public class PrivateKeyFile : IDisposable /// /// Gets the host key. /// - public HostAlgorithm HostKey { get; private set; } + public HostAlgorithm HostKey { get; set; } /// /// Initializes a new instance of the class. @@ -262,7 +262,7 @@ private void Open(Stream privateKey, string passPhrase) if (decryptedLength > blobSize - 4) throw new SshException("Invalid passphrase."); - + if (keyType == "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}") { var exponent = reader.ReadBigIntWithBits();//e diff --git a/src/Renci.SshNet/ScpClient.cs b/src/Renci.SshNet/ScpClient.cs index 8a252cac9..8b91b2bb9 100644 --- a/src/Renci.SshNet/ScpClient.cs +++ b/src/Renci.SshNet/ScpClient.cs @@ -142,7 +142,7 @@ public ScpClient(string host, string username, string password) /// is invalid, -or- is null or contains only whitespace characters. /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] - public ScpClient(string host, int port, string username, params PrivateKeyFile[] keyFiles) + public ScpClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true) { } @@ -155,7 +155,7 @@ public ScpClient(string host, int port, string username, params PrivateKeyFile[] /// Authentication private key file(s) . /// is null. /// is invalid, -or- is null or contains only whitespace characters. - public ScpClient(string host, string username, params PrivateKeyFile[] keyFiles) + public ScpClient(string host, string username, params IPrivateKeyFile[] keyFiles) : this(host, ConnectionInfo.DefaultPort, username, keyFiles) { } diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs index 3c22290d0..d75f5d78d 100644 --- a/src/Renci.SshNet/SftpClient.cs +++ b/src/Renci.SshNet/SftpClient.cs @@ -205,7 +205,7 @@ public SftpClient(string host, string username, string password) /// is invalid. -or- is nunullll or contains only whitespace characters. /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] - public SftpClient(string host, int port, string username, params PrivateKeyFile[] keyFiles) + public SftpClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true) { } @@ -218,7 +218,7 @@ public SftpClient(string host, int port, string username, params PrivateKeyFile[ /// Authentication private key file(s) . /// is null. /// is invalid. -or- is null or contains only whitespace characters. - public SftpClient(string host, string username, params PrivateKeyFile[] keyFiles) + public SftpClient(string host, string username, params IPrivateKeyFile[] keyFiles) : this(host, ConnectionInfo.DefaultPort, username, keyFiles) { } @@ -592,13 +592,13 @@ public bool Exists(string path) // using SSH_FXP_REALPATH is not an alternative as the SFTP specification has not always // been clear on how the server should respond when the specified path is not present on // the server: - // + // // SSH 1 to 4: // No mention of how the server should respond if the path is not present on the server. // // SSH 5: // The server SHOULD fail the request if the path is not present on the server. - // + // // SSH 6: // Draft 06: The server SHOULD fail the request if the path is not present on the server. // Draft 07 to 13: The server MUST NOT fail the request if the path does not exist. @@ -627,7 +627,7 @@ public bool Exists(string path) /// is null or contains only whitespace characters. /// Client is not connected. /// Permission to perform the operation was denied by the remote host. -or- A SSH command was denied by the server. - /// was not found on the remote host./// + /// was not found on the remote host./// /// A SSH error where is the message from the remote host. /// The method was called after the client was disposed. /// diff --git a/src/Renci.SshNet/SshClient.cs b/src/Renci.SshNet/SshClient.cs index 49c9ff84b..e07723d98 100644 --- a/src/Renci.SshNet/SshClient.cs +++ b/src/Renci.SshNet/SshClient.cs @@ -104,7 +104,7 @@ public SshClient(string host, string username, string password) /// is invalid, -or- is null or contains only whitespace characters. /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] - public SshClient(string host, int port, string username, params PrivateKeyFile[] keyFiles) + public SshClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true) { } @@ -121,7 +121,7 @@ public SshClient(string host, int port, string username, params PrivateKeyFile[] /// /// is null. /// is invalid, -or- is null or contains only whitespace characters. - public SshClient(string host, string username, params PrivateKeyFile[] keyFiles) + public SshClient(string host, string username, params IPrivateKeyFile[] keyFiles) : this(host, ConnectionInfo.DefaultPort, username, keyFiles) { }