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); } }
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); } }
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)); } }
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); }
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); }
/// <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); }
/// <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); }
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); } }