Esempio n. 1
0
        public async Task SetChallengeAndResponseAsync(string challenge, string response)
        {
            try
            {
                if (_settings.Diagnostics)
                {
                    Console.WriteLine($"[CERT.STORAGE] Request to store response: {response} for challenge: {challenge}");
                }

                var model = new AcmeChallengeResponse(challenge);
                model.Response = response;

                var table = await GetCloudTableAsync();

                var operation = TableOperation.Insert(model);
                await table.ExecuteAsync(operation);

                if (_settings.Diagnostics)
                {
                    Console.WriteLine($"[CERT.STORAGE] Successfully stored response: {response} for challenge: {challenge}");
                }
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("[CERT.STORAGE] Could not store challenge/response to table storage: " + ex.Message);
                Console.ResetColor();
            }
        }
Esempio n. 2
0
        private async Task CheckDnsChallengeAsync(AcmeChallengeResponse challengeResult, string fullDomain)
        {
            var retries = 0;
            var delay   = TimeSpan.FromSeconds(10);

            var txtRecords = new List <DnsClient.Protocol.TxtRecord>();

            while (true)
            {
                _logger.LogInformation("[Azure DNS][Update Check] Domain Name: {domainName}", challengeResult.Domain);

                var queryResult = await _lookupClient.QueryAsync(fullDomain, QueryType.TXT);

                var records = queryResult.Answers
                              .OfType <DnsClient.Protocol.TxtRecord>()
                              .ToArray();

                txtRecords.AddRange(records);

                if (txtRecords.Count > 0 &&
                    txtRecords.Any(x => x.Text.Contains(challengeResult.Token)))
                {
                    break;
                }

                if (retries > 10)
                {
                    break;
                }

                await Task.Delay(delay);

                retries++;
            }

            if (txtRecords.Count == 0)
            {
                throw new LetsEncryptException($"{challengeResult.Domain} did not resolve.");
            }

            if (!txtRecords.Any(x => x.Text.Contains(challengeResult.Token)))
            {
                throw new LetsEncryptException($"{challengeResult.Domain} value is not correct.");
            }
        }
Esempio n. 3
0
        public async Task SetChallengeAndResponseAsync(string challenge, string response)
        {
            if (_settings == null || _instanceLogger == null)
            {
                throw new InvalidOperationException("[SetChallengeAndResponseAsync] Not initialized.");
            }

            try
            {
                if (String.IsNullOrEmpty(challenge))
                {
                    throw new ArgumentNullException(nameof(challenge));
                }
                if (String.IsNullOrEmpty(response))
                {
                    throw new ArgumentNullException(nameof(response));
                }

                this._instanceLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Verbose, "BlobCertStorage_SetChallengeAndResponseAsync", "Attempt to write challenge and response.",
                                                    challenge.ToKVP("challenge"), response.ToKVP("response"));

                var model = new AcmeChallengeResponse(challenge);
                model.Response = response;

                var table = await GetCloudTableAsync();

                var operation = TableOperation.Insert(model);
                await table.ExecuteAsync(operation);

                this._instanceLogger.AddCustomEvent(Core.PlatformSupport.LogLevel.Verbose, "BlobCertStorage_SetChallengeAndResponseAsync", "Wrote challenge and response.",
                                                    challenge.ToKVP("challenge"), response.ToKVP("response"));
            }
            catch (Exception ex)
            {
                _instanceLogger.AddException("BlobCertStorage_SetChallengeAndResponseAsync", ex, challenge.ToKVP("challenge"), response.ToKVP("response"));
            }
        }
Esempio n. 4
0
        public async Task DnsAuthorizationAsync(string named, string instanceId, AcmeChallengeResponse challenge)
        {
            var options = _optionsMonitor.Get(named);

            using var dnsManagementClient = await CreateDnsManagementClientAsync(options);

            var zone       = (await dnsManagementClient.Zones.ListAsync()).FirstOrDefault(x => challenge.Domain.EndsWith(x?.Name !));
            var resourceId = ParseResourceId(zone.Id);

            var fullDomainName = GetChallengeDnsName(challenge.Domain);

            var domain = fullDomainName.Replace("." + zone.Name, string.Empty);

            _logger.LogInformation("[Azure Dns Update][Started] Domain Name: {domainName}", challenge.Domain);

            RecordSetInner?recordSet;

            try
            {
                recordSet = await dnsManagementClient.RecordSets.GetAsync(resourceId["resourceGroups"], zone.Name, domain, RecordType.TXT);
            }
            catch
            {
                recordSet = null;
            }

            if (recordSet != null)
            {
                if (recordSet.Metadata == null || !recordSet.Metadata.TryGetValue("InstanceId", out var dnsInstanceId) || dnsInstanceId != instanceId)
                {
                    recordSet.Metadata = new Dictionary <string, string>
                    {
                        { "InstanceId", instanceId }
                    };

                    recordSet.TxtRecords.Clear();
                }

                recordSet.TTL = 3600;
                recordSet.TxtRecords.Add(new TxtRecord(new[] { challenge.Token }));
            }
            else
            {
                recordSet = new RecordSetInner()
                {
                    TTL      = 3600,
                    Metadata = new Dictionary <string, string>
                    {
                        { "InstanceId", instanceId }
                    },
                    TxtRecords = new[]
                    {
                        new TxtRecord(new[] { challenge.Token })
                    }
                };
            }

            await dnsManagementClient.RecordSets.CreateOrUpdateAsync(resourceId["resourceGroups"], zone.Name, domain, RecordType.TXT, recordSet);

            _logger.LogInformation("[Azure DNS Update][Ended] Domain Name: {domainName}", challenge.Domain);

            await CheckDnsChallengeAsync(challenge, fullDomainName);
        }