static int VerifySignatures( Dictionary <string, FileMapTarget> fileMap, ExclusionSet exclusions, string exclusionsBootstrapReason) { int totalUnsigned = 0; int i = 0; foreach (var entry in fileMap) { var extension = Path.GetExtension(entry.Value.SourcePath).ToLowerInvariant(); VerifyResult result; if (exclusions.Contains(entry.Value.InstallPath)) { result = VerifyResult.Excluded; } else if (extensionsToCheck.Contains(extension)) { result = WinTrust.VerifyAuthenticodeTrust( entry.Value.SourcePath) == SignatureVerificationResult.Valid ? VerifyResult.Signed : VerifyResult.Unsigned; } else { result = VerifyResult.Skipped; } var level = LogEventLevel.Verbose; switch (result) { case VerifyResult.Unsigned: if (exclusionsBootstrapReason != null) { exclusions.Bootstrap(entry.Value.InstallPath, exclusionsBootstrapReason); } level = LogEventLevel.Error; totalUnsigned++; break; } Log.Write( level, "[{Is}/{Of}] {Result}: {Id} → {InstallPath}", ++i, fileMap.Count, result, entry.Key, NormalizePath(entry.Value.InstallPath)); } return(totalUnsigned); }
public bool Match(IEntity entity) { Func <Type, bool> hasComponent = (t => entity.HasComponent(t)); if (ExclusionSet.Any(hasComponent)) { return(false); } if (!AllSet.All(hasComponent)) { return(false); } if (OneSet.Any() && !OneSet.Any(hasComponent)) { return(false); } // Nobody complained so we're good here! return(true); }
static int Main(string [] args) { var loggingLevelSwitch = new LoggingLevelSwitch { MinimumLevel = LogEventLevel.Information }; Log.Logger = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.ControlledBy(loggingLevelSwitch) .CreateLogger(); Console.OutputEncoding = Encoding.UTF8; string workingPath = null; bool cleanWorkingPath = false; string exclusionsFile = null; bool updateExclusionsFile = false; string exclusionsBootstrapReason = null; bool showHelp = false; string msiFile = null; Exception optionsError = null; var optionSet = new OptionSet { { "o|output=", "Output path for intermediate work", v => workingPath = v }, { "x|exclude=", "Path to an exclusions JSON file (see below for format)", v => exclusionsFile = v }, { "exclude-update", "Update the exclusions file in place by removing " + "entries in the exclusion file no longer present in the installer.", v => updateExclusionsFile = true }, { "exclude-bootstrap=", "Generate an initial exclusions file based on all unsigned files.", v => exclusionsBootstrapReason = v }, { "v|verbose", "Verbose", v => { switch (loggingLevelSwitch.MinimumLevel) { case LogEventLevel.Debug: loggingLevelSwitch.MinimumLevel = LogEventLevel.Verbose; break; case LogEventLevel.Verbose: break; default: loggingLevelSwitch.MinimumLevel = LogEventLevel.Debug; break; } } }, { "h|?|help", "Show this help", v => showHelp = true } }; try { var remaining = optionSet.Parse(args); switch (remaining.Count) { case 0: throw new Exception("must specify an MSI file to process"); case 1: msiFile = remaining [0]; break; default: throw new Exception("only one MSI file may be specified"); } } catch (Exception e) { showHelp = true; optionsError = e; } if (showHelp) { if (optionsError != null) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine("Error: {0}", optionsError.Message); Console.Error.WriteLine(); Console.ResetColor(); } Console.Error.WriteLine( "Usage: {0} [OPTIONS] MSI_FILE", Path.GetFileName(typeof(Program).Assembly.Location)); Console.Error.WriteLine(); Console.Error.WriteLine("Options:"); optionSet.WriteOptionDescriptions(Console.Error); return(1); } if (workingPath == null) { workingPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); cleanWorkingPath = true; } ExclusionSet exclusions; try { exclusions = new ExclusionSet(exclusionsFile); } catch (Exception e) { Log.Fatal(e, "Error loading exclusions file {ExclusionsFile}", exclusionsFile); return(1); } int totalUnsigned = 0; try { var wxsOutputPath = Path.Combine( workingPath, Path.GetFileNameWithoutExtension(msiFile) + ".wxs"); var extractPath = Path.Combine(workingPath, "contents"); if (!Directory.Exists(extractPath)) { Exec( "wix/dark", Path.Combine(FindWixTools(), "dark.exe"), "-v", "-sui", "-o", wxsOutputPath, "-x", extractPath, msiFile); } var fileMap = GenerateFileMap(wxsOutputPath); foreach (var entry in fileMap) { exclusions.MarkHandled(entry.Value.InstallPath); } var stopwatch = new Stopwatch(); stopwatch.Start(); totalUnsigned = VerifySignatures( fileMap, exclusions, exclusionsBootstrapReason); stopwatch.Stop(); Log.Debug("Signature verification completed: {Duration}", stopwatch.Elapsed); if (exclusionsBootstrapReason != null || updateExclusionsFile) { exclusions.Save(); } } finally { if (cleanWorkingPath) { Log.Debug("Removing working directory {WorkingPath}…", workingPath); Directory.Delete(workingPath, recursive: true); } } if (totalUnsigned > 0) { Log.Error("{TotalUnsigned} unsigned files", totalUnsigned); return(2); } return(0); }