public async Task Publish(TlsResultsEvaluated message)
        {
            List <TlsEvaluatedResult> evaluatedResults =
                message.TlsRecords?.Records?.Select(x => x.TlsEvaluatedResult).ToList();
            List <Error> evaluatedCertificates = message.Certificates?.Errors;

            Dictionary <string, List <TlsEntityState> > domainsContainingHost = await _dao.GetDomains(message.Id);

            foreach (string domain in domainsContainingHost.Keys)
            {
                List <TlsEntityState>     existingHostStates = domainsContainingHost[domain];
                List <TlsEvaluatedResult> existingResults    = existingHostStates
                                                               .Where(x => x.TlsRecords?.Records != null)
                                                               .SelectMany(x => x.TlsRecords?.Records?.Select(y => y.TlsEvaluatedResult)).ToList();

                List <Error> existingCertificates = existingHostStates
                                                    .Where(x => x.CertificateResults?.Errors != null)
                                                    .SelectMany(x => x.CertificateResults?.Errors).ToList();

                existingResults.AddRange(evaluatedResults ?? new List <TlsEvaluatedResult>());

                existingCertificates.AddRange(evaluatedCertificates ?? new List <Error>());

                Status status = _domainStatusEvaluator.GetStatus(existingResults, existingCertificates);

                DomainStatusEvaluation domainStatusEvaluation = new DomainStatusEvaluation(domain, "TLS", status);

                _log.LogInformation(
                    $"Publishing TLS domain status for domain {domain} because it contains mx host {message.Id} which was evaluated");
                _dispatcher.Dispatch(domainStatusEvaluation, _tlsEntityConfig.SnsTopicArn);
            }
        }
Exemplo n.º 2
0
        public async Task WhenAllTestAreTcpConnectionFailedShouldReturnOneError()
        {
            EvaluatorResult expectedResult  = EvaluatorResult.INCONCLUSIVE;
            string          expectedMessage =
                "We were unable to create a TLS connection with this server. This could be because the server does not support TLS "
                + "or because Mail Check servers have been blocked. We will keep trying to test TLS with this server, so please check back later or get in touch "
                + "if you think there's a problem.";

            var mxHostTlsResults = new TlsTestResults("abc.def.gov.uk", false, false, new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null),
                                                      new BouncyCastleTlsTestResult(TlsError.TCP_CONNECTION_FAILED, "", null), null);

            IMxSecurityEvaluator          mxSecurityEvaluator = A.Fake <IMxSecurityEvaluator>();
            ILogger <EvaluationProcessor> log = A.Fake <ILogger <EvaluationProcessor> >();

            IEvaluationProcessor processor = new EvaluationProcessor(mxSecurityEvaluator, log);
            TlsResultsEvaluated  results   = await processor.Process(mxHostTlsResults);


            Assert.AreEqual(expectedResult, results.TlsRecords.Tls12AvailableWithBestCipherSuiteSelected.TlsEvaluatedResult.Result.Value);
            Assert.AreEqual(expectedMessage, results.TlsRecords.Tls12AvailableWithBestCipherSuiteSelected.TlsEvaluatedResult.Description);
        }
        public async Task <TlsResultsEvaluated> Process(TlsTestResults tlsTestRptRecords)
        {
            Stopwatch           stopwatch = Stopwatch.StartNew();
            TlsResultsEvaluated result    = await EvaluateMxRecordProfile(tlsTestRptRecords);

            stopwatch.Stop();
            _log.LogDebug($"Processed domain with ID {tlsTestRptRecords.Id}. Took {stopwatch.Elapsed.TotalSeconds} seconds.");
            return(result);
        }
        public async Task ShouldHandleChangeSaveAndDispatchWhenTlsTestResultIsReceived()
        {
            string snsTopicArn = "snsTopicArn";

            A.CallTo(() => _tlsEntityConfig.SnsTopicArn).Returns(snsTopicArn);

            string hostName = "testhostname";

            TlsEntityState stateFromDb = new TlsEntityState(hostName)
            {
                TlsState = TlsState.Created
            };

            A.CallTo(() => _dao.Get(hostName)).Returns(Task.FromResult(stateFromDb));
            A.CallTo(() => _dao.GetDomainsFromHost(hostName)).Returns(Task.FromResult(new List <string> {
                "test.gov.uk"
            }));



            A.CallTo(() => _tlsEntityConfig.NextScheduledInSeconds).Returns(33);
            A.CallTo(() => _clock.GetDateTimeUtc()).Returns(DateTime.MinValue);

            CertificateResults certificateResults = new CertificateResults(null, null);

            TlsResultsEvaluated message = new TlsResultsEvaluated(hostName, false, new TlsRecords(
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      , new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      , new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      , new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      ), certificateResults);

            await _tlsEntity.Handle(message);

            Assert.AreEqual(stateFromDb.TlsState, TlsState.Evaluated);
            Assert.AreEqual(stateFromDb.TlsRecords, message.TlsRecords);
            Assert.AreEqual(stateFromDb.LastUpdated, message.Timestamp);
            List <string> domains = new List <string>();

            A.CallTo(() => _changeNotifierComposite.Handle(stateFromDb, message, A <List <string> > ._)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dao.Save(stateFromDb)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dispatcher.Dispatch(A <TlsRecordEvaluationsChanged> .That.Matches(a => a.Id == message.Id && a.TlsRecords == message.TlsRecords && a.CertificateResults == message.Certificates), snsTopicArn)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dispatcher.Dispatch(A <CreateScheduledReminder> .That.Matches(a => a.ResourceId == hostName && a.Service == "Tls" && a.ScheduledTime.Second == 33), snsTopicArn)).MustHaveHappenedOnceExactly();
        }
        public async Task AllRulePassNoErrors()
        {
            TlsResultsEvaluated EvaluatorResults = A.Fake <TlsResultsEvaluated>();

            A.CallTo(() => _rule1.Evaluate(EvaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult>());
            A.CallTo(() => _rule2.Evaluate(EvaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult>());

            var evaluationResult = await _evaluator.Evaluate(EvaluatorResults);

            Assert.That(evaluationResult.Messages, Is.Empty);
        }
        public async Task Handle(TlsTestResults message)
        {
            TlsResultsEvaluated results = await _tlsRptEvaluationProcessor.Process(message);

            if (message.Certificates.Any())
            {
                CertificateResults certs = await _certificateProcessor.Process(message);

                results = new TlsResultsEvaluated(results.Id, results.Failed, results.TlsRecords, certs);
            }

            _dispatcher.Dispatch(results, _config.SnsTopicArn);
        }
        protected async Task <TlsResultsEvaluated> EvaluateMxRecordProfile(TlsTestResults tlsTestResults)
        {
            List <BouncyCastleTlsTestResult> bouncyCastleTlsTestResults = new List <BouncyCastleTlsTestResult> {
                tlsTestResults.Ssl3FailsWithBadCipherSuite,
                tlsTestResults.Tls10AvailableWithBestCipherSuiteSelected,
                tlsTestResults.Tls10AvailableWithWeakCipherSuiteNotSelected,
                tlsTestResults.Tls11AvailableWithBestCipherSuiteSelected,
                tlsTestResults.Tls11AvailableWithWeakCipherSuiteNotSelected,
                tlsTestResults.Tls12AvailableWithBestCipherSuiteSelected,
                tlsTestResults.Tls12AvailableWithBestCipherSuiteSelectedFromReverseList,
                tlsTestResults.Tls12AvailableWithSha2HashFunctionSelected,
                tlsTestResults.Tls12AvailableWithWeakCipherSuiteNotSelected,
                tlsTestResults.TlsSecureDiffieHellmanGroupSelected,
                tlsTestResults.TlsSecureEllipticCurveSelected,
                tlsTestResults.TlsWeakCipherSuitesRejected
            };

            bool hasFailedConnection = bouncyCastleTlsTestResults.All(_ =>
                                                                      _.TlsError == TlsError.SESSION_INITIALIZATION_FAILED ||
                                                                      _.TlsError == TlsError.TCP_CONNECTION_FAILED);

            if (hasFailedConnection)
            {
                _log.LogDebug($"TLS connection failed for host {tlsTestResults.Id}");

                string failedConnectionErrors = string.Join(", ", bouncyCastleTlsTestResults
                                                            .Select(_ => _.ErrorDescription)
                                                            .Distinct()
                                                            .ToList());

                return(GetConnectionFailedResults(tlsTestResults.Id, failedConnectionErrors, tlsTestResults.ToTlsResult()));
            }

            bool hostNotFound = bouncyCastleTlsTestResults.All(_ => _.TlsError == TlsError.HOST_NOT_FOUND);

            if (hostNotFound)
            {
                _log.LogDebug($"Host not found for {tlsTestResults.Id}");

                return(GetHostNotFoundResults(tlsTestResults.Id, tlsTestResults.ToTlsResult()));
            }

            _log.LogDebug($"Evaluating TLS connection results for {tlsTestResults.Id}.");

            TlsResultsEvaluated tlsEvaluatedResults = await _mxSecurityEvaluator.Evaluate(tlsTestResults);

            return(tlsEvaluatedResults);
        }
        public async Task ShouldRescheduledWhenItHasFailedToCorrectPeriod()
        {
            string snsTopicArn = "snsTopicArn";

            A.CallTo(() => _tlsEntityConfig.SnsTopicArn).Returns(snsTopicArn);

            string hostName = "testhostname";

            TlsEntityState stateFromDb = new TlsEntityState(hostName)
            {
                TlsState = TlsState.Created
            };

            A.CallTo(() => _dao.Get(hostName)).Returns(Task.FromResult(stateFromDb));


            A.CallTo(() => _tlsEntityConfig.FailureNextScheduledInSeconds).Returns(15);
            A.CallTo(() => _tlsEntityConfig.MaxTlsRetryAttempts).Returns(5);

            A.CallTo(() => _clock.GetDateTimeUtc()).Returns(DateTime.MinValue);

            CertificateResults certificateResults = new CertificateResults(null, null);

            TlsResultsEvaluated message = new TlsResultsEvaluated(hostName, true, new TlsRecords(
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      , new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      , new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      , new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS)),
                                                                      new TlsRecord(new TlsEvaluatedResult(Guid.NewGuid(), EvaluatorResult.PASS))
                                                                      ), certificateResults);

            await _tlsEntity.Handle(message);

            A.CallTo(() => _changeNotifierComposite.Handle(stateFromDb, message, A <List <string> > ._)).MustNotHaveHappened();
            A.CallTo(() => _dao.Save(stateFromDb)).MustHaveHappenedOnceExactly();
            A.CallTo(() => _dispatcher.Dispatch(A <TlsRecordEvaluationsChanged> .That.Matches(a => a.Id == message.Id && a.TlsRecords == message.TlsRecords && a.CertificateResults == message.Certificates), snsTopicArn, null)).MustNotHaveHappened();
            A.CallTo(() => _dispatcher.Dispatch(A <CreateScheduledReminder> .That.Matches(a => a.ResourceId == hostName && a.Service == "Tls" && a.ScheduledTime.Second == 15), snsTopicArn)).MustHaveHappenedOnceExactly();
        }
        public async Task MixedRuleFailuresErrorsAsExpected()
        {
            TlsResultsEvaluated evaluatorResults = A.Fake <TlsResultsEvaluated>();

            var evaluationError1 = new RuleTypedTlsEvaluationResult(TlsTestType.Tls10Available, Guid.NewGuid(), EvaluatorResult.FAIL, "Rule 1 Failed");

            A.CallTo(() => _rule1.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult> {
                evaluationError1
            });
            A.CallTo(() => _rule2.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult>());

            EvaluationResult <TlsResultsEvaluated, RuleTypedTlsEvaluationResult> evaluationResult = await _evaluator.Evaluate(evaluatorResults);

            Assert.That(evaluationResult.Messages.Count, Is.EqualTo(1));
            Assert.That(evaluationResult.Messages[0], Is.EqualTo(evaluationError1));
        }
Exemplo n.º 10
0
        public async Task Handle(TlsResultsEvaluated message)
        {
            string messageId = message.Id.ToLower();

            TlsEntityState state = await LoadState(messageId, nameof(message));

            await _domainStatusPublisher.Publish(message);

            state.TlsState     = TlsState.Evaluated;
            state.FailureCount = message.Failed ? state.FailureCount + 1 : 0;

            CreateScheduledReminder reminder;

            if (!message.Failed ||
                message.Failed && state.FailureCount >= _tlsEntityConfig.MaxTlsRetryAttempts)
            {
                List <string> domains = await _dao.GetDomainsFromHost(messageId);

                _changeNotifiersComposite.Handle(state, message, domains);

                state.CertificateResults = message.Certificates;
                state.TlsRecords         = message.TlsRecords;
                state.LastUpdated        = message.Timestamp;

                await _dao.Save(state);

                _dispatcher.Dispatch(new TlsRecordEvaluationsChanged(messageId, state.TlsRecords, state.CertificateResults),
                                     _tlsEntityConfig.SnsTopicArn);

                reminder = new CreateScheduledReminder(Guid.NewGuid().ToString(), ServiceName, messageId,
                                                       _clock.GetDateTimeUtc().AddSeconds(_tlsEntityConfig.NextScheduledInSeconds));
            }
            else
            {
                await _dao.Save(state);

                reminder = new CreateScheduledReminder(Guid.NewGuid().ToString(), ServiceName, messageId,
                                                       _clock.GetDateTimeUtc().AddSeconds(_tlsEntityConfig.FailureNextScheduledInSeconds));
            }

            _dispatcher.Dispatch(reminder, _tlsEntityConfig.SnsTopicArn);
        }
        public async Task StopRuleFailureHaltProcessing()
        {
            TlsResultsEvaluated evaluatorResults = A.Fake <TlsResultsEvaluated>();

            var evaluationError1 = new RuleTypedTlsEvaluationResult(TlsTestType.Tls10Available, Guid.NewGuid(), EvaluatorResult.FAIL, "Rule 1 Failed");
            var evaluationError2 = new RuleTypedTlsEvaluationResult(TlsTestType.Tls10Available, Guid.NewGuid(), EvaluatorResult.WARNING, "Rule 2 Failed");

            A.CallTo(() => _rule1.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult> {
                evaluationError1
            });
            A.CallTo(() => _rule1.IsStopRule).Returns(true);

            A.CallTo(() => _rule2.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult> {
                evaluationError2
            });

            EvaluationResult <TlsResultsEvaluated, RuleTypedTlsEvaluationResult> evaluationResult = await _evaluator.Evaluate(evaluatorResults);

            Assert.That(evaluationResult.Messages.Count, Is.EqualTo(1));
            Assert.That(evaluationResult.Messages[0], Is.EqualTo(evaluationError1));
        }
        public async Task FailureEvaluatorUsedWhenProvided()
        {
            TlsResultsEvaluated evaluatorResults = A.Fake <TlsResultsEvaluated>();

            var evaluationError1 = new RuleTypedTlsEvaluationResult(TlsTestType.Tls10Available, Guid.NewGuid(), EvaluatorResult.PASS, "Rule 1 Failed");
            var evaluationError2 = new RuleTypedTlsEvaluationResult(TlsTestType.Tls10Available, Guid.NewGuid(), EvaluatorResult.WARNING, "Rule 2 Failed");

            A.CallTo(() => _rule1.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult> {
                evaluationError1
            });
            A.CallTo(() => _rule1.Category).Returns("Cat1");
            A.CallTo(() => _rule1.IsStopRule).Returns(true);

            A.CallTo(() => _rule2.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult> {
                evaluationError2
            });
            A.CallTo(() => _rule2.Category).Returns("Cat1");

            EvaluationResult <TlsResultsEvaluated, RuleTypedTlsEvaluationResult> evaluationResult = await _evaluator.Evaluate(evaluatorResults, _ => true);

            Assert.That(evaluationResult.Messages.Count, Is.EqualTo(1));
        }
        public async Task RulesInDifferentCategoriesStillProcessedOnOtherCategoryFailure()
        {
            TlsResultsEvaluated evaluatorResults = A.Fake <TlsResultsEvaluated>();

            var evaluationError1 = new RuleTypedTlsEvaluationResult(TlsTestType.Tls10Available, Guid.NewGuid(), EvaluatorResult.FAIL, "Rule 1 Failed");
            var evaluationError2 = new RuleTypedTlsEvaluationResult(TlsTestType.Tls10Available, Guid.NewGuid(), EvaluatorResult.WARNING, "Rule 2 Failed");

            A.CallTo(() => _rule1.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult> {
                evaluationError1
            });
            A.CallTo(() => _rule1.Category).Returns("Cat1");
            A.CallTo(() => _rule1.IsStopRule).Returns(true);

            A.CallTo(() => _rule2.Evaluate(evaluatorResults)).Returns(new List <RuleTypedTlsEvaluationResult> {
                evaluationError2
            });
            A.CallTo(() => _rule2.Category).Returns("Cat2");

            EvaluationResult <TlsResultsEvaluated, RuleTypedTlsEvaluationResult> evaluationResult = await _evaluator.Evaluate(evaluatorResults);

            Assert.That(evaluationResult.Messages.Count, Is.EqualTo(2));
            Assert.That(evaluationResult.Messages[0], Is.EqualTo(evaluationError1));
            Assert.That(evaluationResult.Messages[1], Is.EqualTo(evaluationError2));
        }
        private TlsResultsEvaluated CreateTlsResultsEvaluatedWithResults(TlsRecords records = null)
        {
            TlsResultsEvaluated recordsEvaluated = new TlsResultsEvaluated("mailchecktest.host.gov.uk", false, records ?? CreateTlsRecords());

            return(recordsEvaluated);
        }