1919using Keyfactor . Logging ;
2020using Keyfactor . PKI . PrivateKeys ;
2121using Keyfactor . PKI . PEM ;
22+ using System . Runtime . InteropServices ;
2223
2324namespace Keyfactor . Extensions . Orchestrator . RemoteFile . RemoteHandlers
2425{
2526 class SSHHandler : BaseRemoteHandler
2627 {
2728 private const string LINUX_PERMISSION_REGEXP = "^[0-7]{3}$" ;
2829 private ConnectionInfo Connection { get ; set ; }
30+ private bool RunLocal { get ; set ; }
31+ private bool IsStoreServerLinux { get ; set ; }
2932
3033 private SshClient sshClient ;
3134
32- internal SSHHandler ( string server , string serverLogin , string serverPassword )
35+ internal SSHHandler ( string server , string serverLogin , string serverPassword , bool isStoreServerLinux )
3336 {
3437 _logger . MethodEntry ( LogLevel . Debug ) ;
3538
3639 Server = server ;
40+ RunLocal = Server . ToLower ( ) == "localhost" || Server . ToLower ( ) . EndsWith ( "|localmachine" ) ;
41+ IsStoreServerLinux = isStoreServerLinux ;
3742
38- List < AuthenticationMethod > authenticationMethods = new List < AuthenticationMethod > ( ) ;
39- if ( serverPassword . Length < PASSWORD_LENGTH_MAX )
43+ if ( ! RunLocal )
4044 {
41- authenticationMethods . Add ( new PasswordAuthenticationMethod ( serverLogin , serverPassword ) ) ;
42- }
43- else
44- {
45- PrivateKeyFile privateKeyFile ;
46-
47- try
45+ List < AuthenticationMethod > authenticationMethods = new List < AuthenticationMethod > ( ) ;
46+ if ( serverPassword . Length < PASSWORD_LENGTH_MAX )
4847 {
49- using ( MemoryStream ms = new MemoryStream ( Encoding . ASCII . GetBytes ( FormatRSAPrivateKey ( serverPassword ) ) ) )
50- {
51- privateKeyFile = new PrivateKeyFile ( ms ) ;
52- }
48+ authenticationMethods . Add ( new PasswordAuthenticationMethod ( serverLogin , serverPassword ) ) ;
5349 }
54- catch ( Exception ex )
50+ else
5551 {
56- using ( MemoryStream ms = new MemoryStream ( Encoding . ASCII . GetBytes ( ConvertToPKCS1 ( serverPassword ) ) ) )
52+ PrivateKeyFile privateKeyFile ;
53+
54+ try
55+ {
56+ using ( MemoryStream ms = new MemoryStream ( Encoding . ASCII . GetBytes ( FormatRSAPrivateKey ( serverPassword ) ) ) )
57+ {
58+ privateKeyFile = new PrivateKeyFile ( ms ) ;
59+ }
60+ }
61+ catch ( Exception ex )
5762 {
58- privateKeyFile = new PrivateKeyFile ( ms ) ;
63+ using ( MemoryStream ms = new MemoryStream ( Encoding . ASCII . GetBytes ( ConvertToPKCS1 ( serverPassword ) ) ) )
64+ {
65+ privateKeyFile = new PrivateKeyFile ( ms ) ;
66+ }
5967 }
68+
69+ authenticationMethods . Add ( new PrivateKeyAuthenticationMethod ( serverLogin , privateKeyFile ) ) ;
6070 }
6171
62- authenticationMethods . Add ( new PrivateKeyAuthenticationMethod ( serverLogin , privateKeyFile ) ) ;
72+ Connection = new ConnectionInfo ( server , serverLogin , authenticationMethods . ToArray ( ) ) ;
6373 }
6474
65- Connection = new ConnectionInfo ( server , serverLogin , authenticationMethods . ToArray ( ) ) ;
66-
6775 _logger . MethodExit ( LogLevel . Debug ) ;
6876 }
6977
7078 public override void Initialize ( )
7179 {
7280 _logger . MethodEntry ( LogLevel . Debug ) ;
7381
74- try
75- {
76- sshClient = new SshClient ( Connection ) ;
77- sshClient . Connect ( ) ;
78- }
79- catch ( Exception ex )
82+ if ( ! RunLocal )
8083 {
81- throw new RemoteFileException ( $ "Error making a SSH connection to remote server { Connection . Host } , for user { Connection . Username } . Please contact your company's system administrator to verify connection and permission settings.", ex ) ;
84+ try
85+ {
86+ sshClient = new SshClient ( Connection ) ;
87+ sshClient . Connect ( ) ;
88+ }
89+ catch ( Exception ex )
90+ {
91+ throw new RemoteFileException ( $ "Error making a SSH connection to remote server { Connection . Host } , for user { Connection . Username } . Please contact your company's system administrator to verify connection and permission settings.", ex ) ;
92+ }
8293 }
83-
94+
8495 _logger . MethodExit ( LogLevel . Debug ) ;
8596 }
8697
8798 public override void Terminate ( )
8899 {
89100 _logger . MethodEntry ( LogLevel . Debug ) ;
90-
91- sshClient . Disconnect ( ) ;
92- sshClient . Dispose ( ) ;
101+
102+ if ( ! RunLocal )
103+ {
104+ sshClient . Disconnect ( ) ;
105+ sshClient . Dispose ( ) ;
106+ }
93107
94108 _logger . MethodExit ( LogLevel . Debug ) ;
95109 }
@@ -104,10 +118,18 @@ public override string RunCommand(string commandText, object[] arguments, bool w
104118
105119 try
106120 {
107- if ( withSudo )
121+ if ( withSudo && IsStoreServerLinux )
108122 commandText = sudo + commandText ;
109123
110- commandText = echo + commandText ;
124+ if ( IsStoreServerLinux )
125+ {
126+ commandText = echo + commandText ;
127+ }
128+ else
129+ {
130+ commandText = "powershell -Command \" " + commandText + "\" " ;
131+ commandText = commandText . Replace ( @"\" , @"\\" ) ;
132+ }
111133
112134 string displayCommand = commandText ;
113135 if ( passwordsToMaskInLog != null )
@@ -162,7 +184,7 @@ public override void UploadCertificateFile(string path, string fileName, byte[]
162184
163185 using ( MemoryStream stream = new MemoryStream ( certBytes ) )
164186 {
165- client . Upload ( stream , FormatFTPPath ( uploadPath ) ) ;
187+ client . Upload ( stream , FormatFTPPath ( uploadPath , false ) ) ;
166188 }
167189 }
168190 catch ( Exception ex )
@@ -193,7 +215,7 @@ public override void UploadCertificateFile(string path, string fileName, byte[]
193215
194216 using ( MemoryStream stream = new MemoryStream ( certBytes ) )
195217 {
196- client . UploadFile ( stream , FormatFTPPath ( uploadPath ) ) ;
218+ client . UploadFile ( stream , FormatFTPPath ( uploadPath , ! IsStoreServerLinux ) ) ;
197219 }
198220 }
199221 catch ( Exception ex )
@@ -209,7 +231,7 @@ public override void UploadCertificateFile(string path, string fileName, byte[]
209231 }
210232 }
211233
212- if ( ! string . IsNullOrEmpty ( ApplicationSettings . SeparateUploadFilePath ) )
234+ if ( ! string . IsNullOrEmpty ( ApplicationSettings . SeparateUploadFilePath ) && IsStoreServerLinux )
213235 {
214236 //RunCommand($"cat {uploadPath} > {path}/{fileName}", null, ApplicationSettings.UseSudo, null);
215237 RunCommand ( $ "tee { path } /{ fileName } < { uploadPath } > /dev/null", null , ApplicationSettings . UseSudo , null ) ;
@@ -230,7 +252,7 @@ public override byte[] DownloadCertificateFile(string path)
230252 string altPathOnly = string . Empty ;
231253 string altFileNameOnly = string . Empty ;
232254
233- if ( ! string . IsNullOrEmpty ( ApplicationSettings . SeparateUploadFilePath ) )
255+ if ( ! string . IsNullOrEmpty ( ApplicationSettings . SeparateUploadFilePath ) && IsStoreServerLinux )
234256 {
235257 SplitStorePathFile ( path , out altPathOnly , out altFileNameOnly ) ;
236258 downloadPath = ApplicationSettings . SeparateUploadFilePath + altFileNameOnly ;
@@ -251,7 +273,7 @@ public override byte[] DownloadCertificateFile(string path)
251273
252274 using ( MemoryStream stream = new MemoryStream ( ) )
253275 {
254- client . Download ( FormatFTPPath ( downloadPath ) , stream ) ;
276+ client . Download ( FormatFTPPath ( downloadPath , false ) , stream ) ;
255277 rtnStore = stream . ToArray ( ) ;
256278 }
257279 }
@@ -283,7 +305,7 @@ public override byte[] DownloadCertificateFile(string path)
283305
284306 using ( MemoryStream stream = new MemoryStream ( ) )
285307 {
286- client . DownloadFile ( FormatFTPPath ( downloadPath ) , stream ) ;
308+ client . DownloadFile ( FormatFTPPath ( downloadPath , ! IsStoreServerLinux ) , stream ) ;
287309 rtnStore = stream . ToArray ( ) ;
288310 }
289311 }
@@ -300,7 +322,7 @@ public override byte[] DownloadCertificateFile(string path)
300322 }
301323 }
302324
303- if ( ! string . IsNullOrEmpty ( ApplicationSettings . SeparateUploadFilePath ) )
325+ if ( ! string . IsNullOrEmpty ( ApplicationSettings . SeparateUploadFilePath ) && IsStoreServerLinux )
304326 {
305327 RunCommand ( $ "rm { downloadPath } ", null , ApplicationSettings . UseSudo , null ) ;
306328 }
@@ -322,8 +344,13 @@ public override void CreateEmptyStoreFile(string path, string linuxFilePermissio
322344 linuxFileGroup = linuxGroupOwner [ 1 ] ;
323345 }
324346
325- AreLinuxPermissionsValid ( linuxFilePermissions ) ;
326- RunCommand ( $ "install -m { linuxFilePermissions } -o { linuxFileOwner } -g { linuxFileGroup } /dev/null { path } ", null , ApplicationSettings . UseSudo , null ) ;
347+ if ( IsStoreServerLinux )
348+ {
349+ AreLinuxPermissionsValid ( linuxFilePermissions ) ;
350+ RunCommand ( $ "install -m { linuxFilePermissions } -o { linuxFileOwner } -g { linuxFileGroup } /dev/null { path } ", null , ApplicationSettings . UseSudo , null ) ;
351+ }
352+ else
353+ RunCommand ( $@ "Out-File -FilePath ""{ path } """, null, false, null);
327354
328355 _logger.MethodExit(LogLevel.Debug);
329356 }
@@ -332,14 +359,15 @@ public override bool DoesFileExist(string path)
332359 {
333360 _logger . MethodEntry ( LogLevel . Debug ) ;
334361 _logger. LogDebug ( $ "DoesFileExist: { path } ") ;
335-
362+
336363 using ( SftpClient client = new SftpClient ( Connection ) )
337364 {
338365 try
339366 {
340367 client. Connect ( ) ;
341- string existsPath = FormatFTPPath ( path ) ;
368+ string existsPath = FormatFTPPath( path, false ) ;
342369 bool exists = client. Exists ( existsPath ) ;
370+ _logger. LogDebug ( existsPath ) ;
343371
344372 _logger. MethodExit ( LogLevel . Debug ) ;
345373
@@ -406,12 +434,14 @@ private string ConvertToPKCS1(string privateKey)
406434 return pemString. Replace ( "PRIVATE" , "RSA PRIVATE" ) ;
407435 }
408436
409- private string FormatFTPPath ( string path )
437+ private string FormatFTPPath( string path , bool addLeadingSlashForWindows )
410438 {
411439 _logger. MethodEntry ( LogLevel . Debug ) ;
412440 _logger. MethodExit ( LogLevel . Debug ) ;
413441
414- return path . Substring ( 0 , 1 ) == @"/" ? path : @"/" + path . Replace ( "\\ " , "/" ) ;
442+ string rtnPath = IsStoreServerLinux ? path : path . Replace ( "\\ " , "/" ) ;
443+ _logger. LogTrace ( $ "Formatted path: { rtnPath } ") ;
444+ return addLeadingSlashForWindows ? rtnPath : "/" + rtnPath;
415445 }
416446 }
417447}
0 commit comments