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