mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Finish up code signing fix, hopefully HSM's will work properly now!
This commit is contained in:
@@ -74,34 +74,15 @@ public class CodeSign
|
||||
}
|
||||
|
||||
var filesToSignStr = String.Join(" ", filesToSign.Select(f => $"\"{f}\""));
|
||||
var command = $"/S /C \"\"{HelperFile.SignToolPath}\" sign {signArguments} {filesToSignStr} >> \"{signLogFile}\" 2>&1\"";
|
||||
|
||||
var psi = new ProcessStartInfo {
|
||||
FileName = "cmd.exe",
|
||||
Arguments = command,
|
||||
UseShellExecute = false,
|
||||
WorkingDirectory = rootDir,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = Process.Start(psi);
|
||||
process.WaitForExit();
|
||||
|
||||
if (process.ExitCode != 0) {
|
||||
var cmdWithPasswordHidden = "cmd.exe " + new Regex(@"\/p\s+?[^\s]+").Replace(command, "/p ********");
|
||||
Log.Debug($"Signing command failed: {cmdWithPasswordHidden}");
|
||||
var output = File.Exists(signLogFile) ? File.ReadAllText(signLogFile).Trim() : "No output file was created.";
|
||||
throw new UserInfoException(
|
||||
$"Signing command failed. Specify --verbose argument to print signing command.\n" +
|
||||
$"Output was:" + Environment.NewLine + output);
|
||||
}
|
||||
var command = $"\"{HelperFile.SignToolPath}\" sign {signArguments} {filesToSignStr}";
|
||||
RunSigningCommand(command, rootDir, signLogFile);
|
||||
|
||||
int processed = totalToSign - pendingSign.Count;
|
||||
Log.Info($"Code-signed {processed}/{totalToSign} files");
|
||||
progress((int) ((double) processed / totalToSign * 100));
|
||||
} while (pendingSign.Count > 0);
|
||||
|
||||
Log.Info("SignTool Output: " + Environment.NewLine + File.ReadAllText(signLogFile).Trim());
|
||||
Log.Debug("SignTool Output: " + Environment.NewLine + File.ReadAllText(signLogFile).Trim());
|
||||
}
|
||||
|
||||
public void SignPEFileWithTemplate(string filePath, string signTemplate)
|
||||
@@ -111,129 +92,38 @@ public class CodeSign
|
||||
return;
|
||||
}
|
||||
|
||||
using var _1 = Utility.GetTempFileName(out var signLogFile);
|
||||
var command = signTemplate.Replace("\"{{file}}\"", "{{file}}").Replace("{{file}}", $"\"{filePath}\"");
|
||||
|
||||
var result = Exe.InvokeProcess(command, null, null);
|
||||
if (result.ExitCode != 0) {
|
||||
var cmdWithPasswordHidden = new Regex(@"\/p\s+?[^\s]+").Replace(result.Command, "/p ********");
|
||||
Log.Debug($"Signing command failed: {cmdWithPasswordHidden}");
|
||||
throw new Exception(
|
||||
$"Signing command failed. Specify --verbose argument to print signing command.\n\n" +
|
||||
$"Output was:\n" + result.StdOutput);
|
||||
}
|
||||
|
||||
Log.Info("Sign successful: " + result.StdOutput);
|
||||
RunSigningCommand(command, Path.GetDirectoryName(filePath), signLogFile);
|
||||
Log.Debug("SignTool Output: " + Environment.NewLine + File.ReadAllText(signLogFile).Trim());
|
||||
}
|
||||
|
||||
//private static ProcessStartInfo CreateProcessStartInfo(string fileName, string arguments, string workingDirectory = "")
|
||||
//{
|
||||
// var psi = new ProcessStartInfo(fileName, arguments);
|
||||
// psi.UseShellExecute = false;
|
||||
// psi.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
// psi.ErrorDialog = false;
|
||||
// psi.CreateNoWindow = true;
|
||||
// psi.RedirectStandardOutput = true;
|
||||
// psi.RedirectStandardError = true;
|
||||
// psi.WorkingDirectory = workingDirectory;
|
||||
// return psi;
|
||||
//}
|
||||
private void RunSigningCommand(string command, string workDir, string signLogFile)
|
||||
{
|
||||
// here we invoke signtool.exe with 'cmd.exe /C' and redirect output to a file, because something
|
||||
// about how the dotnet tool host works prevents signtool from being able to open a token password
|
||||
// prompt, meaning signing fails for those with an HSM.
|
||||
|
||||
//private void SignPEFile(string filePath, string signParams, string signTemplate)
|
||||
//{
|
||||
// try {
|
||||
// if (AuthenticodeTools.IsTrusted(filePath)) {
|
||||
// Log.Debug($"'{filePath}' is already signed, skipping...");
|
||||
// return;
|
||||
// }
|
||||
// } catch (Exception ex) {
|
||||
// Log.Error(ex, "Failed to determine signing status for " + filePath);
|
||||
// }
|
||||
string args = $"/S /C \"{command} >> \"{signLogFile}\" 2>&1\"";
|
||||
|
||||
// string cmd;
|
||||
// ProcessStartInfo psi;
|
||||
// if (!String.IsNullOrEmpty(signParams)) {
|
||||
// // use embedded signtool.exe with provided parameters
|
||||
// cmd = $"sign {signParams} \"{filePath}\"";
|
||||
// psi = CreateProcessStartInfo(HelperFile.SignToolPath, cmd);
|
||||
// cmd = "signtool.exe " + cmd;
|
||||
// } else if (!String.IsNullOrEmpty(signTemplate)) {
|
||||
// // escape custom sign command and pass it to cmd.exe
|
||||
// cmd = signTemplate.Replace("\"{{file}}\"", "{{file}}").Replace("{{file}}", $"\"{filePath}\"");
|
||||
// psi = CreateProcessStartInfo("cmd", $"/c {EscapeCmdExeMetachars(cmd)}");
|
||||
// } else {
|
||||
// Log.Debug($"{filePath} was not signed. (skipped; no signing parameters)");
|
||||
// return;
|
||||
// }
|
||||
var psi = new ProcessStartInfo {
|
||||
FileName = "cmd.exe",
|
||||
Arguments = args,
|
||||
UseShellExecute = false,
|
||||
WorkingDirectory = workDir,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
|
||||
// var processResult = InvokeProcessUnsafeAsync(psi, CancellationToken.None)
|
||||
// .ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
var process = Process.Start(psi);
|
||||
process.WaitForExit();
|
||||
|
||||
// if (processResult.ExitCode != 0) {
|
||||
// var cmdWithPasswordHidden = new Regex(@"/p\s+\w+").Replace(cmd, "/p ********");
|
||||
// throw new Exception("Signing command failed: \n > " + cmdWithPasswordHidden + "\n" + processResult.StdOutput);
|
||||
// } else {
|
||||
// Log.Info("Sign successful: " + processResult.StdOutput);
|
||||
// }
|
||||
//}
|
||||
|
||||
//private static string EscapeCmdExeMetachars(string command)
|
||||
//{
|
||||
// var result = new StringBuilder();
|
||||
// foreach (var ch in command) {
|
||||
// switch (ch) {
|
||||
// case '(':
|
||||
// case ')':
|
||||
// case '%':
|
||||
// case '!':
|
||||
// case '^':
|
||||
// case '"':
|
||||
// case '<':
|
||||
// case '>':
|
||||
// case '&':
|
||||
// case '|':
|
||||
// result.Append('^');
|
||||
// break;
|
||||
// }
|
||||
// result.Append(ch);
|
||||
// }
|
||||
// return result.ToString();
|
||||
//}
|
||||
|
||||
//private class ProcessResult
|
||||
//{
|
||||
// public int ExitCode { get; set; }
|
||||
// public string StdOutput { get; set; }
|
||||
|
||||
// public ProcessResult(int exitCode, string stdOutput)
|
||||
// {
|
||||
// ExitCode = exitCode;
|
||||
// StdOutput = stdOutput;
|
||||
// }
|
||||
//}
|
||||
|
||||
//private static async Task<ProcessResult> InvokeProcessUnsafeAsync(ProcessStartInfo psi, CancellationToken ct)
|
||||
//{
|
||||
// var pi = Process.Start(psi);
|
||||
// await Task.Run(() => {
|
||||
// while (!ct.IsCancellationRequested) {
|
||||
// if (pi.WaitForExit(2000)) return;
|
||||
// }
|
||||
|
||||
// if (ct.IsCancellationRequested) {
|
||||
// pi.Kill();
|
||||
// ct.ThrowIfCancellationRequested();
|
||||
// }
|
||||
// }).ConfigureAwait(false);
|
||||
|
||||
// string textResult = await pi.StandardOutput.ReadToEndAsync().ConfigureAwait(false);
|
||||
// if (String.IsNullOrWhiteSpace(textResult) || pi.ExitCode != 0) {
|
||||
// textResult = (textResult ?? "") + "\n" + await pi.StandardError.ReadToEndAsync().ConfigureAwait(false);
|
||||
|
||||
// if (String.IsNullOrWhiteSpace(textResult)) {
|
||||
// textResult = String.Empty;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return new ProcessResult(pi.ExitCode, textResult.Trim());
|
||||
//}
|
||||
if (process.ExitCode != 0) {
|
||||
var cmdWithPasswordHidden = "cmd.exe " + new Regex(@"\/p\s+?[^\s]+").Replace(command, "/p ********");
|
||||
Log.Debug($"Signing command failed: {cmdWithPasswordHidden}");
|
||||
var output = File.Exists(signLogFile) ? File.ReadAllText(signLogFile).Trim() : "No output file was created.";
|
||||
throw new UserInfoException(
|
||||
$"Signing command failed. Specify --verbose argument to print signing command." + Environment.NewLine +
|
||||
$"Output was:" + Environment.NewLine + output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,11 @@ public class WindowsPackCommandRunner : PackageBuilder<WindowsPackOptions>
|
||||
if (!VelopackRuntimeInfo.IsWindows) return;
|
||||
|
||||
if (!string.IsNullOrEmpty(signParams)) {
|
||||
Log.Info($"Preparing to sign {filePaths.Length} files with embedded signtool.exe with parallelism of {signParallel}");
|
||||
string message = $"Preparing to sign {filePaths.Length} files with embedded signtool.exe";
|
||||
if (signParallel > 1 && filePaths.Length > 1) {
|
||||
message += $" with parallelism of {signParallel}";
|
||||
}
|
||||
Log.Info(message);
|
||||
helper.SignPEFilesWithSignTool(rootDir, filePaths, signParams, signParallel, progress);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user