예제 #1
0
        static int Main(string[] args)
        {
            // Main parameters with their default values
            string taskName = null;

            _winCertesOptions = new WinCertesOptions();

            if (!Utils.IsAdministrator())
            {
                Console.WriteLine("WinCertes.exe must be launched as Administrator"); return(ERROR);
            }
            // Command line options handling and initialization stuff
            if (!HandleOptions(args))
            {
                return(ERROR_INCORRECT_PARAMETER);
            }
            if (_periodic)
            {
                taskName = Utils.DomainsToFriendlyName(_domains);
            }
            InitWinCertesDirectoryPath();
            Utils.ConfigureLogger(_winCertesPath);
            _config = new RegistryConfig(_extra);
            _winCertesOptions.WriteOptionsIntoConfiguration(_config);
            if (_show)
            {
                _winCertesOptions.displayOptions(_config); return(0);
            }

            // Reset is a full reset !
            if (_reset)
            {
                IConfig baseConfig = new RegistryConfig(false);
                baseConfig.DeleteAllParameters();
                Utils.DeleteScheduledTasks();
                return(0);
            }

            // Initialization and renewal/revocation handling
            try
            {
                InitCertesWrapper(_winCertesOptions.ServiceUri, _winCertesOptions.Email);
            }
            catch (Exception e) { _logger.Error(e.Message); return(ERROR); }
            if (_winCertesOptions.Revoke > -1)
            {
                RevokeCert(_domains, _winCertesOptions.Revoke); return(0);
            }
            // default mode: enrollment/renewal. check if there's something to be done
            // note that in any case, we want to be able to set the scheduled task (won't do anything if taskName is null)
            if (!IsThereCertificateAndIsItToBeRenewed(_domains))
            {
                Utils.CreateScheduledTask(taskName, _domains, _extra); return(0);
            }

            // Now the real stuff: we register the order for the domains, and have them validated by the ACME service
            IHTTPChallengeValidator httpChallengeValidator = HTTPChallengeValidatorFactory.GetHTTPChallengeValidator(_winCertesOptions.Standalone, _winCertesOptions.HttpPort, _winCertesOptions.WebRoot);
            IDNSChallengeValidator  dnsChallengeValidator  = DNSChallengeValidatorFactory.GetDNSChallengeValidator(_config);

            if ((httpChallengeValidator == null) && (dnsChallengeValidator == null))
            {
                WriteErrorMessageWithUsage(_options, "Specify either an HTTP or a DNS validation method."); return(ERROR_INCORRECT_PARAMETER);
            }
            if (!(Task.Run(() => _certesWrapper.RegisterNewOrderAndVerify(_domains, httpChallengeValidator, dnsChallengeValidator)).GetAwaiter().GetResult()))
            {
                if (httpChallengeValidator != null)
                {
                    httpChallengeValidator.EndAllChallengeValidations();
                }
                return(ERROR);
            }
            if (httpChallengeValidator != null)
            {
                httpChallengeValidator.EndAllChallengeValidations();
            }

            // We get the certificate from the ACME service
            var pfxName = Task.Run(() => _certesWrapper.RetrieveCertificate(_domains, _winCertesPath, Utils.DomainsToFriendlyName(_domains))).GetAwaiter().GetResult();

            if (pfxName == null)
            {
                return(ERROR);
            }
            AuthenticatedPFX          pfx = new AuthenticatedPFX(_winCertesPath + "\\" + pfxName, _certesWrapper.PfxPassword);
            CertificateStorageManager certificateStorageManager = new CertificateStorageManager(pfx, ((_winCertesOptions.Csp == null) && (!_winCertesOptions.noCsp)));

            // Let's process the PFX into Windows Certificate objet.
            certificateStorageManager.ProcessPFX();
            // and we write its information to the WinCertes configuration
            RegisterCertificateIntoConfiguration(certificateStorageManager.Certificate, _domains);
            // Import the certificate into the Windows store
            if (!_winCertesOptions.noCsp)
            {
                certificateStorageManager.ImportCertificateIntoCSP(_winCertesOptions.Csp);
            }

            // Bind certificate to IIS Site (won't do anything if option is null)
            Utils.BindCertificateForIISSite(certificateStorageManager.Certificate, _winCertesOptions.BindName);
            // Execute PowerShell Script (won't do anything if option is null)
            Utils.ExecutePowerShell(_winCertesOptions.ScriptFile, pfx);
            // Create the AT task that will execute WinCertes periodically (won't do anything if taskName is null)
            Utils.CreateScheduledTask(taskName, _domains, _extra);

            // Let's delete the PFX file
            RemoveFileAndLog(pfx.PfxFullPath);

            return(0);
        }
예제 #2
0
        /// <summary>
        /// Main programme
        /// </summary>
        /// <param name="args">WinCertes command line arguments</param>
        /// <returns>Zero if successul, error code otherwise</returns>
        private static int Main(string[] args)
        {
            // WinCertes Certificate path...
            InitWinCertesDirectoryPath();
            Utils.ConfigureLogger(_logPath);

            if (!Utils.IsAdministrator())
            {
                string message = "WinCertes.exe must be launched as Administrator with elevated permissions";
                _logger.Error(message);
                Thread.Sleep(1000);
                Utils.AdminRelauncher();
            }
            // Merge command line parameters with registry defaults
            // TODO: Revamp this completely to use simple command line (like aloopkin\WinCertes) or configuration file
            int result = HandleOptions(args);

            if (result != 0)
            {
                return(MainExit(result));
            }

            // Display settings, don't create or renew the certificate
            if (_show)
            {
                _winCertesOptions.DisplayOptions();
                return(MainExit(SUCCESS));
            }

            // Helper to create the DNS keys
            if (_creatednskeys)
            {
                _winCertesOptions.WriteDnsOptions();
                return(MainExit(SUCCESS));
            }

            // Reset is a full reset!
            if (_reset)
            {
                Console.WriteLine("\nWARNING: You should revoke the certificate before deleting it from the registry\nDelete [{0}]?\nPress Enter when ready...", _winCertesOptions.Registry.FullRegistryKey);
                Console.ReadLine();
                _winCertesOptions.Registry.DeleteAllParameters();
                Utils.DeleteScheduledTasks();
                return(MainExit(SUCCESS));
            }


            _logger.Info("Initialisation successful, processing your request...");
            string taskName = null;

            if (_periodic)
            {
                taskName = Utils.DomainsToFriendlyName(_winCertesOptions.Domains);
            }

            // Initialization and renewal/revocation handling
            try
            {
                InitCertesWrapper(_winCertesOptions);
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return(MainExit(ERROR));
            }
            if (_winCertesOptions.Revoke > -1)
            {
                RevokeCert(_winCertesOptions.Domains, _winCertesOptions.Revoke);
                return(MainExit(SUCCESS));
            }
            // default mode: enrollment/renewal. check if there's something to be done
            // note that in any case, we want to be able to set the scheduled task (won't do anything if taskName is null)
            if (!IsThereCertificateAndIsItToBeRenewed(_winCertesOptions.Domains))
            {
                Utils.CreateScheduledTask(taskName, _winCertesOptions.Domains, _extra);
                return(MainExit(SUCCESS));
            }

            // Now the real stuff: we register the order for the domains, and have them validated by the ACME service
            IHTTPChallengeValidator httpChallengeValidator = HTTPChallengeValidatorFactory.GetHTTPChallengeValidator(_winCertesOptions.Standalone, _winCertesOptions.HttpPort, _winCertesOptions.WebRoot);
            IDNSChallengeValidator  dnsChallengeValidator  = DNSChallengeValidatorFactory.GetDNSChallengeValidator();

            if ((httpChallengeValidator == null) && (dnsChallengeValidator == null))
            {
                WriteErrorMessageWithUsage(_options, "Specify either an HTTP or a DNS validation method.");
                return(MainExit(ERROR_MISSING_HTTP_DNS));
            }
            if (!(Task.Run(() => _certesWrapper.RegisterNewOrderAndVerify(_winCertesOptions.Domains, httpChallengeValidator, dnsChallengeValidator)).GetAwaiter().GetResult()))
            {
                if (httpChallengeValidator != null)
                {
                    httpChallengeValidator.EndAllChallengeValidations();
                }
                return(MainExit(ERROR));
            }
            if (httpChallengeValidator != null)
            {
                httpChallengeValidator.EndAllChallengeValidations();
            }

            // We get the certificate from the ACME service
            string pfxFullFileName = _winCertesPath + "\\" + _winCertesOptions.CertificateName;
            var    pfx             = Task.Run(() =>
                                              _certesWrapper.RetrieveCertificate(_winCertesOptions.Domains, pfxFullFileName, Utils.DomainsToFriendlyName(_winCertesOptions.Domains), _winCertesOptions.ExportPem)
                                              ).GetAwaiter().GetResult();

            if (pfx == null)
            {
                return(MainExit(ERROR));
            }
            CertificateStorageManager certificateStorageManager = new CertificateStorageManager(pfx, (_winCertesOptions.Csp == null) && (!_winCertesOptions.noCsp));

            // Let's process the PFX into Windows Certificate object.
            certificateStorageManager.ProcessPFX();
            // and we write its information to the WinCertes configuration
            RegisterCertificateIntoConfiguration(certificateStorageManager.Certificate, _winCertesOptions.Domains);
            // Import the certificate into the Windows store
            if (!_winCertesOptions.noCsp)
            {
                certificateStorageManager.ImportCertificateIntoCSP(_winCertesOptions.Csp);
            }

            // Bind certificate to IIS Site (won't do anything if option is null)
            Utils.BindCertificateForIISSite(certificateStorageManager.Certificate, _winCertesOptions.BindName);
            // Execute PowerShell Script (won't do anything if option is null)
            Utils.ExecutePowerShell(_winCertesOptions.ScriptFile, pfx);
            // Create the AT task that will execute WinCertes periodically (won't do anything if taskName is null)
            Utils.CreateScheduledTask(taskName, _winCertesOptions.Domains, _extra);

            // Let's delete the PFX file, if export was not enabled
            if (!_winCertesOptions.ExportPem)
            {
                RemoveFileAndLog(pfx);
            }

            return(MainExit(SUCCESS));
        }