Exemple #1
0
        public DomainScan Scan()
        {
            return(NamedLocker.RunWithLock(_domain.Uri, () =>
            {
                _logger.LogInformation($"Scanning domain {_domain.Uri}");
                var uri = new Uri(_domain.Uri);
                var hostEntry = _lookupClient.GetHostEntry(uri.Host);
                if (hostEntry != null && hostEntry.AddressList.Any())
                {
                    var msg = $"{uri.Host} resolved to the following IP addresses: " +
                              $"{string.Join(", ", hostEntry.AddressList.Select(x => x))}";
                    _messages.Add(msg);

                    _logger.LogDebug(msg);

                    var ip = hostEntry.AddressList.First();
                    OpenSslConnection(uri.Host, ip, uri.Port);
                }
                var domainCert = DomainCertificate.FromX509Certificate2(_certificate, CertificateSource.TrackedDomain);
                _certificate?.Dispose();

                var domainScan = new DomainScan
                {
                    DateScan = DateTime.UtcNow,
                    DomainCertificate = domainCert,
                    ScanResult = string.Join("\r\n", _messages),
                    ScanSuccess = domainCert != null,
                    ScanStatus = _scanStatus
                };
                _logger.LogInformation($"Domain scan finished {(domainScan.ScanSuccess ? "successfully" : "unsuccessfully")} " +
                                       $"for {_domain.Uri}");

                return domainScan;
            }));
        }
Exemple #2
0
        private async Task AddOrUpdateCertificate(IFormFile certificateFile)
        {
            var bytes = await certificateFile.ReadAsBytesAsync();

            X509Certificate2 cert = null;

            try
            {
                cert = new X509Certificate2(bytes);
            }
            catch { }

            if (cert == null)
            {
                ModelState.AddModelError("Input.CertificateFile", "Not a valid certificate");
                return;
            }

            var existingDomainCert = await _dataContext.DomainCertificates
                                     .FirstOrDefaultAsync(x => x.Thumbprint == cert.Thumbprint);

            if (existingDomainCert != null)
            {
                ModelState.AddModelError("Input.CertificateFile", "Certificate already exists");
            }
            else
            {
                var domainCert = DomainCertificate.FromX509Certificate2(cert, CertificateSource.Uploaded);
                _dataContext.DomainCertificates.Add(domainCert);
                await _dataContext.SaveChangesAsync();

                StatusMessage = "New certificate added";
            }
        }
Exemple #3
0
        public async Task <AcmeOrder> Complete()
        {
            if (_acmeOrder.Status != AcmeOrderStatus.Validating)
            {
                return(_acmeOrder);
            }

            foreach (var cc in _authChallengeContainers)
            {
                cc.AuthorizationTask = cc.AuthorizationContext.Resource();
            }

            var attempts = 5;

            do
            {
                // Kick off the authorization tasks for the tasks that haven't been run yet
                await Task.WhenAll(_authChallengeContainers
                                   .Where(x => !x.AuthorizationTask.IsCompleted)
                                   .Select(x => x.AuthorizationTask)
                                   .ToList());

                var incompletes = 0;
                // After running the tasks, find all incomplete authz
                foreach (var cc in _authChallengeContainers)
                {
                    var status    = cc.AuthorizationTask.Result.Status;
                    var completed = status == AuthorizationStatus.Valid ||
                                    status == AuthorizationStatus.Invalid;
                    if (!completed)
                    {
                        incompletes++;

                        // Update the task such that it's a new task and it will be awaited above
                        cc.AuthorizationTask = cc.AuthorizationContext.Resource();
                    }
                    else
                    {
                        cc.Authorization = cc.AuthorizationTask.Result;
                    }
                }

                // Find incomplete ones and try again
                _logger.LogDebug($"{incompletes} incomplete authorizations.");

                if (incompletes == 0)
                {
                    break;
                }

                await Task.Delay(5000);
            } while (attempts-- > 0);

            // All authorizations have completed, save the results
            foreach (var cc in _authChallengeContainers)
            {
                cc.Authorization = cc.AuthorizationTask.Result;
            }

            // At this point, they're all complete and need to see which are valid/invalid
            // and obtain the cert if possible.
            try
            {
                var invalidResp = _authChallengeContainers
                                  .SelectMany(x => x.Authorization.Challenges)
                                  .Where(x => x.Error != null)
                                  .ToList();

                var errors = string.Join("\r\n", invalidResp
                                         .Select(x => $"{x.Error.Status} {x.Error.Type} {x.Error.Detail}"));

                _acmeOrder.RequestCount         = _authChallengeContainers.Count;
                _acmeOrder.InvalidResponseCount = invalidResp.Count;
                _acmeOrder.Errors = errors;
                _acmeOrder.Status = AcmeOrderStatus.Completed;

                if (invalidResp.Count > 0)
                {
                    _acmeOrder.Status = AcmeOrderStatus.Invalid;
                    return(_acmeOrder);
                }

                var cert = await _order.Generate(
                    new CsrInfo
                {
                    CommonName       = _acmeCertificate.CsrCommonName,
                    CountryName      = _acmeCertificate.CsrCountryName,
                    Locality         = _acmeCertificate.CsrLocality,
                    Organization     = _acmeCertificate.CsrOrganization,
                    OrganizationUnit = _acmeCertificate.CsrOrganizationUnit,
                    State            = _acmeCertificate.CsrState
                }, KeyFactory.FromPem(_acmeCertificate.Key.RawData));

                var certBytes = cert.Certificate.ToDer();

                var xCert      = new X509Certificate2(certBytes);
                var domainCert = DomainCertificate.FromX509Certificate2(xCert, CertificateSource.AcmeCertificate);
                xCert.Dispose();

                _acmeOrder.RawDataPem        = cert.ToPem();
                _acmeOrder.DomainCertificate = domainCert;

                return(_acmeOrder);
            }
            catch (AcmeRequestException e)
            {
                _acmeOrder.Status = AcmeOrderStatus.Error;
                _acmeOrder.Errors = $"{e.Error.Status} {e.Error.Type} {e.Error.Detail}";
            }
            catch (Exception)
            {
                _acmeOrder.Status = AcmeOrderStatus.Error;
                _acmeOrder.Errors = "Unknown Error";
            }
            return(_acmeOrder);
        }