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