public HttpChallenge DecodeChallenge() { AuthorizeChallenge challenge = _client.DecodeChallenge(_authorizationState, AcmeProtocol.CHALLENGE_TYPE_HTTP); _authorizationState.Challenges = new[] { challenge }; return((HttpChallenge)challenge.Challenge); }
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; }
/// <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(); } }
/// <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); }
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)); }
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); } }
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); }
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); } }
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); } }); }
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); }); }
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"); }
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); } }); }