private void ConfigureCompareType()
 {
     if (!Enum.TryParse(_options.TestType, true, out _arg_tagTestType))
     {
         throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_ARG_VALUE, _options.TestType));
     }
 }
        /// <summary>
        /// Option for DLL use as alternate to Run which only outputs a file to return results as string
        /// CommandOption defaults will not have been set when used as DLL via CLI processing so some checks added
        /// </summary>
        /// <returns>output results</returns>
        public VerifyRulesResult GetResult()
        {
            WriteOnce.SafeLog("VerifyRulesCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Verify Rules"));

            VerifyRulesResult verifyRulesResult = new VerifyRulesResult()
            {
                AppVersion = Utils.GetVersionString()
            };

            try
            {
                RulesVerifier verifier = new RulesVerifier(_rules_path, _options.Log);
                verifyRulesResult.ResultCode     = VerifyRulesResult.ExitCode.Verified;
                verifyRulesResult.RuleStatusList = verifier.Verify();
                verifyRulesResult.ResultCode     = verifier.IsVerified ? VerifyRulesResult.ExitCode.Verified : VerifyRulesResult.ExitCode.NotVerified;
            }
            catch (OpException e)
            {
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }

            return(verifyRulesResult);
        }
        /// <summary>
        /// Intentional as no identified value in calling from DLL at this time
        /// </summary>
        /// <returns></returns>
        public PackRulesResult GetResult()
        {
            WriteOnce.SafeLog("PackRules::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Pack Rules"));

            if (!Utils.CLIExecutionContext)
            { //requires output format and filepath only supported via CLI use
                WriteOnce.Error("Command not supported for DLL calls");
                throw new Exception("Command not supported for DLL calls");
            }

            PackRulesResult packRulesResult = new PackRulesResult()
            {
                AppVersion = Utils.GetVersionString()
            };

            try
            {
                RulesVerifier verifier = new RulesVerifier(_rules_path, _options.Log);
                verifier.Verify();
                packRulesResult.Rules = new List <Rule>(verifier.CompiledRuleset.AsEnumerable());

                packRulesResult.ResultCode = PackRulesResult.ExitCode.Success;
            }
            catch (OpException e)
            {
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }

            return(packRulesResult);
        }
        public void ConfigureRules()
        {
            WriteOnce.SafeLog("TagTestCommand::ConfigRules", LogLevel.Trace);

            if (string.IsNullOrEmpty(_options.CustomRulesPath))
            {
                throw new OpException(MsgHelp.GetString(MsgHelp.ID.CMD_NORULES_SPECIFIED));
            }

            try
            {
                RulesVerifier verifier = new RulesVerifier(_options.CustomRulesPath, _options.Log);
                verifier.Verify();

                _rulesSet = verifier.CompiledRuleset;
            }
            catch (Exception e)
            {
                WriteOnce.SafeLog(e.Message + "\n" + e.StackTrace, NLog.LogLevel.Error);
                throw new OpException(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULE_FAILED, _options.CustomRulesPath));
            }

            //error check based on ruleset not path enumeration
            if (_rulesSet.Count() == 0)
            {
                throw new OpException(MsgHelp.GetString(MsgHelp.ID.CMD_NORULES_SPECIFIED));
            }
        }
        /// <summary>
        /// Intentional as no identified value in calling from DLL at this time
        /// </summary>
        /// <returns></returns>
        public PackRulesResult GetResult()
        {
            WriteOnce.SafeLog("PackRules::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Pack Rules"));

            PackRulesResult packRulesResult = new()
            {
                AppVersion = Common.Utils.GetVersionString()
            };

            try
            {
                RulesVerifier verifier = new(_rules_path, _options?.Log);
                if (_options?.PackEmbeddedRules ?? false)
                {
                    verifier.LoadRuleSet(RuleSetUtils.GetDefaultRuleSet());
                }
                verifier.Verify();
                if (!verifier.IsVerified)
                {
                    throw new OpException(MsgHelp.GetString(MsgHelp.ID.VERIFY_RULES_RESULTS_FAIL));
                }
                packRulesResult.Rules      = verifier.CompiledRuleset?.GetAppInspectorRules().ToList() ?? new List <Rule>();
                packRulesResult.ResultCode = PackRulesResult.ExitCode.Success;
            }
            catch (OpException e)
            {
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }

            return(packRulesResult);
        }
    }
예제 #6
0
        private void ConfigRules()
        {
            _logger.LogTrace("ExportTagsCommand::ConfigRules");
            _rules = new RuleSet(_loggerFactory);
            if (!_options.IgnoreDefaultRules)
            {
                _rules = RuleSetUtils.GetDefaultRuleSet(_loggerFactory);
            }

            if (!string.IsNullOrEmpty(_options?.CustomRulesPath))
            {
                if (Directory.Exists(_options.CustomRulesPath))
                {
                    _rules.AddDirectory(_options.CustomRulesPath);
                }
                else if (File.Exists(_options.CustomRulesPath))
                {
                    _rules.AddFile(_options.CustomRulesPath);
                }
                else
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_RULE_PATH, _options.CustomRulesPath));
                }
            }

            //error check based on ruleset not path enumeration
            if (_rules == null || !_rules.Any())
            {
                throw new OpException(MsgHelp.GetString(MsgHelp.ID.CMD_NORULES_SPECIFIED));
            }
        }
 private void LoadFile(string file)
 {
     try
     {
         _rules?.AddFile(file, null);
     }
     catch (Exception e)
     {
         Debug.Write(e.Message);//Ensure console message indicates problem for Build process
         WriteOnce.SafeLog(e.Message, NLog.LogLevel.Error);
         throw new OpException(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULE_LOADFILE_FAILED, file));
     }
 }
        public ExportTagsResult GetResult()
        {
            WriteOnce.SafeLog("ExportTagsCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Export Tags"));

            ExportTagsResult exportTagsResult = new()
            {
                AppVersion = Common.Utils.GetVersionString()
            };

            SortedDictionary <string, string> uniqueTags = new();

            try
            {
                foreach (Rule?r in _rules)
                {
                    //builds a list of unique tags
                    foreach (string t in r?.Tags ?? Array.Empty <string>())
                    {
                        if (uniqueTags.ContainsKey(t))
                        {
                            continue;
                        }
                        else
                        {
                            uniqueTags.Add(t, t);
                        }
                    }
                }

                //generate results list
                foreach (string s in uniqueTags.Values)
                {
                    exportTagsResult.TagsList.Add(s);
                }

                exportTagsResult.ResultCode = ExportTagsResult.ExitCode.Success;
            }
            catch (OpException e)
            {
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }

            return(exportTagsResult);
        }
    }
예제 #9
0
        public void Verify(bool failFast = true)
        {
            fail_fast = failFast;

            if (Directory.Exists(_rulesPath))
            {
                LoadDirectory(_rulesPath);
            }
            else if (File.Exists(_rulesPath))
            {
                LoadFile(_rulesPath);
            }
            else
            {
                throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_RULE_PATH, _rulesPath));
            }
        }
예제 #10
0
        private void LoadFile(string file)
        {
            try
            {
                _rules.AddFile(file, null);
            }
            catch (Exception e)
            {
                Debug.Write(e.Message);//Ensure console message indicates problem for Build process
                WriteOnce.SafeLog(e.Message, NLog.LogLevel.Error);

                //allow caller to specify whether to continue
                if (fail_fast)
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULE_FAILED, file));
                }
            }
        }
        /// <summary>
        /// Compile ruleset from a path to a directory or file containing a rule.json file and verify the status of the rules.
        /// </summary>
        /// <param name="fileName">Path to rules.</param>
        /// <returns></returns>
        /// <exception cref="OpException"></exception>
        public RulesVerifierResult Verify(string rulesPath)
        {
            RuleSet CompiledRuleset = new(_loggerFactory);

            if (!string.IsNullOrEmpty(rulesPath))
            {
                if (Directory.Exists(rulesPath))
                {
                    CompiledRuleset.AddDirectory(rulesPath);
                }
                else if (File.Exists(rulesPath))
                {
                    CompiledRuleset.AddFile(rulesPath);
                }
                else
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_RULE_PATH, rulesPath));
                }
            }
            return(Verify(CompiledRuleset));
        }
        /// <summary>
        /// Establish console verbosity
        /// For NuGet DLL use, console is muted overriding any arguments sent
        /// </summary>
        private void ConfigureConsoleOutput()
        {
            WriteOnce.SafeLog("PackRulesCommand::ConfigureConsoleOutput", LogLevel.Trace);

            //Set console verbosity based on run context (none for DLL use) and caller arguments
            if (!Utils.CLIExecutionContext)
            {
                WriteOnce.Verbosity = WriteOnce.ConsoleVerbosity.None;
            }
            else
            {
                WriteOnce.ConsoleVerbosity verbosity = WriteOnce.ConsoleVerbosity.Medium;
                if (!Enum.TryParse(_options.ConsoleVerbosityLevel, true, out verbosity))
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_ARG_VALUE, "-x"));
                }
                else
                {
                    WriteOnce.Verbosity = verbosity;
                }
            }
        }
        /// <summary>
        /// Return list of rule verification results
        /// </summary>
        /// <returns></returns>
        public List <RuleStatus> Verify()
        {
            _ruleStatuses = new List <RuleStatus>();
            if (!string.IsNullOrEmpty(_rulesPath))
            {
                if (Directory.Exists(_rulesPath))
                {
                    LoadDirectory(_rulesPath);
                }
                else if (File.Exists(_rulesPath))
                {
                    LoadFile(_rulesPath);
                }
                else
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_RULE_PATH, _rulesPath));
                }

                CheckIntegrity();
            }

            return(_ruleStatuses);
        }
        /// <summary>
        /// Option for DLL use as alternate to Run which only outputs a file to return results as string
        /// CommandOption defaults will not have been set when used as DLL via CLI processing so some checks added
        /// </summary>
        /// <returns>output results</returns>
        public VerifyRulesResult GetResult()
        {
            WriteOnce.SafeLog("VerifyRulesCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Verify Rules"));

            VerifyRulesResult verifyRulesResult = new VerifyRulesResult()
            {
                AppVersion = Utils.GetVersionString()
            };

            try
            {
                RulesVerifier verifier = new RulesVerifier(_rules_path, _options.Log);
                verifier.Verify(_options.Failfast);
                verifyRulesResult.ResultCode = VerifyRulesResult.ExitCode.Verified;

                RuleSet rules = verifier.CompiledRuleset;

                foreach (Rule rule in rules)
                {
                    verifyRulesResult.RuleStatusList.Add(new RuleStatus()
                    {
                        RulesId   = rule.Id,
                        RulesName = rule.Name,
                        Verified  = true
                    });
                }
            }
            catch (OpException e)
            {
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;;
            }

            return(verifyRulesResult);
        }
        public List <RuleStatus> CheckIntegrity(RuleSet ruleSet)
        {
            List <RuleStatus> ruleStatuses = new();

            foreach (ConvertedOatRule rule in ruleSet.GetOatRules() ?? Array.Empty <ConvertedOatRule>())
            {
                RuleStatus ruleVerified = CheckIntegrity(rule);

                ruleStatuses.Add(ruleVerified);

                if (_failFast && !ruleVerified.Verified)
                {
                    break;
                }
            }
            var duplicatedRules = ruleSet.GroupBy(x => x.Id).Where(y => y.Count() > 1);

            if (duplicatedRules.Any())
            {
                foreach (var rule in duplicatedRules)
                {
                    _logger.LogError(MsgHelp.GetString(MsgHelp.ID.VERIFY_RULES_DUPLICATEID_FAIL), rule.Key);
                    var relevantStati = ruleStatuses.Where(x => x.RulesId == rule.Key);
                    foreach (var status in relevantStati)
                    {
                        status.Errors = status.Errors.Append(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_DUPLICATEID_FAIL, rule.Key));
                    }
                    if (_failFast)
                    {
                        break;
                    }
                }
            }

            return(ruleStatuses);
        }
예제 #16
0
        private void ConfigRules()
        {
            WriteOnce.SafeLog("ExportTagsCommand::ConfigRules", LogLevel.Trace);

            if (!_options.IgnoreDefaultRules)
            {
                _rules = Utils.GetDefaultRuleSet(_options.Log);
            }

            if (!string.IsNullOrEmpty(_options.CustomRulesPath))
            {
                if (_rules == null)
                {
                    _rules = new RuleSet(_options.Log);
                }

                if (Directory.Exists(_options.CustomRulesPath))
                {
                    _rules.AddDirectory(_options.CustomRulesPath);
                }
                else if (File.Exists(_options.CustomRulesPath))
                {
                    _rules.AddFile(_options.CustomRulesPath);
                }
                else
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_RULE_PATH, _options.CustomRulesPath));
                }
            }

            //error check based on ruleset not path enumeration
            if (_rules == null || _rules.Count() == 0)
            {
                throw new OpException(MsgHelp.GetString(MsgHelp.ID.CMD_NORULES_SPECIFIED));
            }
        }
        /// <summary>
        /// Main entry from CLI
        /// </summary>
        /// <returns></returns>
        public TagTestResult GetResult()
        {
            WriteOnce.SafeLog("TagTestCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Tag Test"));
            TagTestResult tagTestResult = new TagTestResult()
            {
                AppVersion = Utils.GetVersionString()
            };

            //init based on true or false present argument value
            WriteOnce.ConsoleVerbosity saveVerbosity    = WriteOnce.Verbosity;
            AnalyzeResult.ExitCode     analyzeCmdResult = AnalyzeResult.ExitCode.CriticalError;

            try
            {
                //setup analyze call with silent option
                AnalyzeCommand cmd1 = new AnalyzeCommand(new AnalyzeOptions
                {
                    SourcePath            = _options.SourcePath,
                    IgnoreDefaultRules    = true,
                    CustomRulesPath       = _options.CustomRulesPath,
                    FilePathExclusions    = _options.FilePathExclusions,
                    ConsoleVerbosityLevel = "none",
                    Log = _options.Log
                });

                //get and perform initial analyze on results
                AnalyzeResult analyze1 = cmd1.GetResult();

                //restore
                WriteOnce.Verbosity = saveVerbosity;

                if (analyze1.ResultCode == AnalyzeResult.ExitCode.CriticalError)
                {
                    throw new OpException(MsgHelp.GetString(MsgHelp.ID.CMD_CRITICAL_FILE_ERR));
                }
                else if (analyzeCmdResult == AnalyzeResult.ExitCode.NoMatches)
                {
                    WriteOnce.General(MsgHelp.FormatString(MsgHelp.ID.TAGTEST_RESULTS_TEST_TYPE, _arg_tagTestType.ToString()), false, WriteOnce.ConsoleVerbosity.Low);
                    tagTestResult.ResultCode = _arg_tagTestType == TagTestType.RulesPresent ? TagTestResult.ExitCode.TestFailed : TagTestResult.ExitCode.TestPassed;
                }
                else //assumed (result == AnalyzeCommand.ExitCode.MatchesFound)
                {
                    tagTestResult.ResultCode = TagTestResult.ExitCode.TestPassed;

                    int      count     = 0;
                    int      sizeTags  = analyze1.Metadata.UniqueTags.Count;
                    string[] tagsFound = new string[sizeTags];

                    foreach (string tag in analyze1.Metadata.UniqueTags.Keys.ToList <string>())
                    {
                        tagsFound[count++] = tag;
                    }

                    foreach (Rule rule in _rulesSet)
                    {
                        //supports both directions by generalizing
                        string[] testList1 = _arg_tagTestType == TagTestType.RulesNotPresent ?
                                             rule.Tags : tagsFound;

                        string[] testList2 = _arg_tagTestType == TagTestType.RulesNotPresent ?
                                             tagsFound : rule.Tags;

                        foreach (string t in testList2)
                        {
                            if (TagTest(testList1, t))
                            {
                                tagTestResult.TagsStatusList.Add(new TagStatus()
                                {
                                    Tag = t, Detected = true
                                });
                            }
                            else
                            {
                                tagTestResult.ResultCode = TagTestResult.ExitCode.TestFailed;
                                tagTestResult.TagsStatusList.Add(new TagStatus()
                                {
                                    Tag = t, Detected = false
                                });
                            }
                        }
                    }
                }
            }
            catch (OpException e)
            {
                WriteOnce.Verbosity = saveVerbosity;
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }

            return(tagTestResult);
        }
예제 #18
0
        /// <summary>
        /// Setup application inspector logging; 1 file per process
        /// </summary>
        /// <param name="opts"></param>
        /// <returns></returns>
        public static Logger SetupLogging(CommandOptions opts, bool onErrorConsole = false)
        {
            //prevent being called again if already set unless closed first
            if (Logger != null)
            {
                return(Logger);
            }

            var config = new NLog.Config.LoggingConfiguration();

            if (String.IsNullOrEmpty(opts.LogFilePath))
            {
                opts.LogFilePath = Utils.GetPath(Utils.AppPath.defaultLog);
            }

            //clean up previous for convenience in reading
            if (File.Exists(opts.LogFilePath))
            {
                // Read the file and display it line by line.
                System.IO.StreamReader file = new System.IO.StreamReader(opts.LogFilePath);
                String line = file.ReadLine();
                file.Close();
                if (!String.IsNullOrEmpty(line))
                {
                    if (line.Contains("AppInsLog"))//prevent file other than our logs from deletion
                    {
                        File.Delete(opts.LogFilePath);
                    }
                    else
                    {
                        if (Utils.CLIExecutionContext && onErrorConsole)
                        {
                            WriteOnce.Error(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_LOG_PATH, opts.LogFilePath), true, WriteOnce.ConsoleVerbosity.Low, false);
                        }

                        throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_LOG_PATH, opts.LogFilePath));
                    }
                }
            }
            else
            {
                try
                {
                    File.WriteAllText(opts.LogFilePath, "");//verify log file path is writable
                }
                catch (Exception e)
                {
                    WriteOnce.SafeLog(e.Message + "\n" + e.StackTrace, NLog.LogLevel.Error);
                    if (Utils.CLIExecutionContext && onErrorConsole)
                    {
                        WriteOnce.Error(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_FILE_OR_DIR, opts.LogFilePath), true, WriteOnce.ConsoleVerbosity.Low, false);
                    }

                    throw new OpException((MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_FILE_OR_DIR, opts.LogFilePath)));
                }
            }

            LogLevel log_level = LogLevel.Error;//default

            if (String.IsNullOrEmpty(opts.LogFileLevel))
            {
                opts.LogFileLevel = "Error";
            }

            try
            {
                log_level = LogLevel.FromString(opts.LogFileLevel);
            }
            catch (Exception)
            {
                if (Utils.CLIExecutionContext && onErrorConsole)
                {
                    WriteOnce.Error(MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_ARG_VALUE, "-v"), true, WriteOnce.ConsoleVerbosity.Low, false);
                }

                throw new OpException((MsgHelp.FormatString(MsgHelp.ID.CMD_INVALID_ARG_VALUE, "-v")));
            }

            using (var fileTarget = new FileTarget()
            {
                Name = "LogFile",
                FileName = opts.LogFilePath,
                Layout = @"${date:format=yyyy-MM-dd HH\:mm\:ss} ${threadid} ${level:uppercase=true} - AppInsLog - ${message}",
                ForceMutexConcurrentWrites = true
            })
            {
                config.AddTarget(fileTarget);
                config.LoggingRules.Add(new LoggingRule("CST.ApplicationInspector", log_level, fileTarget));
            }

            LogFilePath = opts.LogFilePath;//preserve for console path msg

            LogManager.Configuration = config;
            Logger = LogManager.GetLogger("CST.ApplicationInspector");
            return(Logger);
        }
        /// <summary>
        /// Main entry from CLI
        /// </summary>
        /// <returns></returns>
        public TagDiffResult GetResult()
        {
            WriteOnce.SafeLog("TagDiffCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Tag Diff"));

            TagDiffResult tagDiffResult = new TagDiffResult()
            {
                AppVersion = Utils.GetVersionString()
            };

            //save to quiet analyze cmd and restore
            WriteOnce.ConsoleVerbosity saveVerbosity = WriteOnce.Verbosity;

            try
            {
                #region setup analyze calls

                AnalyzeCommand cmd1 = new AnalyzeCommand(new AnalyzeOptions
                {
                    SourcePath            = _options.SourcePath1,
                    CustomRulesPath       = _options.CustomRulesPath,
                    IgnoreDefaultRules    = _options.IgnoreDefaultRules,
                    FilePathExclusions    = _options.FilePathExclusions,
                    ConsoleVerbosityLevel = "none",
                    Log = _options.Log
                });
                AnalyzeCommand cmd2 = new AnalyzeCommand(new AnalyzeOptions
                {
                    SourcePath            = _options.SourcePath2,
                    CustomRulesPath       = _options.CustomRulesPath,
                    IgnoreDefaultRules    = _options.IgnoreDefaultRules,
                    FilePathExclusions    = _options.FilePathExclusions,
                    ConsoleVerbosityLevel = "none",
                    Log = _options.Log
                });

                AnalyzeResult analyze1 = cmd1.GetResult();
                AnalyzeResult analyze2 = cmd2.GetResult();

                //restore
                WriteOnce.Verbosity = saveVerbosity;

                #endregion setup analyze calls

                bool equalTagsCompare1 = true;
                bool equalTagsCompare2 = true;

                //process results for each analyze call before comparing results
                if (analyze1.ResultCode == AnalyzeResult.ExitCode.CriticalError)
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_CRITICAL_FILE_ERR, _options.SourcePath1));
                }
                else if (analyze2.ResultCode == AnalyzeResult.ExitCode.CriticalError)
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_CRITICAL_FILE_ERR, _options.SourcePath2));
                }
                else if (analyze1.ResultCode == AnalyzeResult.ExitCode.NoMatches || analyze2.ResultCode == AnalyzeResult.ExitCode.NoMatches)
                {
                    throw new OpException(MsgHelp.GetString(MsgHelp.ID.TAGDIFF_NO_TAGS_FOUND));
                }
                else //compare tag results; assumed (result1&2 == AnalyzeCommand.ExitCode.Success)
                {
                    int      count1    = 0;
                    int      sizeTags1 = analyze1.Metadata.UniqueTags.Count;
                    string[] file1Tags = new string[sizeTags1];

                    foreach (string tag in analyze1.Metadata.UniqueTags.Keys.ToList <string>())
                    {
                        file1Tags[count1++] = tag;
                    }

                    int      count2    = 0;
                    int      sizeTags2 = analyze2.Metadata.UniqueTags.Count;
                    string[] file2Tags = new string[sizeTags2];

                    foreach (string tag in analyze2.Metadata.UniqueTags.Keys.ToList <string>())
                    {
                        file2Tags[count2++] = tag;
                    }

                    //can't simply compare counts as content may differ; must compare both in directions in two passes a->b; b->a
                    equalTagsCompare1 = CompareTags(file1Tags, file2Tags, ref tagDiffResult, TagDiff.DiffSource.Source1);

                    //reverse order for second pass
                    equalTagsCompare2 = CompareTags(file2Tags, file1Tags, ref tagDiffResult, TagDiff.DiffSource.Source2);

                    //final results
                    bool resultsDiffer = !(equalTagsCompare1 && equalTagsCompare2);
                    if (_arg_tagTestType == TagTestType.Inequality && !resultsDiffer)
                    {
                        tagDiffResult.ResultCode = TagDiffResult.ExitCode.TestFailed;
                    }
                    else if (_arg_tagTestType == TagTestType.Equality && resultsDiffer)
                    {
                        tagDiffResult.ResultCode = TagDiffResult.ExitCode.TestFailed;
                    }
                    else
                    {
                        tagDiffResult.ResultCode = TagDiffResult.ExitCode.TestPassed;
                    }
                }
            }
            catch (OpException e)
            {
                WriteOnce.Verbosity = saveVerbosity;
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }

            return(tagDiffResult);
        }
예제 #20
0
        /// <summary>
        /// Main entry from CLI
        /// </summary>
        /// <returns></returns>
        public TagDiffResult GetResult()
        {
            WriteOnce.SafeLog("TagDiffCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Tag Diff"));

            TagDiffResult tagDiffResult = new() { AppVersion = Common.Utils.GetVersionString() };

            //save to quiet analyze cmd and restore
            WriteOnce.ConsoleVerbosity saveVerbosity = WriteOnce.Verbosity;

            try
            {
                if (_options is null)
                {
                    throw new ArgumentNullException("_options");
                }
                AnalyzeCommand cmd1 = new(new AnalyzeOptions()
                {
                    SourcePath = _options.SourcePath1,
                    CustomRulesPath = _options.CustomRulesPath,
                    IgnoreDefaultRules = _options.IgnoreDefaultRules,
                    FilePathExclusions = _options.FilePathExclusions,
                    ConsoleVerbosityLevel = "none",
                    Log = _options.Log,
                    TagsOnly = true,
                    ConfidenceFilters = _options.ConfidenceFilters,
                    FileTimeOut = _options.FileTimeOut,
                    ProcessingTimeOut = _options.ProcessingTimeOut,
                    NoFileMetadata = true,
                    NoShowProgress = true,
                    ScanUnknownTypes = _options.ScanUnknownTypes,
                    SingleThread = _options.SingleThread,
                });
                AnalyzeCommand cmd2 = new(new AnalyzeOptions()
                {
                    SourcePath = _options.SourcePath2,
                    CustomRulesPath = _options.CustomRulesPath,
                    IgnoreDefaultRules = _options.IgnoreDefaultRules,
                    FilePathExclusions = _options.FilePathExclusions,
                    ConsoleVerbosityLevel = "none",
                    Log = _options.Log,
                    TagsOnly = true,
                    ConfidenceFilters = _options.ConfidenceFilters,
                    FileTimeOut = _options.FileTimeOut,
                    ProcessingTimeOut = _options.ProcessingTimeOut,
                    NoFileMetadata = true,
                    NoShowProgress = true,
                    ScanUnknownTypes = _options.ScanUnknownTypes,
                    SingleThread = _options.SingleThread,
                });

                AnalyzeResult analyze1 = cmd1.GetResult();
                AnalyzeResult analyze2 = cmd2.GetResult();

                //restore
                WriteOnce.Verbosity = saveVerbosity;

                //process results for each analyze call before comparing results
                if (analyze1.ResultCode == AnalyzeResult.ExitCode.CriticalError)
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_CRITICAL_FILE_ERR, string.Join(',', _options.SourcePath1)));
                }
                else if (analyze2.ResultCode == AnalyzeResult.ExitCode.CriticalError)
                {
                    throw new OpException(MsgHelp.FormatString(MsgHelp.ID.CMD_CRITICAL_FILE_ERR, string.Join(',', _options.SourcePath2)));
                }
                else if (analyze1.ResultCode == AnalyzeResult.ExitCode.NoMatches || analyze2.ResultCode == AnalyzeResult.ExitCode.NoMatches)
                {
                    throw new OpException(MsgHelp.GetString(MsgHelp.ID.TAGDIFF_NO_TAGS_FOUND));
                }
                else //compare tag results; assumed (result1&2 == AnalyzeCommand.ExitCode.Success)
                {
                    var list1 = analyze1.Metadata.UniqueTags ?? new List <string>();
                    var list2 = analyze2.Metadata.UniqueTags ?? new List <string>();

                    var removed = list1.Except(list2);
                    var added   = list2.Except(list1);

                    foreach (var add in added)
                    {
                        tagDiffResult.TagDiffList.Add(new TagDiff()
                        {
                            Source = TagDiff.DiffSource.Source2,
                            Tag    = add
                        });
                    }
                    foreach (var remove in removed)
                    {
                        tagDiffResult.TagDiffList.Add(new TagDiff()
                        {
                            Source = TagDiff.DiffSource.Source1,
                            Tag    = remove
                        });
                    }


                    if (tagDiffResult.TagDiffList.Count > 0)
                    {
                        tagDiffResult.ResultCode = _arg_tagTestType == TagTestType.Inequality ? TagDiffResult.ExitCode.TestPassed : TagDiffResult.ExitCode.TestFailed;
                    }
                    else
                    {
                        tagDiffResult.ResultCode = _arg_tagTestType == TagTestType.Inequality ? TagDiffResult.ExitCode.TestFailed : TagDiffResult.ExitCode.TestPassed;
                    }

                    return(tagDiffResult);
                }
            }
            catch (OpException e)
            {
                WriteOnce.Verbosity = saveVerbosity;
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }
        }
    }
        public bool CheckIntegrity(Rule rule)
        {
            bool isValid = true;

            // Check for null Id
            if (rule.Id == null)
            {
                _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_NULLID_FAIL, rule.Name));
                isValid = false;
            }
            else
            {
                // Check for same ID
                Rule sameRule = _rules.FirstOrDefault(x => x.Id == rule.Id);
                if (_rules.Count(x => x.Id == rule.Id) > 1)
                {
                    _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_DUPLICATEID_FAIL, rule.Id));
                    isValid = false;
                }
            }

            //applicability
            if (rule.AppliesTo != null)
            {
                string[] languages = Language.GetNames();
                // Check for unknown language
                foreach (string lang in rule.AppliesTo)
                {
                    if (!string.IsNullOrEmpty(lang))
                    {
                        if (!languages.Any(x => x.Equals(lang, StringComparison.CurrentCultureIgnoreCase)))
                        {
                            _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_LANGUAGE_FAIL, rule.Id ?? ""));
                            isValid = false;
                        }
                    }
                }
            }

            //valid search pattern
            foreach (SearchPattern searchPattern in rule.Patterns ?? new SearchPattern[] { })
            {
                try
                {
                    Regex regex = new Regex(searchPattern.Pattern);
                }
                catch (Exception e)
                {
                    _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_REGEX_FAIL, rule.Id ?? "", searchPattern.Pattern ?? "", e.Message));
                    isValid = false;
                    break;
                }
            }

            if (rule.Tags?.Length == 0)
            {
                isValid = false;
            }

            return(isValid);
        }
예제 #22
0
        public bool CheckIntegrity(Rule rule)
        {
            bool isValid = true;

            // Check for null Id
            if (rule.Id == null)
            {
                _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_NULLID_FAIL, rule.Name));
                isValid = false;
            }
            else
            {
                // Check for same ID
                if (CompiledRuleset.Count(x => x.Id == rule.Id) > 1)
                {
                    _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_DUPLICATEID_FAIL, rule.Id));
                    isValid = false;
                }
            }

            //applicability
            if (rule.AppliesTo != null)
            {
                string[] languages = Language.GetNames();
                // Check for unknown language
                foreach (string lang in rule.AppliesTo)
                {
                    if (!string.IsNullOrEmpty(lang))
                    {
                        if (!languages.Any(x => x.Equals(lang, StringComparison.CurrentCultureIgnoreCase)))
                        {
                            _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_LANGUAGE_FAIL, rule.Id ?? ""));
                            return(false);
                        }
                    }
                }
            }

            foreach (var pattern in rule.FileRegexes ?? Array.Empty <string>())
            {
                try
                {
                    _ = new Regex(pattern, RegexOptions.Compiled);
                }
                catch (Exception e)
                {
                    _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_REGEX_FAIL, rule.Id ?? "", pattern ?? "", e.Message));

                    return(false);
                }
            }

            //valid search pattern
            foreach (SearchPattern searchPattern in rule.Patterns ?? Array.Empty <SearchPattern>())
            {
                if (searchPattern.PatternType == PatternType.RegexWord || searchPattern.PatternType == PatternType.Regex)
                {
                    try
                    {
                        if (string.IsNullOrEmpty(searchPattern.Pattern))
                        {
                            throw new ArgumentException();
                        }
                        _ = new Regex(searchPattern.Pattern);
                    }
                    catch (Exception e)
                    {
                        _logger?.Error(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_REGEX_FAIL, rule.Id ?? "", searchPattern.Pattern ?? "", e.Message));
                        return(false);
                    }
                }
            }

            foreach (var condition in rule.Conditions ?? Array.Empty <SearchCondition>())
            {
                if (condition.SearchIn is null)
                {
                    _logger?.Error("SearchIn is null in {0}", rule.Id);
                    return(false);
                }
                if (condition.SearchIn.StartsWith("finding-region"))
                {
                    var parSplits = condition.SearchIn.Split(new char[] { ')', '(' });
                    if (parSplits.Length == 3)
                    {
                        var splits = parSplits[1].Split(',');
                        if (splits.Length == 2)
                        {
                            if (int.TryParse(splits[0], out int int1) && int.TryParse(splits[1], out int int2))
                            {
                                if (int1 > 0 && int2 < 0)
                                {
                                    _logger?.Error("The finding region must have a negative number or 0 for the lines before and a positive number or 0 for lines after. {0}", rule.Id);
                                    return(false);
                                }
                            }
                        }
                        else
                        {
                            _logger?.Error("Improperly specified finding region. {0}", rule.Id);
                            return(false);
                        }
                    }
                    else
                    {
                        _logger?.Error("Improperly specified finding region. {0}", rule.Id);
                        return(false);
                    }
                }
            }

            if (rule.Tags?.Length == 0)
            {
                isValid = false;
            }

            return(isValid);
        }
        public RuleStatus CheckIntegrity(ConvertedOatRule convertedOatRule)
        {
            List <string> errors = new();

            // App Inspector checks
            var rule = convertedOatRule.AppInspectorRule;

            // Check for null Id
            if (string.IsNullOrEmpty(rule.Id))
            {
                _logger.LogError(MsgHelp.GetString(MsgHelp.ID.VERIFY_RULES_NULLID_FAIL), rule.Name);
                errors.Add(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_NULLID_FAIL, rule.Name));
            }

            //applicability
            if (rule.AppliesTo != null)
            {
                string[] languages = _options.LanguageSpecs.GetNames();
                // Check for unknown language
                foreach (string lang in rule.AppliesTo)
                {
                    if (!string.IsNullOrEmpty(lang))
                    {
                        if (!languages.Any(x => x.Equals(lang, StringComparison.CurrentCultureIgnoreCase)))
                        {
                            _logger.LogError(MsgHelp.GetString(MsgHelp.ID.VERIFY_RULES_LANGUAGE_FAIL), rule.Id ?? "");
                            errors.Add(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_LANGUAGE_FAIL, rule.Id ?? ""));
                        }
                    }
                }
            }

            foreach (var pattern in rule.FileRegexes ?? Array.Empty <string>())
            {
                try
                {
                    _ = new Regex(pattern, RegexOptions.Compiled);
                }
                catch (Exception e)
                {
                    _logger?.LogError(MsgHelp.GetString(MsgHelp.ID.VERIFY_RULES_REGEX_FAIL), rule.Id ?? "", pattern ?? "", e.Message);
                    errors.Add(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_REGEX_FAIL, rule.Id ?? "", pattern ?? "", e.Message));
                }
            }

            //valid search pattern
            foreach (SearchPattern searchPattern in rule.Patterns ?? Array.Empty <SearchPattern>())
            {
                if (searchPattern.PatternType == PatternType.RegexWord || searchPattern.PatternType == PatternType.Regex)
                {
                    try
                    {
                        if (string.IsNullOrEmpty(searchPattern.Pattern))
                        {
                            throw new ArgumentException();
                        }
                        _ = new Regex(searchPattern.Pattern);
                    }
                    catch (Exception e)
                    {
                        _logger?.LogError(MsgHelp.GetString(MsgHelp.ID.VERIFY_RULES_REGEX_FAIL), rule.Id ?? "", searchPattern.Pattern ?? "", e.Message);
                        errors.Add(MsgHelp.FormatString(MsgHelp.ID.VERIFY_RULES_REGEX_FAIL, rule.Id ?? "", searchPattern.Pattern ?? "", e.Message));
                    }
                }
            }

            foreach (var condition in rule.Conditions ?? Array.Empty <SearchCondition>())
            {
                if (condition.SearchIn is null)
                {
                    _logger?.LogError("SearchIn is null in {ruleId}", rule.Id);
                    errors.Add(string.Format("SearchIn is null in {0}", rule.Id));
                }
                else if (condition.SearchIn.StartsWith("finding-region"))
                {
                    var parSplits = condition.SearchIn.Split(new char[] { ')', '(' });
                    if (parSplits.Length == 3)
                    {
                        var splits = parSplits[1].Split(',');
                        if (splits.Length == 2)
                        {
                            if (int.TryParse(splits[0], out int int1) && int.TryParse(splits[1], out int int2))
                            {
                                if (int1 > 0 && int2 < 0)
                                {
                                    _logger?.LogError("The finding region must have a negative number or 0 for the lines before and a positive number or 0 for lines after. {0}", rule.Id);
                                    errors.Add(string.Format("The finding region must have a negative number or 0 for the lines before and a positive number or 0 for lines after. {0}", rule.Id));
                                }
                            }
                        }
                        else
                        {
                            _logger?.LogError("Improperly specified finding region. {0}", rule.Id);
                            errors.Add(string.Format("Improperly specified finding region. {0}", rule.Id));
                        }
                    }
                    else
                    {
                        _logger?.LogError("Improperly specified finding region. {0}", rule.Id);
                        errors.Add(string.Format("Improperly specified finding region. {0}", rule.Id));
                    }
                }
            }

            if (rule.Tags?.Length == 0)
            {
                _logger?.LogError("Rule must specify tags. {0}", rule.Id);
                errors.Add(string.Format("Rule must specify tags. {0}", rule.Id));
            }
            return(new RuleStatus()
            {
                RulesId = rule.Id,
                RulesName = rule.Name,
                Errors = errors,
                OatIssues = _analyzer.EnumerateRuleIssues(convertedOatRule)
            });
        }
        /// <summary>
        /// Option for DLL use as alternate to Run which only outputs a file to return results as string
        /// CommandOption defaults will not have been set when used as DLL via CLI processing so some checks added
        /// </summary>
        /// <returns>output results</returns>
        public VerifyRulesResult GetResult()
        {
            WriteOnce.SafeLog("VerifyRulesCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Verify Rules"));

            VerifyRulesResult verifyRulesResult = new() { AppVersion = Utils.GetVersionString() };

            try
            {
                RulesVerifier verifier = new(null, _options.Log);
                verifyRulesResult.ResultCode = VerifyRulesResult.ExitCode.Verified;
                var stati    = new List <RuleStatus>();
                var analyzer = new Analyzer();
                analyzer.SetOperation(new WithinOperation(analyzer));
                analyzer.SetOperation(new OATRegexWithIndexOperation(analyzer));
                analyzer.SetOperation(new OATSubstringIndexOperation(analyzer));

                RuleSet?ruleSet = new(_options.Log);
                if (_options.VerifyDefaultRules)
                {
                    ruleSet = RuleSetUtils.GetDefaultRuleSet(_options.Log);
                }
                try
                {
                    if (_options.CustomRulesPath != null)
                    {
                        if (Directory.Exists(_options.CustomRulesPath))
                        {
                            ruleSet.AddDirectory(_options.CustomRulesPath);
                        }
                        else if (File.Exists(_options.CustomRulesPath))
                        {
                            ruleSet.AddFile(_options.CustomRulesPath);
                        }
                    }
                }
                catch (JsonSerializationException e)
                {
                    WriteOnce.Error(e.Message);
                    verifyRulesResult.ResultCode = VerifyRulesResult.ExitCode.CriticalError;
                    return(verifyRulesResult);
                }
                foreach (var rule in ruleSet.GetOatRules())
                {
                    stati.Add(new RuleStatus()
                    {
                        RulesId   = rule.AppInspectorRule.Id,
                        RulesName = rule.Name,
                        Verified  = verifier.Verify(rule.AppInspectorRule),
                        OatIssues = analyzer.EnumerateRuleIssues(rule)
                    });
                }
                verifyRulesResult.RuleStatusList = stati;
                verifyRulesResult.ResultCode     = stati.All(x => x.Verified && !x.OatIssues.Any()) ? VerifyRulesResult.ExitCode.Verified : VerifyRulesResult.ExitCode.NotVerified;
            }
            catch (OpException e)
            {
                WriteOnce.Error(e.Message);
                //caught for CLI callers with final exit msg about checking log or throws for DLL callers
                throw;
            }
            return(verifyRulesResult);
        }
    }