public HttpChallenge DecodeChallenge()
        {
            AuthorizeChallenge challenge = _client.DecodeChallenge(_authorizationState, AcmeProtocol.CHALLENGE_TYPE_HTTP);

            _authorizationState.Challenges = new[] { challenge };
            return((HttpChallenge)challenge.Challenge);
        }
Beispiel #2
0
 public AuthorizeChallengeItem GetAuthorizeChallengeItemFromAuthChallenge(AuthorizeChallenge challenge)
 {
     return(new AuthorizeChallengeItem
     {
         Status = challenge.Status,
         ChallengeData = challenge.Challenge
     });
 }
        public Action <AuthorizationState> PrepareChallenge(Target target, AuthorizeChallenge challenge, string identifier, Options options, InputService input)
        {
            var dnsChallenge = challenge.Challenge as DnsChallenge;
            var record       = dnsChallenge.RecordName;

            CreateRecord(target, identifier, record, dnsChallenge.RecordValue);
            _log.Information("Answer should now be available at {answerUri}", record);
            return(authzState => DeleteRecord(target, identifier, record));
        }
        /// <inheritdoc cref="IAcmeSharpProvider"/>
        public void GenerateHttpChallenge(out string challengeUrl, out string challengeContent, out string challengeFilePath)
        {
            this.authState = this.AcmeClient.AuthorizeIdentifier(this.Domain);
            this.Challenge = this.AcmeClient.DecodeChallenge(this.authState, AcmeProtocol.CHALLENGE_TYPE_HTTP);
            var httpChallenge = (HttpChallenge)this.Challenge.Challenge;

            challengeUrl      = httpChallenge.FileUrl;
            challengeContent  = httpChallenge.FileContent;
            challengeFilePath = httpChallenge.FilePath;
        }
Beispiel #5
0
 /// <summary>
 /// Handle the challenge
 /// </summary>
 /// <param name="challenge"></param>
 public void PrepareChallenge(AuthorizeChallenge challenge)
 {
     if (challenge.Challenge.GetType() != typeof(T))
     {
         throw new InvalidOperationException();
     }
     else
     {
         _challenge = (T)challenge.Challenge;
         PrepareChallenge();
     }
 }
Beispiel #6
0
        /// <summary>
        /// Updates a challenge record.
        /// </summary>
        /// <param name="uri">Uri of the challenge.</param>
        /// <param name="token">Token of the challenge.</param>
        /// <param name="cancellationToken">Cancellation token for the async request.</param>
        /// <returns></returns>
        public async Task <AuthorizationChallengeResponse> UpdateChallengeAsync(Uri uri, string token, CancellationToken cancellationToken = default)
        {
            var message = new AuthorizeChallenge
            {
                KeyAuthorization = jws.GetKeyAuthorization(token)
            };

            var(result, response) = await client.PostAsync <AuthorizationChallengeResponse>(uri, message, cancellationToken);

            if (result is AuthorizationChallengeResponse acmeOrder)
            {
                return(acmeOrder);
            }

            throw new InvalidServerResponse("Invalid response from server during UpdateChallenge.", response, Directory.NewAccount);
        }
Beispiel #7
0
        static void ApplyToChallenge(AcmeClient client,
                                     AuthorizeChallenge httpChallenge, AuthorizationState state)
        {
            state.Challenges = new AuthorizeChallenge[] { httpChallenge };
            client.SubmitChallengeAnswer(state, AcmeProtocol.CHALLENGE_TYPE_HTTP, true);

            while (state.Status == "pending")
            {
                Log.Debug("Aguardando a identificação do desafio...");
                Thread.Sleep(5000);
                var newState = client.RefreshIdentifierAuthorization(state);
                if (newState.Status != "pending")
                {
                    state = newState;
                }
            }
        }
        public Action <AuthorizationState> PrepareChallenge(Target target, AuthorizeChallenge challenge, string identifier, Options options, InputService input)
        {
            TlsSniChallenge       tlsChallenge = challenge.Challenge as TlsSniChallenge;
            TlsSniChallengeAnswer answer       = tlsChallenge.Answer as TlsSniChallengeAnswer;
            IEnumerable <ValidationCertificate> validationCertificates = GenerateCertificates(answer.KeyAuthorization, tlsChallenge.IterationCount);

            foreach (var validationCertificate in validationCertificates)
            {
                InstallCertificate(target, validationCertificate.Certificate, validationCertificate.HostName);
            }
            return((AuthorizationState authzState) => {
                foreach (var cert in validationCertificates)
                {
                    RemoveCertificate(target, cert.Certificate, cert.HostName);
                }
            });
        }
        public Action <AuthorizationState> PrepareChallenge(Target target, AuthorizeChallenge challenge, string identifier, Options options, InputService input)
        {
            var httpChallenge = challenge.Challenge as HttpChallenge;

            CreateAuthorizationFile(target, httpChallenge);
            BeforeAuthorize(target, httpChallenge);

            _log.Information("Answer should now be browsable at {answerUri}", httpChallenge.FileUrl);
            if (options.Test && !options.Renew)
            {
                if (input.PromptYesNo("Try in default browser?"))
                {
                    Process.Start(httpChallenge.FileUrl);
                    input.Wait();
                }
            }
            if (options.Warmup)
            {
                _log.Information("Waiting for site to warmup...");
                WarmupSite(new Uri(httpChallenge.FileUrl));
            }

            return(authzState => Cleanup(target, httpChallenge));
        }
Beispiel #10
0
        protected override void ProcessRecord()
        {
            using (var vlt = Util.VaultHelper.GetVault(VaultProfile))
            {
                vlt.OpenStorage();
                var v = vlt.LoadVault();

                if (v.Registrations == null || v.Registrations.Count < 1)
                {
                    throw new InvalidOperationException("No registrations found");
                }

                var ri = v.Registrations[0];
                var r  = ri.Registration;

                if (v.Identifiers == null || v.Identifiers.Count < 1)
                {
                    throw new InvalidOperationException("No identifiers found");
                }

                var ii = v.Identifiers.GetByRef(IdentifierRef, throwOnMissing: false);
                if (ii == null)
                {
                    throw new Exception("Unable to find an Identifier for the given reference");
                }

                var authzState = ii.Authorization;

                if (ii.Challenges == null)
                {
                    ii.Challenges = new Dictionary <string, AuthorizeChallenge>();
                }

                if (ii.ChallengeCompleted == null)
                {
                    ii.ChallengeCompleted = new Dictionary <string, DateTime?>();
                }

                if (ii.ChallengeCleanedUp == null)
                {
                    ii.ChallengeCleanedUp = new Dictionary <string, DateTime?>();
                }

                // Resolve details from inline or profile attributes
                string challengeType = null;
                string handlerName   = null;
                IReadOnlyDictionary <string, object> handlerParams    = null;
                IReadOnlyDictionary <string, object> cliHandlerParams = null;

                if (HandlerParameters?.Count > 0)
                {
                    cliHandlerParams = (IReadOnlyDictionary <string, object>
                                        )PoshHelper.Convert <string, object>(HandlerParameters);
                }

                if (!Force && !CleanUp)
                {
                    if (!authzState.IsPending())
                    {
                        throw new InvalidOperationException(
                                  "authorization is not in pending state;"
                                  + " use Force flag to override this validation");
                    }

                    if (authzState.Challenges.Any(_ => _.IsInvalid()))
                    {
                        throw new InvalidOperationException(
                                  "authorization already contains challenges in an invalid state;"
                                  + " use Force flag to override this validation");
                    }
                }

                if (!string.IsNullOrEmpty(HandlerProfileRef))
                {
                    var ppi = v.ProviderProfiles.GetByRef(HandlerProfileRef, throwOnMissing: false);
                    if (ppi == null)
                    {
                        throw new ItemNotFoundException("no Handler profile found for the given reference")
                              .With(nameof(HandlerProfileRef), HandlerProfileRef);
                    }

                    var ppAsset = vlt.GetAsset(Vault.VaultAssetType.ProviderConfigInfo,
                                               ppi.Id.ToString());
                    ProviderProfile pp;
                    using (var s = vlt.LoadAsset(ppAsset))
                    {
                        pp = JsonHelper.Load <ProviderProfile>(s);
                    }
                    if (pp.ProviderType != ProviderType.CHALLENGE_HANDLER)
                    {
                        throw new InvalidOperationException("referenced profile does not resolve to a Challenge Handler")
                              .With(nameof(HandlerProfileRef), HandlerProfileRef)
                              .With("actualProfileProviderType", pp.ProviderType.ToString());
                    }

                    if (!pp.ProfileParameters.ContainsKey(nameof(ChallengeType)))
                    {
                        throw new InvalidOperationException("handler profile is incomplete; missing Challenge Type")
                              .With(nameof(HandlerProfileRef), HandlerProfileRef);
                    }

                    challengeType = (string)pp.ProfileParameters[nameof(ChallengeType)];
                    handlerName   = pp.ProviderName;
                    handlerParams = pp.InstanceParameters;
                    if (cliHandlerParams != null)
                    {
                        WriteVerbose("Override Handler parameters specified");
                        if (handlerParams == null || handlerParams.Count == 0)
                        {
                            WriteVerbose("Profile does not define any parameters, using override parameters only");
                            handlerParams = cliHandlerParams;
                        }
                        else
                        {
                            WriteVerbose("Merging Handler override parameters with profile");
                            var mergedParams = new Dictionary <string, object>();

                            foreach (var kv in pp.InstanceParameters)
                            {
                                mergedParams[kv.Key] = kv.Value;
                            }
                            foreach (var kv in cliHandlerParams)
                            {
                                mergedParams[kv.Key] = kv.Value;
                            }

                            handlerParams = mergedParams;
                        }
                    }
                }
                else
                {
                    challengeType = ChallengeType;
                    handlerName   = Handler;
                    handlerParams = cliHandlerParams;
                }

                AuthorizeChallenge challenge          = null;
                DateTime?          challengeCompleted = null;
                DateTime?          challengeCleanedUp = null;
                ii.Challenges.TryGetValue(challengeType, out challenge);
                ii.ChallengeCompleted.TryGetValue(challengeType, out challengeCompleted);
                ii.ChallengeCleanedUp.TryGetValue(challengeType, out challengeCleanedUp);

                try
                {
                    if (challenge == null || RepeatDecoder)
                    {
                        using (var c = ClientHelper.GetClient(v, ri))
                        {
                            c.Init();
                            c.GetDirectory(true);

                            challenge = c.DecodeChallenge(authzState, challengeType);
                            ii.Challenges[challengeType] = challenge;
                        }
                    }

                    if (CleanUp && (RepeatHandler || challengeCleanedUp == null))
                    {
                        using (var c = ClientHelper.GetClient(v, ri))
                        {
                            c.Init();
                            c.GetDirectory(true);

                            challenge = c.HandleChallenge(authzState, challengeType,
                                                          handlerName, handlerParams, CleanUp);
                            ii.ChallengeCleanedUp[challengeType] = DateTime.Now;
                        }
                    }
                    else if (RepeatHandler || challengeCompleted == null)
                    {
                        using (var c = ClientHelper.GetClient(v, ri))
                        {
                            c.Init();
                            c.GetDirectory(true);

                            challenge = c.HandleChallenge(authzState, challengeType,
                                                          handlerName, handlerParams);
                            ii.ChallengeCompleted[challengeType] = DateTime.Now;
                        }
                    }
                }
                catch (AcmeClient.AcmeWebException ex)
                {
                    ThrowTerminatingError(PoshHelper.CreateErrorRecord(ex, ii));
                    return;
                }

                vlt.SaveVault(v);

                WriteObject(authzState);
            }
        }
Beispiel #11
0
        public AuthorizationState RequestChallengeVerification(AuthorizationState authorizationState, AuthorizeChallenge challenge)
        {
            try
            {
                _logger.Information("Submitting answer to authorization server, asking for verification using {challengeType}",
                                    AcmeProtocol.CHALLENGE_TYPE_HTTP);

                authorizationState.Challenges = new[] { challenge };
                _acmeClient.SubmitChallengeAnswer(authorizationState, AcmeProtocol.CHALLENGE_TYPE_HTTP, true);

                var       retries   = 0;
                const int retryTime = 3000;
                while (authorizationState.Status == AuthorizationState.STATUS_PENDING)
                {
                    retries += 1;
                    if (retries > 5)
                    {
                        break;
                    }

                    _logger.Information("Authorization in progress, attempt {retries}", retries);

                    if (retries > 1)
                    {
                        // Give it some time before doing a retry
                        Thread.Sleep(retryTime);
                    }

                    var refreshedAuthorization = _acmeClient.RefreshIdentifierAuthorization(authorizationState);

                    if (refreshedAuthorization.Status != authorizationState.Status)
                    {
                        _logger.Information("Authorization has updated status from {previousStatus} to {newStatus}",
                                            authorizationState.Status, refreshedAuthorization.Status);
                    }

                    // Update the status of the object we'll return eventually
                    authorizationState.Status = refreshedAuthorization.Status;

                    if (refreshedAuthorization.Status != AuthorizationState.STATUS_VALID)
                    {
                        // We're not at valid yet, retry
                        continue;
                    }

                    // If we've successfully validated then return this new status
                    if (refreshedAuthorization.Status == AuthorizationState.STATUS_VALID)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                if (authorizationState.Status == AuthorizationState.STATUS_INVALID)
                {
                    _logger.Error("Authorization failed with status {status}", authorizationState.Status);
                }

                _logger.Error("Exception: {@ex}", ex);
            }

            return(authorizationState);
        }
Beispiel #12
0
        protected override void ProcessRecord()
        {
            using (var vp = InitializeVault.GetVaultProvider(VaultProfile))
            {
                vp.OpenStorage();
                var v = vp.LoadVault();

                if (v.Registrations == null || v.Registrations.Count < 1)
                {
                    throw new InvalidOperationException("No registrations found");
                }

                var ri = v.Registrations[0];
                var r  = ri.Registration;

                if (v.Identifiers == null || v.Identifiers.Count < 1)
                {
                    throw new InvalidOperationException("No identifiers found");
                }

                var ii = v.Identifiers.GetByRef(Ref);
                if (ii == null)
                {
                    throw new Exception("Unable to find an Identifier for the given reference");
                }

                var authzState = ii.Authorization;

                if (ii.Challenges == null)
                {
                    ii.Challenges = new Dictionary <string, AuthorizeChallenge>();
                }

                if (ii.ChallengeCompleted == null)
                {
                    ii.ChallengeCompleted = new Dictionary <string, DateTime?>();
                }

                if (v.ProviderConfigs == null || v.ProviderConfigs.Count < 1)
                {
                    throw new InvalidOperationException("No provider configs found");
                }

                var pc = v.ProviderConfigs.GetByRef(ProviderConfig);
                if (pc == null)
                {
                    throw new InvalidOperationException("Unable to find a Provider Config for the given reference");
                }

                AuthorizeChallenge challenge         = null;
                DateTime?          challengCompleted = null;
                ii.Challenges.TryGetValue(Challenge, out challenge);
                ii.ChallengeCompleted.TryGetValue(Challenge, out challengCompleted);

                if (challenge == null || Regenerate)
                {
                    using (var c = ClientHelper.GetClient(v, ri))
                    {
                        c.Init();
                        c.GetDirectory(true);

                        challenge = c.GenerateAuthorizeChallengeAnswer(authzState, Challenge);
                        ii.Challenges[Challenge] = challenge;
                    }
                }

                if (Repeat || challengCompleted == null)
                {
                    var pcFilePath = $"{pc.Id}.json";
                    var pcAsset    = vp.GetAsset(Vault.VaultAssetType.ProviderConfigInfo, pcFilePath);

                    // TODO:  There's *way* too much logic buried in here
                    // this needs to be refactored and extracted out to be
                    // more manageble and more reusable

                    if (Challenge == AcmeProtocol.CHALLENGE_TYPE_DNS)
                    {
                        if (string.IsNullOrEmpty(pc.DnsProvider))
                        {
                            throw new InvalidOperationException("Referenced Provider Configuration does not support the selected Challenge");
                        }

                        var dnsName   = challenge.ChallengeAnswer.Key;
                        var dnsValue  = Regex.Replace(challenge.ChallengeAnswer.Value, "\\s", "");
                        var dnsValues = Regex.Replace(dnsValue, "(.{100,100})", "$1\n").Split('\n');

                        using (var s = vp.LoadAsset(pcAsset)) // new FileStream(pcFilePath, FileMode.Open))
                        {
                            var dnsInfo = DnsInfo.Load(s);
                            dnsInfo.Provider.EditTxtRecord(dnsName, dnsValues);
                            ii.ChallengeCompleted[Challenge] = DateTime.Now;
                        }
                    }
                    else if (Challenge == AcmeProtocol.CHALLENGE_TYPE_HTTP)
                    {
                        if (string.IsNullOrEmpty(pc.WebServerProvider))
                        {
                            throw new InvalidOperationException("Referenced Provider Configuration does not support the selected Challenge");
                        }

                        var wsFilePath = challenge.ChallengeAnswer.Key;
                        var wsFileBody = challenge.ChallengeAnswer.Value;
                        var wsFileUrl  = new Uri($"http://{authzState.Identifier}/{wsFilePath}");



                        using (var s = vp.LoadAsset(pcAsset)) // new FileStream(pcFilePath, FileMode.Open))
                        {
                            var webServerInfo = WebServerInfo.Load(s);
                            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(wsFileBody)))
                            {
                                webServerInfo.Provider.UploadFile(wsFileUrl, ms);
                                ii.ChallengeCompleted[Challenge] = DateTime.Now;
                            }
                        }
                    }
                }

                vp.SaveVault(v);

                WriteObject(authzState);
            }
        }
Beispiel #13
0
        private static Action <AuthorizationState> PrepareHttpChallenge(Target target, AuthorizeChallenge challenge, out string answerUri)
        {
            var webRootPath   = target.WebRootPath;
            var httpChallenge = challenge.Challenge as HttpChallenge;

            // We need to strip off any leading '/' in the path
            var filePath = httpChallenge.FilePath;

            if (filePath.StartsWith("/", StringComparison.OrdinalIgnoreCase))
            {
                filePath = filePath.Substring(1);
            }
            var answerPath = Environment.ExpandEnvironmentVariables(Path.Combine(webRootPath, filePath));

            target.Plugin.CreateAuthorizationFile(answerPath, httpChallenge.FileContent);
            target.Plugin.BeforeAuthorize(target, answerPath, httpChallenge.Token);

            answerUri = httpChallenge.FileUrl;

            if (Options.Warmup)
            {
                Console.WriteLine($"Waiting for site to warmup...");
                WarmupSite(new Uri(answerUri));
            }

            Log.Information("Answer should now be browsable at {answerUri}", answerUri);

            return(authzState =>
            {
                if (authzState.Status == "valid")
                {
                    target.Plugin.DeleteAuthorization(answerPath, httpChallenge.Token, webRootPath, filePath);
                }
            });
        }
Beispiel #14
0
        private static Action <AuthorizationState> PrepareDnsChallenge(Target target, AuthorizeChallenge challenge, out string answerUri)
        {
            var dnsChallenge = challenge.Challenge as DnsChallenge;

            target.Plugin.CreateAuthorizationFile(dnsChallenge.RecordName, dnsChallenge.RecordValue);
            target.Plugin.BeforeAuthorize(target, dnsChallenge.RecordName, dnsChallenge.Token);
            answerUri = dnsChallenge.RecordName;

            Log.Information("Answer should now be available at {answerUri}", answerUri);

            return(authzState =>
            {
                target.Plugin.DeleteAuthorization(dnsChallenge.RecordName, dnsChallenge.Token, null, null);
            });
        }
Beispiel #15
0
        private void ChallengeGetCertAndInstall(List <SiteBinding> sites)
        {
            AuthorizationState authorizationState = null;
            AuthorizeChallenge authorizeChallenge = null;
            HttpChallenge      httpChallenge      = null;

            Log("\tChallengeGetCertAndInstall started");
            Log("\tChallengeGetCertAndInstall total sites: {0}", sites.Count);
            foreach (var site in sites)
            {
                Log("\t\tChallengeGetCertAndInstall * procesing {0}", site.BindingHost);

                try
                {
                    authorizationState = this.client.AuthorizeIdentifier(site.BindingHost);
                    Log("\t\tChallengeGetCertAndInstall authorizationState ok");
                }
                catch (Exception exception)
                {
                    Log("\t\tChallengeGetCertAndInstall Error AuthorizeIdentifier {0}", exception.Message);
                    continue;
                }

                try
                {
                    authorizeChallenge = this.client.DecodeChallenge(authorizationState, AcmeProtocol.CHALLENGE_TYPE_HTTP);
                }
                catch (Exception exception)
                {
                    Log("\t\tChallengeGetCertAndInstall Error DecodeChallenge {0}", exception.Message);
                    continue;
                }

                if (authorizeChallenge == null)
                {
                    Log("\t\tChallengeGetCertAndInstall authorizeChallenge == null");
                    continue;
                }

                httpChallenge = authorizeChallenge.Challenge as HttpChallenge;
                if (httpChallenge == null)
                {
                    Log("\t\tChallengeGetCertAndInstall httpChallenge == null");
                    continue;
                }

                var challengePath = Path.Combine(site.Path, httpChallenge.FilePath.Replace('/', '\\'));

                if (!CreateChallenge(challengePath, httpChallenge.FileContent))
                {
                    continue;
                }
                if (!CreateWebConfig(challengePath))
                {
                    continue;
                }

                // warmup?
                try
                {
                    using (var wc = new WebClient())
                    {
                        var response = wc.DownloadString(httpChallenge.FileUrl);
                        if (httpChallenge.FileContent != response)
                        {
                            Log("\t\tChallengeGetCertAndInstall error FileContent != response for {0}", site.BindingHost);
                            continue;
                        }
                    }
                }
                catch (Exception exception)
                {
                    Log("\t\tChallengeGetCertAndInstall DownloadString {0} Error {1}", httpChallenge.FileUrl, exception.Message);
                    continue;
                }
                Log("\t\tChallengeGetCertAndInstall Challenge placed for {0}", site.BindingHost);

                authorizationState.Challenges = new AuthorizeChallenge[] { authorizeChallenge };
                this.client.SubmitChallengeAnswer(authorizationState, AcmeProtocol.CHALLENGE_TYPE_HTTP, true);

                for (int intI = 0; intI < 60; intI++)
                {
                    System.Threading.Thread.Sleep(1000);
                    var newAuthorizationState = this.client.RefreshIdentifierAuthorization(authorizationState);
                    if (newAuthorizationState.Status != "pending")
                    {
                        authorizationState = newAuthorizationState;
                        break;
                    }
                }

                if (DeleteWebConfig(challengePath))
                {
                    Log("\t\tChallengeGetCertAndInstall WebConfig deleted for {0}", site.BindingHost);
                }

                if (DeleteChallenge(challengePath))
                {
                    Log("\t\tChallengeGetCertAndInstall Challenge deleted for {0}", site.BindingHost);
                }

                switch (authorizationState.Status)
                {
                default:
                    Log("\t\tChallengeGetCertAndInstall unknown status {0}", authorizationState.Status);
                    break;

                case "pending":
                    Log("\t\tChallengeGetCertAndInstall error pending");
                    break;

                case "invalid":
                    Log("\t\tChallengeGetCertAndInstall error invalid");
                    break;

                case "valid":
                    Log("\t\tChallengeGetCertAndInstall valid for {0}", site.BindingHost);
                    if (InstallCertificate(site.BindingHost))
                    {
                        Log("\t\tChallengeGetCertAndInstall ready {0}", site.BindingHost);
                    }
                    break;
                }
            }
            Log("\tChallengeGetCertAndInstall ended");
        }
Beispiel #16
0
        private static Action <AuthorizationState> PrepareHttpChallenge(Target target, AuthorizeChallenge challenge, out string answerUri)
        {
            var webRootPath   = Environment.ExpandEnvironmentVariables(target.WebRootPath);
            var httpChallenge = challenge.Challenge as HttpChallenge;
            var filePath      = httpChallenge.FilePath.Replace('/', '\\');
            var answerPath    = $"{webRootPath.TrimEnd('\\')}\\{filePath.TrimStart('\\')}";

            target.Plugin.CreateAuthorizationFile(answerPath, httpChallenge.FileContent);
            target.Plugin.BeforeAuthorize(target, answerPath, httpChallenge.Token);

            answerUri = httpChallenge.FileUrl;

            Log.Information("Answer should now be browsable at {answerUri}", answerUri);
            if (Options.Test && !Options.Renew)
            {
                if (Input.PromptYesNo("Try in default browser?"))
                {
                    Process.Start(answerUri);
                    Input.Wait();
                }
            }
            if (Options.Warmup)
            {
                Log.Information("Waiting for site to warmup...");
                WarmupSite(new Uri(answerUri));
            }

            return(authzState =>
            {
                if (authzState.Status == "valid")
                {
                    target.Plugin.DeleteAuthorization(answerPath, httpChallenge.Token, webRootPath, filePath);
                }
            });
        }