public TestEngineResult RunAllTests(string file, IReadOnlyList <ICmsSignature> signatures, List <ITestResultCollector> collectors, CheckConfiguration configuration)
        {
            var verbose           = configuration.Verbose;
            var suppressedTestIDs = configuration.SuppressErrorIDs;
            var tests             = GetTests();
            var engineResult      = TestEngineResult.AllPass;

            collectors.ForEach(c => c.BeginSet(file));
            Boolean dontInsertRulesTable = false;
            string  portal     = "";
            var     digestStr  = "";
            string  appID      = "";
            string  fileName   = "";
            string  thumbprint = "";

            foreach (var test in tests)
            {
                TestResult result;
                var        verboseWriter = verbose ? new MemorySignatureLogger() : SignatureLogger.Null;
                if (signatures.Count == 0)
                {
                    result = TestResult.Fail;
                    verboseWriter.LogMessage("File is not Authenticode signed.");
                    dontInsertRulesTable = true;
                }
                else
                {
                    if (suppressedTestIDs.Contains(test.Test))
                    {
                        result = TestResult.Skip;
                    }
                    else if ((test.TestSet & configuration.TestSet) == 0)
                    {
                        result = TestResult.Excluded;
                    }
                    else
                    {
                        switch (test)
                        {
                        case IAuthenticodeFileTest fileTest:
                            result = fileTest.Validate(file, verboseWriter, configuration);
                            break;

                        case IAuthenticodeSignatureTest sigTest:
                            result = sigTest.Validate(signatures, verboseWriter, configuration);
                            break;

                        default:
                            throw new NotSupportedException("Test type is not supported.");
                        }
                    }
                }
                if (result == TestResult.Fail)
                {
                    engineResult = TestEngineResult.NotAllPass;
                }
                if (!dontInsertRulesTable)
                {
                    digestStr = HashHelpers.GetHashForSignature(signatures[0]);//message digest of siganture(signature->details->advance->msg digest)

                    appID      = Program.fileName;
                    fileName   = Program.fileName;
                    portal     = Program.portalName;
                    thumbprint = signatures[0].Certificate.Thumbprint;
                }
                collectors.ForEach(c => c.CollectResult(test, result, verboseWriter.Messages, dontInsertRulesTable, appID, fileName, digestStr, thumbprint, portal));
            }
            if (configuration.ExtractPath != null)
            {
                Extraction.ExtractToDisk(file, configuration, signatures);
            }
            collectors.ForEach(c => c.CompleteSet());
            return(engineResult);
        }
Exemple #2
0
        static async Task Main(string[] args)
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Console.Error.WriteLine("AuthenticodeLint is only supported on Windows.");
                //return ExitCodes.PlatformNotSupported;
            }
            var cli = Environment.CommandLine;
            List <CommandLineParameter> parsedCommandLine;

            try
            {
                var commandLine = CommandLineParser.LexCommandLine(cli).Skip(1);
                parsedCommandLine = CommandLineParser.CreateCommandLineParametersWithValues(commandLine).ToList();
            }
            catch (InvalidOperationException)
            {
                parsedCommandLine = null;
            }

            if (parsedCommandLine == null || parsedCommandLine.Count == 0 || parsedCommandLine.Any(cl => cl.Name == "help"))
            {
                ShowHelp();
                //Avoid returning success for printing help so that automated build systems do not interpret "show the help"
                //As a successful build incase the build system is incorrectly passing arguments.
                //return ExitCodes.InvalidInputOrConfig;
            }
            var    inputs     = new List <string>();
            var    suppress   = new HashSet <int>();
            bool   quiet      = false;
            bool   verbose    = false;
            string report     = null;
            string extract    = null;
            var    revocation = RevocationChecking.None;
            var    testSet    = TestSet.All;

            foreach (var parameter in parsedCommandLine)
            {
                if (parameter.Name == "vt")
                {
                    vt = true;
                }
                else if (parameter.Name == "in")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine("A value is required for input.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    var filePattern = Path.GetFileName(parameter.Value);
                    //The value contains a pattern.
                    if (filePattern.Contains("*") || filePattern.Contains("?"))
                    {
                        var directory = Path.GetDirectoryName(parameter.Value);
                        if (Directory.Exists(directory))
                        {
                            var files = Directory.GetFiles(directory, filePattern, SearchOption.TopDirectoryOnly);
                            inputs.AddRange(files);
                        }
                    }
                    else
                    {
                        inputs.Add(parameter.Value);
                    }
                }
                else if (parameter.Name == "validate")
                {
                    validate = parameter.Value;
                }
                else if (parameter.Name == "portal")
                {
                    portalName = parameter.Value;
                }
                else if (parameter.Name == "app")
                {
                    appName = parameter.Value;
                }
                else if (parameter.Name == "type")
                {
                    fileType = parameter.Value;
                }
                else if (parameter.Name == "number")
                {
                    fileNumber = Int32.Parse(parameter.Value);
                }
                else if (parameter.Name == "suppress")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        ShowInvalidSuppression();
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    foreach (var idString in parameter.Value.Split(',').Select(p => p.Trim()))
                    {
                        int id;
                        if (int.TryParse(idString, out id))
                        {
                            suppress.Add(id);
                        }
                        else
                        {
                            Console.Error.WriteLine($"{idString} is not a valid error ID.");
                            return;// ExitCodes.InvalidInputOrConfig;
                        }
                    }
                }
                else if (parameter.Name == "q" || parameter.Name == "quiet")
                {
                    if (!string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} does not expect a value.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    quiet = true;
                }
                else if (parameter.Name == "verbose")
                {
                    if (!string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} does not expect a value.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    verbose = true;
                }

                else if (parameter.Name == "report")
                {
                    report = parameter.Value;
                }
                else if (parameter.Name == "extract")
                {
                    extract = parameter.Value;
                }
                else if (parameter.Name == "revocation")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} requires a value if specified.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    if (!Enum.TryParse(parameter.Value, true, out revocation))
                    {
                        Console.Error.WriteLine($"-{parameter.Value} is an unrecognized revocation mode.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                }
                else if (parameter.Name == "testset")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} requires a value if specified.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    if (!Enum.TryParse(parameter.Value, true, out testSet) || parameter.Value.Equals("all", StringComparison.OrdinalIgnoreCase))
                    {
                        Console.Error.WriteLine($"-{parameter.Value} is an unrecognized testset.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                }
                else
                {
                    Console.Error.WriteLine($"-{parameter.Name} is an unknown parameter.");
                    return;// ExitCodes.InvalidInputOrConfig;
                }
            }
            if (inputs.Count == 0)
            {
                Console.Error.WriteLine("Input is expected. See -help for usage.");
                return;// ExitCodes.InvalidInputOrConfig;
            }
            var configuration = new CheckConfiguration(inputs, report, quiet, suppress, verbose, revocation, extract, testSet);

            if (!ConfigurationValidator.ValidateAndPrint(configuration, Console.Error))
            {
                return;// ExitCodes.InvalidInputOrConfig;
            }
            var collectors = new List <ITestResultCollector>();

            if (!quiet)
            {
                collectors.Add(new StdOutTestResultCollector());
            }
            if (!string.IsNullOrWhiteSpace(report))
            {
                collectors.Add(new XmlTestResultCollector(report));
            }
            var result = ExitCodes.Success;

            foreach (var file in inputs)
            {
                filePath = Path.GetFullPath(file);
                if (!vt && validate.Equals(""))
                {
                    var signatures    = SignatureTreeInspector.Extract(file);
                    var verboseWriter = verbose ? new MemorySignatureLogger() : SignatureLogger.Null;
                    fileName = Path.GetFileName(file);
                    if (signatures.Count == 0)
                    {
                        DBConnect.InsertApplicationTable(appName, fileName, portalName, 0, fileType, fileNumber);
                        verboseWriter.LogMessage("File is not Authenticode signed.");
                    }
                    else
                    {
                        DBConnect.InsertApplicationTable(appName, fileName, portalName, 1, fileType, fileNumber);
                        signed = true;
                    }
                    if (CheckEngine.Instance.RunAllTests(file, signatures, collectors, configuration) != TestEngineResult.AllPass)
                    {
                        result = ExitCodes.ChecksFailed;
                    }
                }
                else
                {
                    fileName = Path.GetFileName(file);
                    filePath = Path.GetFullPath(file);
                    if (vt)
                    {
                        await VTChecker.GetScanReportForFile();
                    }

                    /*  else if (validate.Equals("signature"))
                     *    Validation.validate(fileName, signatureIndex, thumbprint);*/
                }
            }
            collectors.ForEach(c => c.Flush());
            return;// result;
        }