Esempio n. 1
0
        /// <summary>
        /// Make sure we have authorization for every host in target
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        private static AuthorizationState Authorize(ILifetimeScope renewalScope, Target target)
        {
            List <string>             identifiers = target.GetHosts(false);
            List <AuthorizationState> authStatus  = new List <AuthorizationState>();
            var client = renewalScope.Resolve <LetsEncryptClient>();

            foreach (var identifier in identifiers)
            {
                var authzState = client.Acme.AuthorizeIdentifier(identifier);
                if (authzState.Status == _authorizationValid && !_options.Test)
                {
                    _log.Information("Cached authorization result: {Status}", authzState.Status);
                    authStatus.Add(authzState);
                }
                else
                {
                    using (var identifierScope = AutofacBuilder.Identifier(renewalScope, target, identifier))
                    {
                        IValidationPluginFactory validationPluginFactory = null;
                        IValidationPlugin        validationPlugin        = null;
                        try
                        {
                            validationPluginFactory = identifierScope.Resolve <IValidationPluginFactory>();
                            validationPlugin        = identifierScope.Resolve <IValidationPlugin>();
                        }
                        catch { }
                        if (validationPluginFactory == null || validationPluginFactory is INull || validationPlugin == null)
                        {
                            return(new AuthorizationState {
                                Status = _authorizationInvalid
                            });
                        }
                        _log.Information("Authorizing {dnsIdentifier} using {challengeType} validation ({name})", identifier, validationPluginFactory.ChallengeType, validationPluginFactory.Name);
                        var challenge = client.Acme.DecodeChallenge(authzState, validationPluginFactory.ChallengeType);
                        validationPlugin.PrepareChallenge(challenge);
                        _log.Debug("Submitting answer");
                        authzState.Challenges = new AuthorizeChallenge[] { challenge };
                        client.Acme.SubmitChallengeAnswer(authzState, validationPluginFactory.ChallengeType, true);

                        // have to loop to wait for server to stop being pending.
                        // TODO: put timeout/retry limit in this loop
                        while (authzState.Status == _authorizationPending)
                        {
                            _log.Debug("Refreshing authorization");
                            Thread.Sleep(4000); // this has to be here to give ACME server a chance to think
                            var newAuthzState = client.Acme.RefreshIdentifierAuthorization(authzState);
                            if (newAuthzState.Status != _authorizationPending)
                            {
                                authzState = newAuthzState;
                            }
                        }

                        if (authzState.Status != _authorizationValid)
                        {
                            _log.Information("Authorization result: {Status}", authzState.Status);
                        }
                        else
                        {
                            _log.Error("Authorization result: {Status}", authzState.Status);
                        }
                        authStatus.Add(authzState);
                    }
                }
            }
            foreach (var authState in authStatus)
            {
                if (authState.Status != _authorizationValid)
                {
                    return(authState);
                }
            }
            return(new AuthorizationState {
                Status = _authorizationValid
            });
        }
Esempio n. 2
0
        /// <summary>
        /// Make sure we have authorization for every host in target
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        private async Task <Challenge> Authorize(
            ILifetimeScope execute, RunLevel runLevel,
            ValidationPluginOptions options, TargetPart targetPart,
            Authorization authorization)
        {
            var invalid = new Challenge {
                Status = AcmeClient.AuthorizationInvalid
            };
            var valid = new Challenge {
                Status = AcmeClient.AuthorizationValid
            };
            var client     = execute.Resolve <AcmeClient>();
            var identifier = authorization.Identifier.Value;

            try
            {
                _log.Information("Authorize identifier: {identifier}", identifier);
                if (authorization.Status == AcmeClient.AuthorizationValid &&
                    !runLevel.HasFlag(RunLevel.Test) &&
                    !runLevel.HasFlag(RunLevel.IgnoreCache))
                {
                    _log.Information("Cached authorization result: {Status}", authorization.Status);
                    return(valid);
                }
                else
                {
                    using var validation = _scopeBuilder.Validation(execute, options, targetPart, identifier);
                    IValidationPlugin validationPlugin = null;
                    try
                    {
                        validationPlugin = validation.Resolve <IValidationPlugin>();
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex, "Error resolving validation plugin");
                    }
                    if (validationPlugin == null)
                    {
                        _log.Error("Validation plugin not found or not created.");
                        return(invalid);
                    }
                    if (validationPlugin.Disabled)
                    {
                        _log.Error("Validation plugin is not available to the current user, try running as administrator.");
                        return(invalid);
                    }
                    var challenge = authorization.Challenges.FirstOrDefault(c => c.Type == options.ChallengeType);
                    if (challenge == null)
                    {
                        _log.Error("Expected challenge type {type} not available for {identifier}.",
                                   options.ChallengeType,
                                   authorization.Identifier.Value);
                        return(invalid);
                    }

                    if (challenge.Status == AcmeClient.AuthorizationValid &&
                        !runLevel.HasFlag(RunLevel.Test) &&
                        !runLevel.HasFlag(RunLevel.IgnoreCache))
                    {
                        _log.Information("{dnsIdentifier} already validated by {challengeType} validation ({name})",
                                         authorization.Identifier.Value,
                                         options.ChallengeType,
                                         options.Name);
                        return(valid);
                    }

                    _log.Information("Authorizing {dnsIdentifier} using {challengeType} validation ({name})",
                                     identifier,
                                     options.ChallengeType,
                                     options.Name);
                    try
                    {
                        var details = client.DecodeChallengeValidation(authorization, challenge);
                        await validationPlugin.PrepareChallenge(details);
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex, "Error preparing for challenge answer");
                        return(invalid);
                    }

                    _log.Debug("Submitting challenge answer");
                    challenge = await client.AnswerChallenge(challenge);

                    if (challenge.Status != AcmeClient.AuthorizationValid)
                    {
                        if (challenge.Error != null)
                        {
                            _log.Error(challenge.Error.ToString());
                        }
                        _log.Error("Authorization result: {Status}", challenge.Status);
                        return(invalid);
                    }
                    else
                    {
                        _log.Information("Authorization result: {Status}", challenge.Status);
                        return(valid);
                    }
                }
            }
            catch (Exception ex)
            {
                _log.Error("Error authorizing {renewal}", targetPart);
                _exceptionHandler.HandleException(ex);
                return(invalid);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Make sure we have authorization for every host in target
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        private Challenge Authorize(ILifetimeScope execute, RunLevel runLevel, OrderDetails order, ValidationPluginOptions options, TargetPart targetPart, Authorization authorization)
        {
            var invalid = new Challenge {
                Status = _authorizationInvalid
            };
            var valid = new Challenge {
                Status = _authorizationValid
            };
            var client     = execute.Resolve <AcmeClient>();
            var identifier = authorization.Identifier.Value;

            try
            {
                _log.Information("Authorize identifier: {identifier}", identifier);
                if (authorization.Status == _authorizationValid && !runLevel.HasFlag(RunLevel.Test))
                {
                    _log.Information("Cached authorization result: {Status}", authorization.Status);
                    return(valid);
                }
                else
                {
                    using (var validation = _scopeBuilder.Validation(execute, options, targetPart, identifier))
                    {
                        IValidationPlugin validationPlugin = null;
                        try
                        {
                            validationPlugin = validation.Resolve <IValidationPlugin>();
                        }
                        catch (Exception ex)
                        {
                            _log.Error(ex, "Error resolving validation plugin");
                        }
                        if (validationPlugin == null)
                        {
                            _log.Error("Validation plugin not found or not created.");
                            return(invalid);
                        }
                        var challenge = authorization.Challenges.FirstOrDefault(c => c.Type == options.ChallengeType);
                        if (challenge == null)
                        {
                            _log.Error("Expected challenge type {type} not available for {identifier}.",
                                       options.ChallengeType,
                                       authorization.Identifier.Value);
                            return(invalid);
                        }

                        if (challenge.Status == _authorizationValid && !runLevel.HasFlag(RunLevel.Test))
                        {
                            _log.Information("{dnsIdentifier} already validated by {challengeType} validation ({name})",
                                             authorization.Identifier.Value,
                                             options.ChallengeType,
                                             options.Name);
                            return(valid);
                        }

                        _log.Information("Authorizing {dnsIdentifier} using {challengeType} validation ({name})",
                                         identifier,
                                         options.ChallengeType,
                                         options.Name);
                        try
                        {
                            var details = client.DecodeChallengeValidation(authorization, challenge);
                            validationPlugin.PrepareChallenge(details);
                        }
                        catch (Exception ex)
                        {
                            _log.Error(ex, "Error preparing for challenge answer");
                            return(invalid);
                        }

                        _log.Debug("Submitting challenge answer");
                        challenge = client.AnswerChallenge(challenge);

                        // Have to loop to wait for server to stop being pending
                        var tries    = 0;
                        var maxTries = 4;
                        while (challenge.Status == _authorizationPending)
                        {
                            _log.Debug("Refreshing authorization");
                            Thread.Sleep(2000); // this has to be here to give ACME server a chance to think
                            challenge = client.GetChallengeDetails(challenge.Url);
                            tries    += 1;
                            if (tries > maxTries)
                            {
                                _log.Error("Authorization timed out");
                                return(invalid);
                            }
                        }

                        if (challenge.Status != _authorizationValid)
                        {
                            _log.Error("Authorization result: {Status}", challenge.Status);
                            return(invalid);
                        }
                        else
                        {
                            _log.Information("Authorization result: {Status}", challenge.Status);
                            return(valid);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _log.Error("Error authorizing {renewal}", targetPart);
                HandleException(ex);
                return(invalid);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Make sure we have authorization for every host in target
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        private static AuthorizationState Authorize(ILifetimeScope renewalScope, Target target)
        {
            var invalid = new AuthorizationState {
                Status = _authorizationInvalid
            };

            try
            {
                var identifiers = target.GetHosts(false);
                var authStatus  = new List <AuthorizationState>();
                var client      = renewalScope.Resolve <AcmeClientWrapper>();
                foreach (var identifier in identifiers)
                {
                    _log.Information("Authorize identifier: {identifier}", identifier);
                    var authzState = client.Acme.AuthorizeIdentifier(identifier);
                    if (authzState.Status == _authorizationValid && !_options.Test)
                    {
                        _log.Information("Cached authorization result: {Status}", authzState.Status);
                        authStatus.Add(authzState);
                    }
                    else
                    {
                        using (var identifierScope = AutofacBuilder.Identifier(renewalScope, target, identifier))
                        {
                            IValidationPluginFactory validationPluginFactory = null;
                            IValidationPlugin        validationPlugin        = null;
                            try
                            {
                                validationPluginFactory = identifierScope.Resolve <IValidationPluginFactory>();
                                validationPlugin        = identifierScope.Resolve <IValidationPlugin>();
                            }
                            catch (Exception ex)
                            {
                                _log.Error(ex, "Error resolving validation plugin");
                            }
                            if (validationPluginFactory == null || validationPluginFactory is INull || validationPlugin == null)
                            {
                                _log.Error("Validation plugin not found or not created.");
                                return(invalid);
                            }
                            if (!authzState.Challenges.Any(c => c.Type == validationPluginFactory.ChallengeType))
                            {
                                _log.Error("Expected challenge type {type} not available for {identifier}.", validationPluginFactory.ChallengeType, identifier);
                                return(invalid);
                            }
                            _log.Information("Authorizing {dnsIdentifier} using {challengeType} validation ({name})", identifier, validationPluginFactory.ChallengeType, validationPluginFactory.Name);
                            var challenge = client.Acme.DecodeChallenge(authzState, validationPluginFactory.ChallengeType);
                            try
                            {
                                validationPlugin.PrepareChallenge(challenge);
                            }
                            catch (Exception ex)
                            {
                                _log.Error(ex, "Error preparing for challenge answer");
                                return(invalid);
                            }
                            _log.Debug("Submitting answer");
                            authzState.Challenges = new AuthorizeChallenge[] { challenge };
                            client.Acme.SubmitChallengeAnswer(authzState, validationPluginFactory.ChallengeType, true);

                            // have to loop to wait for server to stop being pending.
                            // TODO: put timeout/retry limit in this loop
                            while (authzState.Status == _authorizationPending)
                            {
                                _log.Debug("Refreshing authorization");
                                Thread.Sleep(4000); // this has to be here to give ACME server a chance to think
                                var newAuthzState = client.Acme.RefreshIdentifierAuthorization(authzState);
                                if (newAuthzState.Status != _authorizationPending)
                                {
                                    authzState = newAuthzState;
                                }
                            }

                            if (authzState.Status != _authorizationValid)
                            {
                                _log.Error("Authorization result: {Status}", authzState.Status);
                            }
                            else
                            {
                                _log.Information("Authorization result: {Status}", authzState.Status);
                            }
                            authStatus.Add(authzState);
                        }
                    }
                }
                foreach (var authState in authStatus)
                {
                    if (authState.Status != _authorizationValid)
                    {
                        return(authState);
                    }
                }
                return(new AuthorizationState {
                    Status = _authorizationValid
                });
            }
            catch (Exception ex)
            {
                _log.Error("Error authorizing {target}", target);
                HandleException(ex);
                return(invalid);
            }
        }