11using System . IO ;
22using System . Net . Http ;
33using System . Threading ;
4+ using System . Threading . Tasks ;
45using Microsoft . Net . Http . Client ;
6+ using Renci . SshNet ;
57
68namespace Docker . DotNet . SSH
79{
810 public class SSHCredentials : Credentials
911 {
12+ private PrivateKeyFile _privateKey ;
13+
14+ /// <summary>
15+ /// Creates SSH credentials to handle connecting over SSH.
16+ /// </summary>
17+ /// <param name="privateKey">The private key contents</param>
18+ public SSHCredentials ( string privateKey ) : this ( privateKey , null ) { }
19+
20+ /// <summary>
21+ /// Creates SSH credentials to handle connecting over SSH.
22+ /// </summary>
23+ /// <param name="privateKey">The private key contents</param>
24+ /// <param name="password">Password for the private key</param>
25+ public SSHCredentials ( string privateKey , string password )
26+ {
27+ var stream = new MemoryStream ( ) ;
28+ using ( var writer = new StreamWriter ( stream ) )
29+ {
30+ writer . Write ( privateKey ) ;
31+ writer . Flush ( ) ;
32+
33+ stream . Position = 0 ;
34+ // This needs to be created *before* the StreamWriter (which closes the stream) is disposed
35+ _privateKey = new PrivateKeyFile ( stream , password ) ;
36+ }
37+ }
38+
1039 public override HttpMessageHandler GetHandler ( HttpMessageHandler innerHandler )
1140 {
1241 return innerHandler ;
@@ -22,11 +51,20 @@ public override bool IsTlsCredentials()
2251 return false ;
2352 }
2453
25- public override ManagedHandler . StreamOpener GetStreamOpener ( )
54+ public override ManagedHandler . StreamOpener GetSshStreamOpener ( string user )
2655 {
27- // TODO
28- return async ( string host , int port , CancellationToken cancellationToken ) => {
29- return File . OpenRead ( "/dev/null" ) ;
56+ return ( string host , int port , CancellationToken cancellationToken ) => {
57+ var authMethod = new PrivateKeyAuthenticationMethod ( user , _privateKey ) ;
58+ var connectionInfo = new ConnectionInfo ( host , port , user , authMethod ) ;
59+ var client = new SshClient ( connectionInfo ) ;
60+ client . Connect ( ) ;
61+
62+ var cmd = client . CreateCommand ( "docker system dial-stdio" ) ;
63+ cmd . BeginExecute ( ) ;
64+
65+ var result = new JoinedReadWriteStream ( cmd . OutputStream , cmd . InputStream ) ;
66+
67+ return Task . FromResult ( ( Stream ) result ) ;
3068 } ;
3169 }
3270 }
0 commit comments