Esempio n. 1
0
        private static void Main(string[] args)
        {
            // Setup DI
            _container = AutofacBuilder.Global(args, _clientName, new PluginService(_log));

            // Basic services
            _log            = _container.Resolve <ILogService>();
            _optionsService = _container.Resolve <IOptionsService>();
            _options        = _optionsService.Options;
            if (_options == null)
            {
                return;
            }
            _input = _container.Resolve <IInputService>();

            // .NET Framework check
            var dn = _container.Resolve <DotNetVersionService>();

            if (!dn.Check())
            {
                return;
            }

            // Show version information
            _input.ShowBanner();

            // Advanced services
            _renewalService = _container.Resolve <IRenewalService>();
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

            // Main loop
            do
            {
                try
                {
                    if (_options.Renew)
                    {
                        CheckRenewals(_options.ForceRenewal);
                        CloseDefault();
                    }
                    else if (!string.IsNullOrEmpty(_options.Plugin))
                    {
                        if (_options.Cancel)
                        {
                            CancelRenewal();
                        }
                        else
                        {
                            CreateNewCertificate(RunLevel.Unattended);
                        }
                        CloseDefault();
                    }
                    else
                    {
                        MainMenu();
                    }
                }
                catch (Exception e)
                {
                    HandleException(e);
                    Environment.ExitCode = e.HResult;
                }
                if (!_options.CloseOnFinish)
                {
                    _options.Plugin       = null;
                    _options.Renew        = false;
                    _options.ForceRenewal = false;
                    Environment.ExitCode  = 0;
                }
            } while (!_options.CloseOnFinish);
        }
Esempio n. 2
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
            {
                List <string>             identifiers = target.GetHosts(false);
                List <AuthorizationState> 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);
            }
        }
Esempio n. 3
0
        private static void CreateNewCertificate(RunLevel runLevel)
        {
            _log.Information(true, "Running in {runLevel} mode", runLevel);
            var tempRenewal = CreateRenewal(_options);

            using (var scope = AutofacBuilder.Renewal(_container, tempRenewal, runLevel))
            {
                // Choose target plugin
                var targetPluginFactory = scope.Resolve <ITargetPluginFactory>();
                if (targetPluginFactory is INull)
                {
                    return; // User cancelled or unable to resolve
                }

                // Aquire target
                var targetPlugin   = scope.Resolve <ITargetPlugin>();
                var target         = runLevel == RunLevel.Unattended ? targetPlugin.Default(_optionsService) : targetPlugin.Aquire(_optionsService, _input, runLevel);
                var originalTarget = tempRenewal.Binding;
                tempRenewal.Binding = target;
                if (target == null)
                {
                    _log.Error("Plugin {name} was unable to generate a target", targetPluginFactory.Name);
                    return;
                }
                tempRenewal.Binding.TargetPluginName     = targetPluginFactory.Name;
                tempRenewal.Binding.SSLPort              = _options.SSLPort;
                tempRenewal.Binding.ValidationPort       = _options.ValidationPort;
                tempRenewal.Binding.ValidationPluginName = originalTarget.ValidationPluginName;
                _log.Information("Plugin {name} generated target {target}", targetPluginFactory.Name, tempRenewal.Binding);

                // Choose validation plugin
                var validationPluginFactory = scope.Resolve <IValidationPluginFactory>();
                if (validationPluginFactory is INull)
                {
                    return; // User cancelled
                }
                else if (!validationPluginFactory.CanValidate(target))
                {
                    // Might happen in unattended mode
                    _log.Error("Validation plugin {name} is unable to validate target", validationPluginFactory.Name);
                    return;
                }

                // Configure validation
                try
                {
                    if (runLevel == RunLevel.Unattended)
                    {
                        validationPluginFactory.Default(target, _optionsService);
                    }
                    else
                    {
                        validationPluginFactory.Aquire(target, _optionsService, _input, runLevel);
                    }
                    tempRenewal.Binding.ValidationPluginName = $"{validationPluginFactory.ChallengeType}.{validationPluginFactory.Name}";
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Invalid validation input");
                    return;
                }

                // Choose and configure installation plugins
                try
                {
                    var installFactories = scope.Resolve <List <IInstallationPluginFactory> >();
                    if (installFactories.Count == 0)
                    {
                        // User cancelled, otherwise we would at least have the Null-installer
                        return;
                    }
                    foreach (var installFactory in installFactories)
                    {
                        if (runLevel == RunLevel.Unattended)
                        {
                            installFactory.Default(tempRenewal, _optionsService);
                        }
                        else
                        {
                            installFactory.Aquire(tempRenewal, _optionsService, _input, runLevel);
                        }
                    }
                    tempRenewal.InstallationPluginNames = installFactories.Select(f => f.Name).ToList();
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Invalid installation input");
                    return;
                }

                var result = Renew(scope, CreateRenewal(tempRenewal));
                if (!result.Success)
                {
                    _log.Error("Create certificate failed");
                }
            }
        }