Skip to content

Commit 0d78768

Browse files
authored
Merge branch 'ab#55565' into release-2.6
2 parents 8748d2a + 11cb684 commit 0d78768

File tree

6 files changed

+242
-40
lines changed

6 files changed

+242
-40
lines changed

RemoteFile/RemoteCertificateStore.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@
2323
using Keyfactor.Extensions.Orchestrator.RemoteFile.Models;
2424
using Keyfactor.Logging;
2525
using System.Management.Automation;
26+
using System.Runtime.InteropServices;
27+
using Microsoft.CodeAnalysis.CSharp.Syntax;
2628

2729
namespace Keyfactor.Extensions.Orchestrator.RemoteFile
2830
{
2931
internal class RemoteCertificateStore
3032
{
3133
private const string NO_EXTENSION = "noext";
3234
private const string FULL_SCAN = "fullscan";
35+
private const string LOCAL_MACHINE_SUFFIX = "|localmachine";
3336

3437
internal enum ServerTypeEnum
3538
{
@@ -340,10 +343,12 @@ internal void Initialize(string sudoImpersonatedUser)
340343
{
341344
logger.MethodEntry(LogLevel.Debug);
342345

343-
if (ServerType == ServerTypeEnum.Linux)
344-
RemoteHandler = new SSHHandler(Server, ServerId, ServerPassword, sudoImpersonatedUser);
346+
bool treatAsLocal = Server.ToLower().EndsWith(LOCAL_MACHINE_SUFFIX);
347+
348+
if (ServerType == ServerTypeEnum.Linux || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
349+
RemoteHandler = treatAsLocal ? new LinuxLocalHandler() as IRemoteHandler : new SSHHandler(Server, ServerId, ServerPassword, ServerType == ServerTypeEnum.Linux) as IRemoteHandler;
345350
else
346-
RemoteHandler = new WinRMHandler(Server, ServerId, ServerPassword);
351+
RemoteHandler = new WinRMHandler(Server, ServerId, ServerPassword, treatAsLocal);
347352

348353
RemoteHandler.Initialize();
349354

@@ -389,10 +394,10 @@ private List<string> FindStoresLinux(string[] paths, string[] extensions, string
389394
{
390395
foreach (string fileName in fileNames)
391396
{
392-
command += (command.IndexOf("-iname") == -1 ? string.Empty : "-or ");
393-
command += $"-iname '{fileName.Trim()}";
397+
command += (command.IndexOf("-name") == -1 ? string.Empty : "-or ");
398+
command += $"-name '{fileName.Trim()}";
394399
if (extension.ToLower() == NO_EXTENSION)
395-
command += $"' ! -iname '*.*' ";
400+
command += $"' ! -name '*.*' ";
396401
else
397402
command += $".{extension.Trim()}' ";
398403
}

RemoteFile/RemoteFile.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,22 @@
66
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
77
</PropertyGroup>
88

9+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
10+
<DebugType>none</DebugType>
11+
</PropertyGroup>
12+
13+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
14+
<DebugType>none</DebugType>
15+
</PropertyGroup>
16+
917
<ItemGroup>
1018
<Compile Remove="ImplementedStoreTypes\JKS\JksStore.cs" />
1119
<Compile Remove="RemoteHandlers\SSHHelper.cs" />
1220
</ItemGroup>
1321

1422
<ItemGroup>
1523
<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.0" />
24+
<PackageReference Include="CliWrap" Version="3.6.6" />
1625
<PackageReference Include="Keyfactor.Logging" Version="1.1.1" />
1726
<PackageReference Include="Keyfactor.Orchestrators.IOrchestratorJobExtensions" Version="0.7.0" />
1827
<PackageReference Include="Keyfactor.PKI" Version="5.0.0" />

RemoteFile/RemoteHandlers/BaseRemoteHandler.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Keyfactor.Logging;
99

1010
using Microsoft.Extensions.Logging;
11+
using System.Text.RegularExpressions;
1112

1213
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers
1314
{
@@ -16,6 +17,7 @@ abstract class BaseRemoteHandler : IRemoteHandler
1617
internal ILogger _logger;
1718
internal const string PASSWORD_MASK_VALUE = "[PASSWORD]";
1819
internal const int PASSWORD_LENGTH_MAX = 100;
20+
internal const string LINUX_PERMISSION_REGEXP = "^[0-7]{3}$";
1921

2022
public string Server { get; set; }
2123

@@ -24,6 +26,13 @@ public BaseRemoteHandler()
2426
_logger = LogHandler.GetClassLogger(this.GetType());
2527
}
2628

29+
public static void AreLinuxPermissionsValid(string permissions)
30+
{
31+
Regex regex = new Regex(LINUX_PERMISSION_REGEXP);
32+
if (!regex.IsMatch(permissions))
33+
throw new RemoteFileException($"Invalid format for Linux file permissions. This value must be exactly 3 digits long with each digit between 0-7 but found {permissions} instead.");
34+
}
35+
2736
public abstract void Initialize();
2837

2938
public abstract void Terminate();
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// Copyright 2021 Keyfactor
2+
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
3+
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4+
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
6+
// and limitations under the License.
7+
8+
using System;
9+
using System.IO;
10+
using System.Security.Cryptography;
11+
12+
using CliWrap;
13+
using CliWrap.Buffered;
14+
15+
using Renci.SshNet;
16+
17+
using Microsoft.Extensions.Logging;
18+
19+
using Keyfactor.Logging;
20+
using Keyfactor.PKI.PrivateKeys;
21+
using Keyfactor.PKI.PEM;
22+
23+
namespace Keyfactor.Extensions.Orchestrator.RemoteFile.RemoteHandlers
24+
{
25+
class LinuxLocalHandler : BaseRemoteHandler
26+
{
27+
private Command BaseCommand { get; set; }
28+
29+
internal LinuxLocalHandler()
30+
{
31+
_logger.MethodEntry(LogLevel.Debug);
32+
_logger.MethodExit(LogLevel.Debug);
33+
}
34+
35+
public override void Initialize()
36+
{
37+
_logger.MethodEntry(LogLevel.Debug);
38+
39+
BaseCommand = Cli.Wrap("/bin/bash");
40+
41+
_logger.MethodExit(LogLevel.Debug);
42+
}
43+
44+
public override void Terminate()
45+
{
46+
_logger.MethodEntry(LogLevel.Debug);
47+
_logger.MethodExit(LogLevel.Debug);
48+
}
49+
50+
public override string RunCommand(string commandText, object[] arguments, bool withSudo, string[] passwordsToMaskInLog)
51+
{
52+
_logger.MethodEntry(LogLevel.Debug);
53+
54+
string sudo = $"echo -e '\n' | sudo -i -S ";
55+
56+
try
57+
{
58+
if (withSudo)
59+
commandText = sudo + commandText;
60+
61+
string displayCommand = commandText;
62+
if (passwordsToMaskInLog != null)
63+
{
64+
foreach (string password in passwordsToMaskInLog)
65+
displayCommand = displayCommand.Replace(password, PASSWORD_MASK_VALUE);
66+
}
67+
68+
_logger.LogDebug($"RunCommand: {displayCommand}");
69+
70+
Command cmd = BaseCommand.WithArguments($@"-c ""{commandText}""");
71+
BufferedCommandResult result = cmd.ExecuteBufferedAsync().GetAwaiter().GetResult();
72+
73+
_logger.LogDebug($"Linux Local Results: {displayCommand}::: {result.StandardOutput}::: {result.StandardError}");
74+
75+
if (!String.IsNullOrEmpty(result.StandardError))
76+
throw new ApplicationException(result.StandardError);
77+
78+
_logger.MethodExit(LogLevel.Debug);
79+
80+
return result.StandardOutput;
81+
}
82+
catch (Exception ex)
83+
{
84+
_logger.LogError($"Exception during RunCommand...{RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}");
85+
throw ex;
86+
}
87+
}
88+
89+
public override void UploadCertificateFile(string path, string fileName, byte[] certBytes)
90+
{
91+
_logger.MethodEntry(LogLevel.Debug);
92+
_logger.LogDebug($"UploadCertificateFile: {path}{fileName}");
93+
94+
string uploadPath = path+fileName;
95+
96+
try
97+
{
98+
File.WriteAllBytes(uploadPath, certBytes);
99+
}
100+
catch (Exception ex)
101+
{
102+
_logger.LogError($"Error attempting upload file to {uploadPath}...");
103+
_logger.LogError($"Upload Exception: {RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}");
104+
throw new RemoteFileException($"Error attempting upload file to {uploadPath}.", ex);
105+
}
106+
107+
_logger.MethodExit(LogLevel.Debug);
108+
}
109+
110+
public override byte[] DownloadCertificateFile(string path)
111+
{
112+
_logger.MethodEntry(LogLevel.Debug);
113+
_logger.LogDebug($"DownloadCertificateFile: {path}");
114+
115+
byte[] rtnStore = new byte[] { };
116+
117+
try
118+
{
119+
rtnStore = File.ReadAllBytes(path);
120+
}
121+
catch (Exception ex)
122+
{
123+
_logger.LogError($"Error attempting download file {path}...");
124+
_logger.LogError($"Download Exception: {RemoteFileException.FlattenExceptionMessages(ex, ex.Message)}");
125+
throw new RemoteFileException($"Error attempting download file {path}.", ex);
126+
}
127+
128+
_logger.MethodExit(LogLevel.Debug);
129+
130+
return rtnStore;
131+
}
132+
133+
public override void CreateEmptyStoreFile(string path, string linuxFilePermissions, string linuxFileOwner)
134+
{
135+
_logger.MethodEntry(LogLevel.Debug);
136+
string[] linuxGroupOwner = linuxFileOwner.Split(":");
137+
string linuxFileGroup = linuxFileOwner;
138+
139+
if (linuxGroupOwner.Length == 2)
140+
{
141+
linuxFileOwner = linuxGroupOwner[0];
142+
linuxFileGroup = linuxGroupOwner[1];
143+
}
144+
145+
AreLinuxPermissionsValid(linuxFilePermissions);
146+
RunCommand($"install -m {linuxFilePermissions} -o {linuxFileOwner} -g {linuxFileGroup} /dev/null {path}", null, ApplicationSettings.UseSudo, null);
147+
148+
_logger.MethodExit(LogLevel.Debug);
149+
}
150+
151+
public override bool DoesFileExist(string path)
152+
{
153+
_logger.MethodEntry(LogLevel.Debug);
154+
_logger.LogDebug($"DoesFileExist: {path}");
155+
156+
return File.Exists(path);
157+
}
158+
159+
public override void RemoveCertificateFile(string path, string fileName)
160+
{
161+
_logger.LogDebug($"RemoveCertificateFile: {path} {fileName}");
162+
163+
RunCommand($"rm {path}{fileName}", null, ApplicationSettings.UseSudo, null);
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)