public void SearchSkimmer_RecoverValidatorMessage()
        {
            const string validationMessage        = " (no validation occurred as it was not enabled. Pass '--dynamic-validation' on the command-line to validate this match)";
            string       dynamicValidationMessage = SearchSkimmer.RecoverValidatorMessage(validationMessage);

            dynamicValidationMessage.Should().Be(validationMessage.Replace(" (", string.Empty).Replace(")", string.Empty));
        }
        private AnalyzeContext CreateGuidMatchingSkimmer(
            string scanTargetExtension,
            ref SearchDefinition definition,
            out SearchSkimmer skimmer,
            string allowFileExtension  = null,
            string denyFileExtension   = null,
            ValidatorsCache validators = null)
        {
            MatchExpression expression =
                CreateGuidDetectingMatchExpression(
                    denyFileExtension: denyFileExtension,
                    allowFileExtension: allowFileExtension);

            definition ??= CreateDefaultSearchDefinition(expression);

            var logger = new TestLogger();

            var context = new AnalyzeContext
            {
                TargetUri    = new Uri($"file:///c:/{definition.Name}.{definition.FileNameAllowRegex}.{scanTargetExtension}"),
                FileContents = definition.Id,
                Logger       = logger
            };

            var mockFileSystem = new Mock <IFileSystem>();

            mockFileSystem.Setup(x => x.FileReadAllText(context.TargetUri.LocalPath)).Returns(definition.Id);

            skimmer = CreateSkimmer(
                definition,
                validators: validators,
                fileSystem: mockFileSystem.Object);

            return(context);
        }
        public void SearchSkimmer_NoDetectionWhenMatchIsEmpty()
        {
            var expression = new MatchExpression();
            SearchDefinition definition = CreateDefaultSearchDefinition(expression);

            string scanTargetContents = definition.Id;

            var logger = new TestLogger();

            var context = new AnalyzeContext
            {
                TargetUri    = new Uri($"file:///c:/{definition.Name}.Fake.asc"),
                FileContents = $"{ definition.Id}",
                Logger       = logger
            };

            SearchSkimmer skimmer = CreateSkimmer(definition);

            skimmer.Analyze(context);

            logger.Results.Should().BeNull();
        }
        public void SearchSkimmer_DetectsFilePatternOnly()
        {
            string           fileExtension = Guid.NewGuid().ToString();
            MatchExpression  expr          = CreateFileDetectingMatchExpression(fileExtension: fileExtension);
            SearchDefinition definition    = CreateDefaultSearchDefinition(expr);

            string scanTargetContents = definition.Id;

            var logger = new TestLogger();

            var context = new AnalyzeContext
            {
                TargetUri    = new Uri($"file:///c:/{definition.Name}.Fake.{fileExtension}"),
                FileContents = definition.Id,
                Logger       = logger
            };

            SearchSkimmer skimmer = CreateSkimmer(definition);

            skimmer.Analyze(context);

            ValidateResultsAgainstDefinition(logger.Results, definition, skimmer);
        }
        public void SearchSkimmer_DetectsBase64EncodedPattern()
        {
            MatchExpression  expr       = CreateGuidDetectingMatchExpression();
            SearchDefinition definition = CreateDefaultSearchDefinition(expr);

            string originalMessage = definition.Message;

            // We inject the well-known encoding name that reports with
            // 'plaintext' or 'base64-encoded' depending on how a match
            // was made.
            definition.Message = $"{{0:encoding}}:{definition.Message}";

            string scanTargetContents = definition.Id;

            byte[] bytes         = Encoding.UTF8.GetBytes(scanTargetContents);
            string base64Encoded = Convert.ToBase64String(bytes);

            var logger = new TestLogger();

            var context = new AnalyzeContext
            {
                TargetUri    = new Uri($"file:///c:/{definition.Name}.{definition.FileNameAllowRegex}"),
                FileContents = base64Encoded,
                Logger       = logger
            };

            SearchSkimmer skimmer = CreateSkimmer(definition);

            skimmer.Analyze(context);

            // Analyzing base64-encoded values with MatchLengthToDecode > 0 succeeds
            logger.Results.Count.Should().Be(1);
            logger.Results[0].RuleId.Should().Be(definition.Id);
            logger.Results[0].Level.Should().Be(definition.Level);
            logger.Results[0].GetMessageText(skimmer).Should().Be($"base64-encoded:{originalMessage}");

            // Analyzing base64-encoded values with MatchLengthToDecode == 0 fails
            definition.MatchExpressions[0].MatchLengthToDecode = 0;

            logger.Results.Clear();
            skimmer = CreateSkimmer(definition);
            skimmer.Analyze(context);

            logger.Results.Count.Should().Be(0);

            // Analyzing plaintext values with MatchLengthToDecode > 0 succeeds
            context.FileContents = scanTargetContents;

            logger.Results.Clear();
            skimmer = CreateSkimmer(definition);
            skimmer.Analyze(context);

            // But we should see a change in encoding information in message. Note
            // that when emitting plaintext matches, we elide this information
            // entirely (i.e., we only explicitly report 'base64-encoded' and
            // report nothing for plaintext).
            logger.Results.Count.Should().Be(1);
            logger.Results[0].RuleId.Should().Be(definition.Id);
            logger.Results[0].Level.Should().Be(definition.Level);
            logger.Results[0].GetMessageText(skimmer).Should().Be($":{originalMessage}");
        }
 private void ValidateResultsAgainstDefinition(IList <Result> results, SearchDefinition definition, SearchSkimmer skimmer)
 {
     results.Should().NotBeNull();
     results.Count.Should().Be(1);
     results[0].RuleId.Should().Be(definition.Id);
     results[0].Level.Should().Be(definition.Level);
     results[0].GetMessageText(skimmer).Should().Be($"{definition.Message}");
 }