Skip to content

Commit d1a1cd5

Browse files
committed
Add IPrivateKeyFile
So Extension can add own PrivateKeyFiles, e.g. PuttyKeyFile.
1 parent 8a6cc88 commit d1a1cd5

8 files changed

+55
-32
lines changed

src/Renci.SshNet/IPrivateKeyFile.cs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Renci.SshNet.Security;
2+
3+
namespace Renci.SshNet
4+
{
5+
/// <summary>
6+
/// Represents private key file interface.
7+
/// </summary>
8+
public interface IPrivateKeyFile
9+
{
10+
/// <summary>
11+
/// Gets the host key.
12+
/// </summary>
13+
HostAlgorithm HostKey { get; }
14+
}
15+
}

src/Renci.SshNet/NetConfClient.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public NetConfClient(string host, string username, string password)
103103
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
104104
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
105105
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
106-
public NetConfClient(string host, int port, string username, params PrivateKeyFile[] keyFiles)
106+
public NetConfClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles)
107107
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
108108
{
109109
}
@@ -116,7 +116,7 @@ public NetConfClient(string host, int port, string username, params PrivateKeyFi
116116
/// <param name="keyFiles">Authentication private key file(s) .</param>
117117
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
118118
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
119-
public NetConfClient(string host, string username, params PrivateKeyFile[] keyFiles)
119+
public NetConfClient(string host, string username, params IPrivateKeyFile[] keyFiles)
120120
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
121121
{
122122
}
@@ -163,7 +163,7 @@ internal NetConfClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, I
163163
/// <value>
164164
/// The NetConf server capabilities.
165165
/// </value>
166-
public XmlDocument ServerCapabilities
166+
public XmlDocument ServerCapabilities
167167
{
168168
get { return _netConfSession.ServerCapabilities; }
169169
}

src/Renci.SshNet/PrivateKeyAuthenticationMethod.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,21 @@ public override string Name
2828
/// <summary>
2929
/// Gets the key files used for authentication.
3030
/// </summary>
31-
public ICollection<PrivateKeyFile> KeyFiles { get; private set; }
31+
public ICollection<IPrivateKeyFile> KeyFiles { get; private set; }
3232

3333
/// <summary>
3434
/// Initializes a new instance of the <see cref="PrivateKeyAuthenticationMethod"/> class.
3535
/// </summary>
3636
/// <param name="username">The username.</param>
3737
/// <param name="keyFiles">The key files.</param>
3838
/// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <c>null</c>.</exception>
39-
public PrivateKeyAuthenticationMethod(string username, params PrivateKeyFile[] keyFiles)
39+
public PrivateKeyAuthenticationMethod(string username, params IPrivateKeyFile[] keyFiles)
4040
: base(username)
4141
{
4242
if (keyFiles == null)
4343
throw new ArgumentNullException("keyFiles");
4444

45-
KeyFiles = new Collection<PrivateKeyFile>(keyFiles);
45+
KeyFiles = new Collection<IPrivateKeyFile>(keyFiles);
4646
}
4747

4848
/// <summary>

src/Renci.SshNet/PrivateKeyConnectionInfo.cs

+8-8
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class PrivateKeyConnectionInfo : ConnectionInfo, IDisposable
1515
/// <summary>
1616
/// Gets the key files used for authentication.
1717
/// </summary>
18-
public ICollection<PrivateKeyFile> KeyFiles { get; private set; }
18+
public ICollection<IPrivateKeyFile> KeyFiles { get; private set; }
1919

2020
/// <summary>
2121
/// Initializes a new instance of the <see cref="PrivateKeyConnectionInfo"/> class.
@@ -40,7 +40,7 @@ public PrivateKeyConnectionInfo(string host, string username, params PrivateKeyF
4040
/// <param name="port">Connection port.</param>
4141
/// <param name="username">Connection username.</param>
4242
/// <param name="keyFiles">Connection key files.</param>
43-
public PrivateKeyConnectionInfo(string host, int port, string username, params PrivateKeyFile[] keyFiles)
43+
public PrivateKeyConnectionInfo(string host, int port, string username, params IPrivateKeyFile[] keyFiles)
4444
: this(host, port, username, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty, keyFiles)
4545
{
4646
}
@@ -55,7 +55,7 @@ public PrivateKeyConnectionInfo(string host, int port, string username, params P
5555
/// <param name="proxyHost">The proxy host.</param>
5656
/// <param name="proxyPort">The proxy port.</param>
5757
/// <param name="keyFiles">The key files.</param>
58-
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params PrivateKeyFile[] keyFiles)
58+
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, params IPrivateKeyFile[] keyFiles)
5959
: this(host, port, username, proxyType, proxyHost, proxyPort, string.Empty, string.Empty, keyFiles)
6060
{
6161
}
@@ -71,7 +71,7 @@ public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTyp
7171
/// <param name="proxyPort">The proxy port.</param>
7272
/// <param name="proxyUsername">The proxy username.</param>
7373
/// <param name="keyFiles">The key files.</param>
74-
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params PrivateKeyFile[] keyFiles)
74+
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IPrivateKeyFile[] keyFiles)
7575
: this(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
7676
{
7777
}
@@ -100,7 +100,7 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy
100100
/// <param name="proxyPort">The proxy port.</param>
101101
/// <param name="proxyUsername">The proxy username.</param>
102102
/// <param name="keyFiles">The key files.</param>
103-
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params PrivateKeyFile[] keyFiles)
103+
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, params IPrivateKeyFile[] keyFiles)
104104
: this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty, keyFiles)
105105
{
106106
}
@@ -116,7 +116,7 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy
116116
/// <param name="proxyUsername">The proxy username.</param>
117117
/// <param name="proxyPassword">The proxy password.</param>
118118
/// <param name="keyFiles">The key files.</param>
119-
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles)
119+
public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IPrivateKeyFile[] keyFiles)
120120
: this(host, DefaultPort, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, keyFiles)
121121
{
122122
}
@@ -133,10 +133,10 @@ public PrivateKeyConnectionInfo(string host, string username, ProxyTypes proxyTy
133133
/// <param name="proxyUsername">The proxy username.</param>
134134
/// <param name="proxyPassword">The proxy password.</param>
135135
/// <param name="keyFiles">The key files.</param>
136-
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params PrivateKeyFile[] keyFiles)
136+
public PrivateKeyConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params IPrivateKeyFile[] keyFiles)
137137
: base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, new PrivateKeyAuthenticationMethod(username, keyFiles))
138138
{
139-
KeyFiles = new Collection<PrivateKeyFile>(keyFiles);
139+
KeyFiles = new Collection<IPrivateKeyFile>(keyFiles);
140140
}
141141

142142
#region IDisposable Members

src/Renci.SshNet/PrivateKeyFile.cs

+17-9
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ namespace Renci.SshNet
6363
/// </list>
6464
/// </para>
6565
/// </remarks>
66-
public class PrivateKeyFile : IDisposable
66+
public class PrivateKeyFile : IPrivateKeyFile, IDisposable
6767
{
6868
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 *-+",
6969
#if FEATURE_REGEX_COMPILE
@@ -74,10 +74,18 @@ public class PrivateKeyFile : IDisposable
7474

7575
private Key _key;
7676

77+
private HostAlgorithm _hostKey;
78+
7779
/// <summary>
7880
/// Gets the host key.
7981
/// </summary>
80-
public HostAlgorithm HostKey { get; private set; }
82+
public HostAlgorithm HostKey
83+
{
84+
get
85+
{
86+
return _hostKey;
87+
}
88+
}
8189

8290
/// <summary>
8391
/// Initializes a new instance of the <see cref="PrivateKeyFile"/> class.
@@ -215,21 +223,21 @@ private void Open(Stream privateKey, string passPhrase)
215223
{
216224
case "RSA":
217225
_key = new RsaKey(decryptedData);
218-
HostKey = new KeyHostAlgorithm("ssh-rsa", _key);
226+
_hostKey = new KeyHostAlgorithm("ssh-rsa", _key);
219227
break;
220228
case "DSA":
221229
_key = new DsaKey(decryptedData);
222-
HostKey = new KeyHostAlgorithm("ssh-dss", _key);
230+
_hostKey = new KeyHostAlgorithm("ssh-dss", _key);
223231
break;
224232
#if FEATURE_ECDSA
225233
case "EC":
226234
_key = new EcdsaKey(decryptedData);
227-
HostKey = new KeyHostAlgorithm(_key.ToString(), _key);
235+
_hostKey = new KeyHostAlgorithm(_key.ToString(), _key);
228236
break;
229237
#endif
230238
case "OPENSSH":
231239
_key = ParseOpenSshV1Key(decryptedData, passPhrase);
232-
HostKey = new KeyHostAlgorithm(_key.ToString(), _key);
240+
_hostKey = new KeyHostAlgorithm(_key.ToString(), _key);
233241
break;
234242
case "SSH2 ENCRYPTED":
235243
var reader = new SshDataReader(decryptedData);
@@ -271,7 +279,7 @@ private void Open(Stream privateKey, string passPhrase)
271279

272280
if (decryptedLength > blobSize - 4)
273281
throw new SshException("Invalid passphrase.");
274-
282+
275283
if (keyType == "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}")
276284
{
277285
var exponent = reader.ReadBigIntWithBits();//e
@@ -281,7 +289,7 @@ private void Open(Stream privateKey, string passPhrase)
281289
var q = reader.ReadBigIntWithBits();//p
282290
var p = reader.ReadBigIntWithBits();//q
283291
_key = new RsaKey(modulus, exponent, d, p, q, inverseQ);
284-
HostKey = new KeyHostAlgorithm("ssh-rsa", _key);
292+
_hostKey = new KeyHostAlgorithm("ssh-rsa", _key);
285293
}
286294
else if (keyType == "dl-modp{sign{dsa-nist-sha1},dh{plain}}")
287295
{
@@ -296,7 +304,7 @@ private void Open(Stream privateKey, string passPhrase)
296304
var y = reader.ReadBigIntWithBits();
297305
var x = reader.ReadBigIntWithBits();
298306
_key = new DsaKey(p, q, g, y, x);
299-
HostKey = new KeyHostAlgorithm("ssh-dss", _key);
307+
_hostKey = new KeyHostAlgorithm("ssh-dss", _key);
300308
}
301309
else
302310
{

src/Renci.SshNet/ScpClient.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public ScpClient(string host, string username, string password)
142142
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
143143
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
144144
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
145-
public ScpClient(string host, int port, string username, params PrivateKeyFile[] keyFiles)
145+
public ScpClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles)
146146
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
147147
{
148148
}
@@ -155,7 +155,7 @@ public ScpClient(string host, int port, string username, params PrivateKeyFile[]
155155
/// <param name="keyFiles">Authentication private key file(s) .</param>
156156
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
157157
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
158-
public ScpClient(string host, string username, params PrivateKeyFile[] keyFiles)
158+
public ScpClient(string host, string username, params IPrivateKeyFile[] keyFiles)
159159
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
160160
{
161161
}

src/Renci.SshNet/SftpClient.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public SftpClient(string host, string username, string password)
205205
/// <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>
206206
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
207207
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
208-
public SftpClient(string host, int port, string username, params PrivateKeyFile[] keyFiles)
208+
public SftpClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles)
209209
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
210210
{
211211
}
@@ -218,7 +218,7 @@ public SftpClient(string host, int port, string username, params PrivateKeyFile[
218218
/// <param name="keyFiles">Authentication private key file(s) .</param>
219219
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <b>null</b>.</exception>
220220
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid. <para>-or-</para> <paramref name="username"/> is <b>null</b> or contains only whitespace characters.</exception>
221-
public SftpClient(string host, string username, params PrivateKeyFile[] keyFiles)
221+
public SftpClient(string host, string username, params IPrivateKeyFile[] keyFiles)
222222
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
223223
{
224224
}
@@ -592,13 +592,13 @@ public bool Exists(string path)
592592
// using SSH_FXP_REALPATH is not an alternative as the SFTP specification has not always
593593
// been clear on how the server should respond when the specified path is not present on
594594
// the server:
595-
//
595+
//
596596
// SSH 1 to 4:
597597
// No mention of how the server should respond if the path is not present on the server.
598598
//
599599
// SSH 5:
600600
// The server SHOULD fail the request if the path is not present on the server.
601-
//
601+
//
602602
// SSH 6:
603603
// Draft 06: The server SHOULD fail the request if the path is not present on the server.
604604
// 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)
627627
/// <exception cref="ArgumentException"><paramref name="path" /> is <b>null</b> or contains only whitespace characters.</exception>
628628
/// <exception cref="SshConnectionException">Client is not connected.</exception>
629629
/// <exception cref="SftpPermissionDeniedException">Permission to perform the operation was denied by the remote host. <para>-or-</para> A SSH command was denied by the server.</exception>
630-
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>///
630+
/// <exception cref="SftpPathNotFoundException"><paramref name="path"/> was not found on the remote host.</exception>///
631631
/// <exception cref="SshException">A SSH error where <see cref="Exception.Message" /> is the message from the remote host.</exception>
632632
/// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
633633
/// <remarks>

src/Renci.SshNet/SshClient.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public SshClient(string host, string username, string password)
104104
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
105105
/// <exception cref="ArgumentOutOfRangeException"><paramref name="port"/> is not within <see cref="IPEndPoint.MinPort"/> and <see cref="IPEndPoint.MaxPort"/>.</exception>
106106
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")]
107-
public SshClient(string host, int port, string username, params PrivateKeyFile[] keyFiles)
107+
public SshClient(string host, int port, string username, params IPrivateKeyFile[] keyFiles)
108108
: this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), true)
109109
{
110110
}
@@ -121,7 +121,7 @@ public SshClient(string host, int port, string username, params PrivateKeyFile[]
121121
/// </example>
122122
/// <exception cref="ArgumentNullException"><paramref name="keyFiles"/> is <c>null</c>.</exception>
123123
/// <exception cref="ArgumentException"><paramref name="host"/> is invalid, -or- <paramref name="username"/> is <c>null</c> or contains only whitespace characters.</exception>
124-
public SshClient(string host, string username, params PrivateKeyFile[] keyFiles)
124+
public SshClient(string host, string username, params IPrivateKeyFile[] keyFiles)
125125
: this(host, ConnectionInfo.DefaultPort, username, keyFiles)
126126
{
127127
}

0 commit comments

Comments
 (0)