mirror of
https://github.com/whoeevee/ivinject.git
synced 2026-01-08 23:25:03 +00:00
136 lines
4.8 KiB
C#
136 lines
4.8 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using ivinject.Features.Codesigning;
|
|
using ivinject.Features.Command.Models;
|
|
using ivinject.Features.Injection;
|
|
using ivinject.Features.Injection.Models;
|
|
using ivinject.Features.Packaging;
|
|
using ivinject.Features.Packaging.Models;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace ivinject.Features.Command;
|
|
|
|
internal class IviRootCommandProcessor
|
|
{
|
|
private readonly ILogger _logger;
|
|
private readonly PackageManager _packageManager;
|
|
private readonly InjectionManager _injectionManager;
|
|
private readonly CodesigningManager _codesigningManager;
|
|
|
|
internal IviRootCommandProcessor()
|
|
{
|
|
var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
|
|
|
|
_logger = loggerFactory.CreateLogger("Main");
|
|
_packageManager = new PackageManager(
|
|
loggerFactory.CreateLogger("PackageManager")
|
|
);
|
|
_injectionManager = new InjectionManager(
|
|
loggerFactory.CreateLogger("InjectionManager")
|
|
);
|
|
_codesigningManager = new CodesigningManager(
|
|
loggerFactory.CreateLogger("CodesigningManager")
|
|
);
|
|
}
|
|
|
|
[SuppressMessage("Usage", "CA2254")]
|
|
private void CriticalError(string? message, params object?[] args)
|
|
{
|
|
_logger.LogCritical(message, args);
|
|
Environment.Exit(1);
|
|
}
|
|
|
|
private async Task InjectEntries(IEnumerable<IviInjectionEntry> injectionEntries)
|
|
{
|
|
await _injectionManager.AddEntriesAsync(injectionEntries);
|
|
|
|
if (!await _injectionManager.ThinCopiedBinariesAsync())
|
|
CriticalError("Unable to thin one or more binaries.");
|
|
|
|
await _injectionManager.CopyKnownFrameworksAsync();
|
|
await _injectionManager.FixCopiedDependenciesAsync();
|
|
}
|
|
|
|
private async Task CheckForEncryptedBinaries(IviPackageInfo packageInfo)
|
|
{
|
|
var encryptionInfo = await _codesigningManager.GetEncryptionStateAsync();
|
|
|
|
if (encryptionInfo.IsMainBinaryEncrypted)
|
|
CriticalError("The main application binary, {}, is encrypted.", packageInfo.MainBinary.Name);
|
|
|
|
if (encryptionInfo.EncryptedBinaries.Any())
|
|
{
|
|
var encryptedPaths = encryptionInfo.EncryptedBinaries.Select(binary =>
|
|
Path.GetRelativePath(packageInfo.DirectoriesInfo.BundleDirectory, binary.FullName)
|
|
);
|
|
|
|
_logger.LogError(
|
|
"The app package contains encrypted binaries. Consider removing them: \n{}",
|
|
string.Join("\n", encryptedPaths)
|
|
);
|
|
}
|
|
}
|
|
|
|
private async Task ProcessSigning(IviSigningInfo? signingInfo)
|
|
{
|
|
var hasIdentity = signingInfo is not null;
|
|
var isAdHocSigning = signingInfo?.IsAdHocSigning ?? false;
|
|
var hasEntitlements = signingInfo?.Entitlements is not null;
|
|
|
|
if (hasIdentity && !isAdHocSigning && !hasEntitlements)
|
|
CriticalError("Entitlements are required for non ad hoc identity signing.");
|
|
|
|
if (hasIdentity)
|
|
{
|
|
if (!await _codesigningManager.SaveMainExecutablesEntitlementsAsync())
|
|
{
|
|
_logger.LogError(
|
|
"Unable to save entitlements for one or more binaries. The package is likely unsigned, and all specified entitlements will be applied."
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!await _codesigningManager.RemoveSignatureAsync())
|
|
CriticalError("Unable to remove signature from one or more binaries.");
|
|
|
|
await _injectionManager.InsertLoadCommandsAsync();
|
|
|
|
if (hasIdentity)
|
|
{
|
|
if (!await _codesigningManager.SignPackageAsync(signingInfo!))
|
|
CriticalError("Unable to sign one or more binaries.");
|
|
}
|
|
}
|
|
|
|
internal async Task ProcessRootCommand(IviParameters parameters)
|
|
{
|
|
_packageManager.LoadAppPackage(parameters.TargetAppPackage);
|
|
_logger.LogInformation("Loaded app package");
|
|
|
|
var packageInfo = _packageManager.PackageInfo;
|
|
|
|
if (parameters.PackagingInfo is { } packagingInfo)
|
|
await _packageManager.PerformPackageModifications(packagingInfo);
|
|
|
|
//
|
|
|
|
_injectionManager.UpdateWithPackage(packageInfo);
|
|
await InjectEntries(parameters.InjectionEntries);
|
|
|
|
_codesigningManager.UpdateWithPackage(packageInfo);
|
|
await CheckForEncryptedBinaries(packageInfo);
|
|
|
|
await ProcessSigning(parameters.SigningInfo);
|
|
|
|
if (!_packageManager.CreateAppPackage(
|
|
parameters.OutputAppPackage,
|
|
parameters.OverwriteOutput,
|
|
parameters.CompressionLevel
|
|
))
|
|
CriticalError(
|
|
"The app package couldn't be created. If it already exists, use --overwrite to replace."
|
|
);
|
|
|
|
_codesigningManager.Dispose();
|
|
_packageManager.Dispose();
|
|
}
|
|
} |