예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WireSentry.PacketProcessor"/> class.
        /// </summary>
        /// <param name='dns'>
        /// The DNS Provider which handles DNS lookups for the packets.
        /// </param>
        public PacketProcessor(IDnsProvider dns)
        {
            Dns            = dns;
            DnsLookupQueue = new Queue <DataPacket>();
            WaitHandle     = new EventWaitHandle(false, EventResetMode.AutoReset);

            //Create a bBackground thread to handle DNS lookups for packets
            new Thread(() => {
                while (true)
                {
                    //Wait until an element has entered the work queue.
                    WaitHandle.WaitOne();

                    lock (DnsLookupQueue)
                    {
                        /*
                         * Continue pulling items out of the Queue while items exist
                         * in the queue.  Stop once the Queue is empty and wait for more items
                         * to enter.
                         *
                         * Once the packet is dequeued, attempt to reverse-dns lookup the source
                         * and destination addresses and add them to the existing packet.
                         */
                        while (DnsLookupQueue.Count != 0)
                        {
                            var dpacket               = DnsLookupQueue.Dequeue();
                            dpacket.DomainSource      = Dns.Get(dpacket.IpAddressSource);
                            dpacket.DomainDestination = Dns.Get(dpacket.IpAddressDestination);
                        }
                    }
                }
            }).Start();
        }
예제 #2
0
 public AcmeClient(IDnsProvider dnsProvider, DnsLookupService dnsLookupService, ICertificateStore certifcateStore, ILogger <AcmeClient> logger = null)
 {
     this.dnsProvider      = dnsProvider;
     this.dnsLookupService = dnsLookupService;
     this.certificateStore = certifcateStore;
     this.logger           = logger ?? NullLogger <AcmeClient> .Instance;
 }
예제 #3
0
 public Worker(ILogger <Worker> logger, MonitorSettings settings, IPublicIpProvider publicIpProvider, IDnsProvider dnsProvider)
 {
     _logger           = logger;
     _settings         = settings;
     _publicIpProvider = publicIpProvider;
     _dnsProvider      = dnsProvider;
 }
예제 #4
0
 public AcmeClient(IDnsProvider dnsProvider, DnsLookupService dnsLookupService, IFileSystem fileSystem = null, ILogger <AcmeClient> logger = null)
 {
     this.dnsProvider      = dnsProvider;
     this.dnsLookupService = dnsLookupService;
     this.fileSystem       = fileSystem ?? new FileSystem();
     this.logger           = logger ?? NullLogger <AcmeClient> .Instance;
 }
예제 #5
0
        public async Task InitTest()
        {
            var credentialsManager = new CredentialsManager();

            _credentials = await credentialsManager.GetUnlockedCredentialsDictionary(_credStorageKey);

            _provider = new Providers.DNS.Cloudflare.DnsProviderCloudflare(_credentials);
            await _provider.InitProvider();
        }
예제 #6
0
        static string AddRecordToDNS(IDnsProvider dnsProvider, DnsChallenge dnsChallenge)
        {
            var dnsName  = dnsChallenge.RecordName;
            var dnsValue = Regex.Replace(dnsChallenge.RecordValue, "\\s", "");

            return(dnsProvider.AddTxtRecord(dnsName, dnsValue));

            // todo: resolve the txt record
        }
예제 #7
0
        public static void Authorize(AcmeClient client, IDnsProvider dnsProvider, string hostName, List <string> alternativeNames = null)
        {
            var dnsIdentifiers = new List <string>()
            {
                hostName
            };

            if (alternativeNames != null)
            {
                dnsIdentifiers.AddRange(alternativeNames);
            }

            var authResults = new List <AuthorizationState>();

            foreach (var dnsIdentifier in dnsIdentifiers)
            {
                var authzState = client.AuthorizeIdentifier(dnsIdentifier);
                var challenge  = client.DecodeChallenge(authzState, AcmeProtocol.CHALLENGE_TYPE_DNS);

                var dnsChallenge = challenge.Challenge as DnsChallenge;
                var dnsRecordRef = AddRecordToDNS(dnsProvider, dnsChallenge);
                Thread.Sleep(3 * 1000); //  wait for the newly created TXT record to take effect

                try
                {
                    authzState.Challenges = new AuthorizeChallenge[] { challenge };
                    client.SubmitChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_DNS, true);

                    // have to loop to wait for server to stop being pending.
                    // todo: put timeout/retry limit in this loop
                    while (authzState.Status == "pending")
                    {
                        Thread.Sleep(3 * 1000); // this has to be here to give ACME server a chance to think
                        var newAuthzState = client.RefreshIdentifierAuthorization(authzState);
                        if (newAuthzState.Status != "pending")
                        {
                            authzState = newAuthzState;
                        }
                    }

                    authResults.Add(authzState);
                }
                finally
                {
                    if (!string.IsNullOrEmpty(dnsRecordRef))
                    {
                        dnsProvider.RemoveTxtRecord(dnsRecordRef);
                    }
                }
            }

            if (authResults.Any(result => result.Status != "valid"))
            {
                throw new AuthorizationFailedException(authResults);
            }
        }
예제 #8
0
        public async Task InitTest()
        {
            var credentialsManager = new CredentialsManager();

            _credentials = await credentialsManager.GetUnlockedCredentialsDictionary(_credStorageKey);

            _provider = new Providers.DNS.Azure.DnsProviderAzure(_credentials);
            await _provider.InitProvider(new Dictionary <string, string> {
            });
        }
예제 #9
0
 public SharedFunctions(LookupClient lookupClient, IAcmeProtocolClientFactory acmeProtocolClientFactory,
                        IDnsProvider dnsProvider, CertificateClient certificateClient,
                        WebhookClient webhookClient, IOptions <AcmebotOptions> options)
 {
     _acmeProtocolClientFactory = acmeProtocolClientFactory;
     _dnsProvider       = dnsProvider;
     _lookupClient      = lookupClient;
     _certificateClient = certificateClient;
     _webhookClient     = webhookClient;
     _options           = options.Value;
 }
예제 #10
0
 public SharedFunctions(LookupClient lookupClient, IAcmeProtocolClientFactory acmeProtocolClientFactory,
                        IDnsProvider dnsProvider, KeyVaultClient keyVaultClient,
                        WebhookClient webhookClient, IOptions <AcmebotOptions> options)
 {
     _acmeProtocolClientFactory = acmeProtocolClientFactory;
     _dnsProvider    = dnsProvider;
     _lookupClient   = lookupClient;
     _keyVaultClient = keyVaultClient;
     _webhookClient  = webhookClient;
     _options        = options.Value;
 }
예제 #11
0
 public SharedActivity(LookupClient lookupClient, AcmeProtocolClientFactory acmeProtocolClientFactory,
                       IDnsProvider dnsProvider, CertificateClient certificateClient,
                       WebhookInvoker webhookInvoker, IOptions <AcmebotOptions> options, ILogger <SharedActivity> logger)
 {
     _acmeProtocolClientFactory = acmeProtocolClientFactory;
     _dnsProvider       = dnsProvider;
     _lookupClient      = lookupClient;
     _certificateClient = certificateClient;
     _webhookInvoker    = webhookInvoker;
     _options           = options.Value;
     _logger            = logger;
 }
예제 #12
0
 Program()
 {
     _clock                       = new UtcClock();
     _dnsProvider                 = new DnsProvider();
     _hashingService              = new Md5HashingService();
     _msgSerializer               = new MessageSerializer();
     _nodeSocketFactory           = new InProcNodeSocketFactory();
     _correlationFactory          = new CorrelationIdFactory();
     _actionTimerFactory          = new ActionTimerFactory();
     _expiryCalculator            = new ExpiryTimeCalculator(_clock);
     _random                      = new RandomNumberGenerator(_correlationFactory);
     _marshallerFactory           = new NodeMarshallerFactory(_msgSerializer);
     _communicationManagerFactory = new CommunicationManagerFactory();
 }
예제 #13
0
        public static async Task <IDnsProvider> GetDnsProvider(string providerType, Dictionary <string, string> credentials, Dictionary <string, string> parameters, ILog log = null)
        {
            IDnsProvider dnsAPIProvider = null;



            if (!string.IsNullOrEmpty(providerType))
            {
                List <IDnsProviderProviderPlugin> providerPlugins = PluginManager.CurrentInstance.DnsProviderProviders;
                foreach (IDnsProviderProviderPlugin providerPlugin in providerPlugins)
                {
                    dnsAPIProvider = providerPlugin.GetProvider(providerPlugin.GetType(), providerType);
                    if (dnsAPIProvider != null)
                    {
                        break;
                    }
                }
            }
            else
            {
                return(null);
            }

            if (dnsAPIProvider == null)
            {
                // we don't have the requested provider available, plugin probably didn't load or ID is wrong
                if (providerType == "DNS01.API.MSDNS")
                {
                    // We saved earlier that the MSDNS provider failed to load. It's now explicitly being requested, so log that failure.
                    log?.Error("Failed to create MS DNS API Provider. Check Microsoft.Management.Infrastructure is available and install latest compatible Windows Management Framework: https://docs.microsoft.com/en-us/powershell/wmf/overview");
                    return(null);
                }
                else
                {
                    log?.Error($"Cannot create requested DNS API Provider. Plugin did not load or provider ID is invalid: {providerType}");
                    return(null);
                }
            }
            else
            {
                await dnsAPIProvider.InitProvider(credentials, parameters, log);
            }

            return(dnsAPIProvider);
        }
예제 #14
0
        public static async Task <IDnsProvider> GetDnsProvider(string providerType, Dictionary <string, string> credentials, Dictionary <string, string> parameters, ILog log = null)
        {
            ProviderDefinition providerDefinition;
            IDnsProvider       dnsAPIProvider = null;

            if (!string.IsNullOrEmpty(providerType))
            {
                providerDefinition = (await ChallengeProviders.GetChallengeAPIProviders()).FirstOrDefault(p => p.Id == providerType);
            }
            else
            {
                return(null);
            }

            if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.PYTHON_HELPER)
            {
                if (credentials == null || !credentials.Any())
                {
                    throw new CredentialsRequiredException();
                }

                dnsAPIProvider = new LibcloudDNSProvider(credentials);
            }
            else if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.INTERNAL)
            {
                if (credentials == null || !credentials.Any())
                {
                    throw new CredentialsRequiredException();
                }

                // instantiate/initialise the required DNS provider
                if (providerDefinition.Id == DnsProviderAWSRoute53.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderAWSRoute53(credentials);
                }
                else if (providerDefinition.Id == DnsProviderAzure.Definition.Id)
                {
                    var azureDns = new DnsProviderAzure(credentials);

                    dnsAPIProvider = azureDns;
                }
                else if (providerDefinition.Id == DnsProviderCloudflare.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderCloudflare(credentials);
                }
                else if (providerDefinition.Id == DnsProviderGoDaddy.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderGoDaddy(credentials);
                }
                else if (providerDefinition.Id == DnsProviderSimpleDNSPlus.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderSimpleDNSPlus(credentials);
                }
                else if (providerDefinition.Id == DnsProviderDnsMadeEasy.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderDnsMadeEasy(credentials);
                }
                else if (providerDefinition.Id == DnsProviderOvh.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderOvh(credentials);
                }
                else if (providerDefinition.Id == DnsProviderAliyun.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderAliyun(credentials);
                }
            }
            else if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.MANUAL)
            {
                if (providerDefinition.Id == DNS.DnsProviderManual.Definition.Id)
                {
                    dnsAPIProvider = new DNS.DnsProviderManual(parameters);
                }
            }
            else if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.CUSTOM_SCRIPT)
            {
                if (providerDefinition.Id == DNS.DnsProviderScripting.Definition.Id)
                {
                    dnsAPIProvider = new DNS.DnsProviderScripting(parameters);
                }
            }

            await dnsAPIProvider.InitProvider(log);

            return(dnsAPIProvider);
        }
예제 #15
0
        public async Task <DnsChallengeHelperResult> DeleteDNSChallenge(ILog log, ManagedCertificate managedcertificate, string domain, string txtRecordName, string txtRecordValue)
        {
            // for a given managed site configuration, attempt to delete the TXT record created for
            // the challenge

            var credentials = new Dictionary <string, string>();

            IDnsProvider dnsAPIProvider = null;

            var challengeConfig = managedcertificate.GetChallengeConfig(domain);

            if (challengeConfig == null || challengeConfig.ChallengeProvider == null)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = true, Message = $"The DNS record {txtRecordName} can now be removed."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            if (challengeConfig.ChallengeProvider.Contains(".Manual"))
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = true, Message = $"The DNS record {txtRecordName} can now be removed."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = true
                });
            }

            if (!string.IsNullOrEmpty(challengeConfig.ChallengeCredentialKey))
            {
                // decode credentials string array
                try
                {
                    credentials = await _credentialsManager.GetUnlockedCredentialsDictionary(challengeConfig.ChallengeCredentialKey);
                }
                catch (Exception)
                {
                    return(new DnsChallengeHelperResult
                    {
                        Result = new ActionResult {
                            IsSuccess = false, Message = "DNS Challenge API Credentials could not be decrypted. The original user must be used for decryption."
                        },
                        PropagationSeconds = 0,
                        IsAwaitingUser = false
                    });
                }
            }

            var parameters = new Dictionary <string, string>();

            if (challengeConfig.Parameters != null)
            {
                foreach (var p in challengeConfig.Parameters)
                {
                    parameters.Add(p.Key, p.Value);
                }
            }

            try
            {
                dnsAPIProvider = await ChallengeProviders.GetDnsProvider(challengeConfig.ChallengeProvider, credentials, parameters);
            }
            catch (ChallengeProviders.CredentialsRequiredException)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "This DNS Challenge API requires one or more credentials to be specified."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }
            catch (Exception exp)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = $"DNS Challenge API Provider could not be created. Check all required credentials are set. {exp.ToString()}"
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            if (dnsAPIProvider == null)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "DNS Challenge API Provider not set or not recognised. Select an API to proceed."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            string zoneId = null;

            if (parameters != null && parameters.ContainsKey("zoneid"))
            {
                zoneId = parameters["zoneid"]?.Trim();
            }
            else
            {
                zoneId = challengeConfig.ZoneId?.Trim();
            }

            if (dnsAPIProvider != null)
            {
                //most DNS providers require domains to by ASCII
                txtRecordName = _idnMapping.GetAscii(txtRecordName).ToLower();

                log.Information($"DNS: Deleting TXT Record '{txtRecordName}', in Zone Id '{zoneId}' using API provider '{dnsAPIProvider.ProviderTitle}'");
                try
                {
                    var result = await dnsAPIProvider.DeleteRecord(new DnsRecord
                    {
                        RecordType       = "TXT",
                        TargetDomainName = domain,
                        RecordName       = txtRecordName,
                        RecordValue      = txtRecordValue,
                        ZoneId           = zoneId
                    });

                    result.Message = $"{dnsAPIProvider.ProviderTitle} :: {result.Message}";

                    return(new DnsChallengeHelperResult
                    {
                        Result = result,
                        PropagationSeconds = dnsAPIProvider.PropagationDelaySeconds,
                        IsAwaitingUser = challengeConfig.ChallengeProvider.Contains(".Manual")
                    });
                }
                catch (Exception exp)
                {
                    return(new DnsChallengeHelperResult
                    {
                        Result = new ActionResult {
                            IsSuccess = false, Message = $"Failed [{dnsAPIProvider.ProviderTitle}]: " + exp.Message
                        },
                        PropagationSeconds = 0,
                        IsAwaitingUser = false
                    });
                }
            }
            else
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "Error: Could not determine DNS API Provider."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }
        }
예제 #16
0
        public async Task <DnsChallengeHelperResult> GetDnsProvider(string providerTypeId, string credentialsId, Dictionary <string, string> parameters)
        {
            var credentialsManager = new CredentialsManager();
            var credentials        = new Dictionary <string, string>();

            IDnsProvider dnsAPIProvider = null;

            if (!string.IsNullOrEmpty(credentialsId))
            {
                // decode credentials string array
                try
                {
                    credentials = await credentialsManager.GetUnlockedCredentialsDictionary(credentialsId);
                }
                catch (Exception)
                {
                    return(new DnsChallengeHelperResult
                    {
                        Result = new ActionResult {
                            IsSuccess = false, Message = "DNS Challenge API Credentials could not be decrypted. The original user must be used for decryption."
                        },
                        PropagationSeconds = 0,
                        IsAwaitingUser = false
                    });
                }
            }

            try
            {
                dnsAPIProvider = await ChallengeProviders.GetDnsProvider(providerTypeId, credentials, parameters);
            }
            catch (ChallengeProviders.CredentialsRequiredException)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "This DNS Challenge API requires one or more credentials to be specified."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }
            catch (Exception exp)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = $"DNS Challenge API Provider could not be created. Check all required credentials are set and software dependencies installed. {exp.ToString()}"
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            if (dnsAPIProvider == null)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "DNS Challenge API Provider not set or could not load."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            return(new DnsChallengeHelperResult
            {
                Result = new ActionResult {
                    IsSuccess = true, Message = "Create Provider Instance"
                },
                Provider = dnsAPIProvider
            });
        }
예제 #17
0
        public static async Task <IDnsProvider> GetDnsProvider(string providerType, Dictionary <string, string> credentials, Dictionary <string, string> parameters, ILog log = null)
        {
            ChallengeProviderDefinition providerDefinition;
            IDnsProvider dnsAPIProvider = null;

            if (!string.IsNullOrEmpty(providerType))
            {
                providerDefinition = (await ChallengeProviders.GetChallengeAPIProviders()).FirstOrDefault(p => p.Id == providerType);
            }
            else
            {
                return(null);
            }

            if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.PYTHON_HELPER)
            {
                if (credentials == null || !credentials.Any())
                {
                    throw new CredentialsRequiredException();
                }

                dnsAPIProvider = new LibcloudDNSProvider(credentials);
            }
            else if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.INTERNAL)
            {
                if (credentials == null)
                {
                    throw new CredentialsRequiredException();
                }

                // instantiate/initialise the required DNS provider
                if (providerDefinition.Id == DnsProviderAWSRoute53.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderAWSRoute53(credentials);
                }
                else if (providerDefinition.Id == DnsProviderAzure.Definition.Id)
                {
                    var azureDns = new DnsProviderAzure(credentials);

                    dnsAPIProvider = azureDns;
                }
                else if (providerDefinition.Id == DnsProviderCloudflare.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderCloudflare(credentials);
                }
                else if (providerDefinition.Id == DnsProviderGoDaddy.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderGoDaddy(credentials);
                }
                else if (providerDefinition.Id == DnsProviderSimpleDNSPlus.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderSimpleDNSPlus(credentials);
                }
                else if (providerDefinition.Id == DnsProviderDnsMadeEasy.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderDnsMadeEasy(credentials);
                }
                else if (providerDefinition.Id == DnsProviderOvh.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderOvh(credentials);
                }
                else if (providerDefinition.Id == DnsProviderAliyun.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderAliyun(credentials);
                }
                else if (providerDefinition.Id == "DNS01.API.MSDNS") // DnsProviderMSDNS.Definition.Id - avoid instantiating provider due to possible dll loading issues
                {
                    dnsAPIProvider = TryGetMsDNSProvider(credentials, parameters, log);
                }
                else if (providerDefinition.Id == DnsProviderAcmeDns.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderAcmeDns(credentials, parameters, Util.GetAppDataFolder());
                }
                else if (providerDefinition.Id == DnsProviderNameCheap.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderNameCheap(credentials);
                }
                else if (providerDefinition.Id == DnsProviderTransIP.Definition.Id)
                {
                    dnsAPIProvider = new DnsProviderTransIP(credentials);
                }
            }
            else if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.MANUAL)
            {
                if (providerDefinition.Id == DNS.DnsProviderManual.Definition.Id)
                {
                    dnsAPIProvider = new DNS.DnsProviderManual();
                }
            }
            else if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.CUSTOM_SCRIPT)
            {
                if (providerDefinition.Id == DNS.DnsProviderScripting.Definition.Id)
                {
                    dnsAPIProvider = new DNS.DnsProviderScripting(parameters);
                }
            }
            else if (providerDefinition.HandlerType == Models.Config.ChallengeHandlerType.POWERSHELL)
            {
                if (providerDefinition.Config.Contains("Provider=Certify.Providers.DNS.PoshACME"))
                {
                    var scriptPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"Scripts\DNS\PoshACME\Plugins");
                    var ps         = new DNS.DnsProviderPoshACME(parameters, credentials, scriptPath);
                    ps.DelegateProviderDefinition = providerDefinition;

                    dnsAPIProvider = ps;
                }
            }

            if (dnsAPIProvider != null)
            {
                await dnsAPIProvider.InitProvider(parameters, log);
            }

            return(dnsAPIProvider);
        }
예제 #18
0
        public async Task <DnsChallengeHelperResult> CompleteDNSChallenge(ILog log, ManagedCertificate managedcertificate, string domain, string txtRecordName, string txtRecordValue, bool isTestMode)
        {
            // for a given managed site configuration, attempt to complete the required challenge by
            // creating the required TXT record

            var credentials = new Dictionary <string, string>();

            IDnsProvider dnsAPIProvider = null;

            var challengeConfig = managedcertificate.GetChallengeConfig(domain);

            /*if (String.IsNullOrEmpty(challengeConfig.ZoneId))
             * {
             *  return new ActionResult { IsSuccess = false, Message = "DNS Challenge Zone Id not set. Set the Zone Id to proceed." };
             * }*/

            if (!string.IsNullOrEmpty(challengeConfig.ChallengeCredentialKey))
            {
                // decode credentials string array
                try
                {
                    credentials = await _credentialsManager.GetUnlockedCredentialsDictionary(challengeConfig.ChallengeCredentialKey);
                }
                catch (Exception)
                {
                    return(new DnsChallengeHelperResult
                    {
                        Result = new ActionResult {
                            IsSuccess = false, Message = "DNS Challenge API Credentials could not be decrypted. The original user must be used for decryption."
                        },
                        PropagationSeconds = 0,
                        IsAwaitingUser = false
                    });
                }
            }

            var parameters = new Dictionary <string, string>();

            if (challengeConfig.Parameters != null)
            {
                foreach (var p in challengeConfig.Parameters)
                {
                    parameters.Add(p.Key, p.Value);
                }
            }

            try
            {
                dnsAPIProvider = await ChallengeProviders.GetDnsProvider(challengeConfig.ChallengeProvider, credentials, parameters, log);
            }
            catch (ChallengeProviders.CredentialsRequiredException)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "This DNS Challenge API requires one or more credentials to be specified."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }
            catch (Exception exp)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = $"DNS Challenge API Provider could not be created. Check all required credentials are set. {exp.ToString()}"
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            if (dnsAPIProvider == null)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "DNS Challenge API Provider not set or not recognised. Select an API to proceed."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            if (isTestMode && !dnsAPIProvider.IsTestModeSupported)
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = true, Message = dnsAPIProvider.ProviderTitle + " does not perform any tests."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }

            string zoneId = null;

            if (parameters != null && parameters.ContainsKey("zoneid"))
            {
                zoneId = parameters["zoneid"]?.Trim();
            }
            else
            {
                zoneId = challengeConfig.ZoneId?.Trim();
            }

            if (dnsAPIProvider != null)
            {
                //most DNS providers require domains to by ASCII
                txtRecordName = _idnMapping.GetAscii(txtRecordName).ToLower();

                log.Information($"DNS: Creating TXT Record '{txtRecordName}' with value '{txtRecordValue}', in Zone Id '{zoneId}' using API provider '{dnsAPIProvider.ProviderTitle}'");
                try
                {
                    var result = await dnsAPIProvider.CreateRecord(new DnsRecord
                    {
                        RecordType       = "TXT",
                        TargetDomainName = domain,
                        RecordName       = txtRecordName,
                        RecordValue      = txtRecordValue,
                        ZoneId           = zoneId
                    });

                    result.Message = $"{dnsAPIProvider.ProviderTitle} :: {result.Message}";

                    bool isAwaitingUser = false;

                    if (challengeConfig.ChallengeProvider.Contains(".Manual") || result.Message.Contains("[Action Required]"))
                    {
                        isAwaitingUser = true;
                    }

                    return(new DnsChallengeHelperResult
                    {
                        Result = result,
                        PropagationSeconds = dnsAPIProvider.PropagationDelaySeconds,
                        IsAwaitingUser = isAwaitingUser
                    });
                }
                catch (Exception exp)
                {
                    return(new DnsChallengeHelperResult
                    {
                        Result = new ActionResult {
                            IsSuccess = false, Message = $"Failed [{dnsAPIProvider.ProviderTitle}]: " + exp.Message
                        },
                        PropagationSeconds = 0,
                        IsAwaitingUser = false
                    });
                }

                //TODO: DNS query to check for new record

                /*
                 * if (result.IsSuccess)
                 * {
                 *  // do our own txt record query before proceeding with challenge completion
                 *
                 *  int attempts = 3;
                 *  bool recordCheckedOK = false;
                 *  var networkUtil = new NetworkUtils(false);
                 *
                 *  while (attempts > 0 && !recordCheckedOK)
                 *  {
                 *      recordCheckedOK = networkUtil.CheckDNSRecordTXT(domain, txtRecordName, txtRecordValue);
                 *      attempts--;
                 *      if (!recordCheckedOK)
                 *      {
                 *          await Task.Delay(1000); // hold on a sec
                 *      }
                 *  }
                 *
                 * // wait for provider specific propogation delay
                 *
                 * // FIXME: perform validation check in DNS nameservers await
                 * // Task.Delay(dnsAPIProvider.PropagationDelaySeconds * 1000);
                 *
                 * return result;
                 * }
                 * else
                 * {
                 * return result;
                 * }
                 */
            }
            else
            {
                return(new DnsChallengeHelperResult
                {
                    Result = new ActionResult {
                        IsSuccess = false, Message = "Error: Could not determine DNS API Provider."
                    },
                    PropagationSeconds = 0,
                    IsAwaitingUser = false
                });
            }
        }
예제 #19
0
 private static LetsencryptService GetDnsRenewalService(RenewalParameters renewalParams, IDnsProvider dnsProvider, AzureWebAppEnvironment webAppEnvironment)
 {
     return(new LetsencryptService(
                new AcmeClient(
                    dnsProvider,
                    new DnsLookupService(new Logger <DnsLookupService>(s_loggerFactory)),
                    new NullCertificateStore(),
                    new Logger <AcmeClient>(s_loggerFactory)),
                new NullCertificateStore(),
                new AzureWebAppService(
                    new[]
     {
         new AzureWebAppSettings(
             webAppEnvironment.WebAppName,
             webAppEnvironment.ResourceGroupName,
             GetAzureServicePrincipal(webAppEnvironment),
             GetAzureSubscription(webAppEnvironment),
             webAppEnvironment.SiteSlotName,
             webAppEnvironment.ServicePlanResourceGroupName,
             renewalParams.UseIpBasedSsl),
     },
                    new Logger <AzureWebAppService>(s_loggerFactory)),
                new Logger <LetsencryptService>(s_loggerFactory)));
 }