private async Task <bool> Register()
        {
            if (IsInternet())
            {
                //check if all fields are completed
                if (String.IsNullOrWhiteSpace(Username) || String.IsNullOrWhiteSpace(Password) || String.IsNullOrWhiteSpace(ConfirmPass))
                {
                    await DisplayError(ErrorMsg.CompleteAllFieldsError);
                }
                else
                {
                    //verify status of fields
                    Models.TaskStatus emailStatus = FieldsHelper.VerifyEmail(Username);
                    if (!emailStatus.IsError)
                    {
                        Models.TaskStatus passwordStatus = FieldsHelper.VerifyPassword(Password);
                        if (!passwordStatus.IsError)
                        {
                            if (ConfirmPass == Password)
                            {
                                if (!Password.ToLower().Contains(Username.ToLower()))
                                {
                                    await PageService.PushPopupAsync(new WaitForActionView());

                                    string            authPassword   = VaultManager.CreateAuthPassword(Username, Password);
                                    Models.TaskStatus statusRegister = await UserProcessor.Register(ApiHelper.ApiClient, Username, authPassword, authPassword);

                                    if (!statusRegister.IsError)
                                    {
                                        return(true);
                                    }
                                    else
                                    {
                                        await PageService.PopPopupAsync();
                                        await DisplayError(statusRegister.Message);
                                    }
                                }
                                else
                                {
                                    await DisplayError("Your email can't be in your password!");
                                }
                            }
                            else
                            {
                                await DisplayError("Your Confirm Password and your Password are not the same!");
                            }
                        }
                        else
                        {
                            await DisplayError(passwordStatus.Message);
                        }
                    }
                    else
                    {
                        await DisplayError(emailStatus.Message);
                    }
                }
            }
            return(false);
        }
        private async Task <bool> SignIn()
        {
            if (IsInternet())
            {
                //check if fields are completed
                if (String.IsNullOrWhiteSpace(Username) || String.IsNullOrWhiteSpace(Password))
                {
                    await DisplayError(ErrorMsg.CompleteAllFieldsError);
                }
                else
                {
                    await PageService.PushPopupAsync(new WaitForActionView());

                    //create auth password
                    string            authPassword = VaultManager.CreateAuthPassword(Username, Password);
                    Models.TaskStatus statusLogin  = await UserProcessor.LogIn(ApiHelper.ApiClient, Username, authPassword);

                    if (!statusLogin.IsError)
                    {
                        return(true);
                    }
                    else
                    {
                        await PageService.PopPopupAsync();
                        await DisplayError(statusLogin.Message);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 3
0
        private protected override object DecryptItem(object obj)
        {
            var noteToDecrypt = (Note)obj;

            noteToDecrypt.Notes = VaultManager.DecryptString(noteToDecrypt.Notes);
            return(noteToDecrypt);
        }
Exemplo n.º 4
0
        private void OkButton_Click(object sender, RoutedEventArgs e)
        {
            if (ValidateForm())
            {
                if (Mode == VaultEntryFormMode.Edit)
                {
                    this.CurrentEntry.Title    = titleTextBox.Text;
                    this.CurrentEntry.Login    = usernameTextBox.Text;
                    this.CurrentEntry.Password = passwordBox.Password;
                    this.CurrentEntry.Note     = notesTextBox.Text;
                    this.CurrentEntry.Url      = urlTextBox.Text;
                }
                else
                {
                    this.CurrentEntry = VaultManager.GenerateNewEntry(
                        titleTextBox.Text,
                        usernameTextBox.Text,
                        passwordBox.Password,
                        notesTextBox.Text,
                        urlTextBox.Text);
                }

                if (NewEntryOk != null)
                {
                    NewEntryOk(this.CurrentEntry);
                }
                this.Close();
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Test dummy method for async UI testing etc
        /// </summary>
        /// <param name="vaultManager"></param>
        /// <param name="managedSite"></param>
        /// <param name="progress"></param>
        /// <returns></returns>
        public async Task <CertificateRequestResult> PerformDummyCertificateRequest(VaultManager vaultManager, ManagedSite managedSite, IProgress <RequestProgressState> progress = null)
        {
            return(await Task <CertificateRequestResult> .Run <CertificateRequestResult>(() =>
            {
                for (var i = 0; i < 6; i++)
                {
                    if (progress != null)
                    {
                        progress.Report(new RequestProgressState {
                            CurrentState = RequestState.Running, Message = "Step " + i
                        });
                    }

                    var time = new Random().Next(2000);
                    System.Threading.Thread.Sleep(time);
                }
                if (progress != null)
                {
                    progress.Report(new RequestProgressState {
                        CurrentState = RequestState.Success, Message = "Finish"
                    });
                }
                System.Threading.Thread.Sleep(500);
                return new CertificateRequestResult {
                };
            }));
        }
Exemplo n.º 6
0
        private protected override object EncryptItem(object obj)
        {
            var noteToEncrypt = (Note)obj;

            noteToEncrypt       = (Note)noteToEncrypt.Clone();
            noteToEncrypt.Notes = VaultManager.EncryptString(noteToEncrypt.Notes);
            return(noteToEncrypt);
        }
Exemplo n.º 7
0
        private protected override object DecryptItem(object obj)
        {
            var passwordToDecrypt = (Password)obj;

            passwordToDecrypt.PasswordEncrypted = VaultManager.DecryptString(passwordToDecrypt.PasswordEncrypted);
            passwordToDecrypt.Url   = VaultManager.DecryptString(passwordToDecrypt.Url);
            passwordToDecrypt.Notes = VaultManager.DecryptString(passwordToDecrypt.Notes);
            return(passwordToDecrypt);
        }
Exemplo n.º 8
0
        private void PerformVaultCleanup()
        {
            var vaultManager = new VaultManager(Properties.Settings.Default.VaultPath, LocalDiskVault.VAULT);

            //init vault if not already created
            vaultManager.InitVault(staging: true);

            vaultManager.CleanupVault();
        }
Exemplo n.º 9
0
        public void Can_create_keyfiles()
        {
            string folder = GetFolder("Create");

            TestHelper.DeleteFolder(folder);
            var manager = new VaultManager(folder);

            manager.CreateKeyFiles();
        }
Exemplo n.º 10
0
 private protected override object DecryptItem(object obj)
 {
     var cardToDecrypt = (PaymentCard)obj;
     cardToDecrypt.NameOnCard = VaultManager.DecryptString(cardToDecrypt.NameOnCard);
     cardToDecrypt.CardType = VaultManager.DecryptString(cardToDecrypt.CardType);
     cardToDecrypt.CardNumber = VaultManager.DecryptString(cardToDecrypt.CardNumber);
     cardToDecrypt.SecurityCode = VaultManager.DecryptString(cardToDecrypt.SecurityCode);
     cardToDecrypt.Notes = VaultManager.DecryptString(cardToDecrypt.Notes);
     return cardToDecrypt;
 }
Exemplo n.º 11
0
        private protected override object DecryptItem(object obj)
        {
            var wifiToDecrypt = (Wifi)obj;

            wifiToDecrypt.PasswordEncrypted = VaultManager.DecryptString(wifiToDecrypt.PasswordEncrypted);
            wifiToDecrypt.SSID             = VaultManager.DecryptString(wifiToDecrypt.SSID);
            wifiToDecrypt.SettingsPassword = VaultManager.DecryptString(wifiToDecrypt.SettingsPassword);
            wifiToDecrypt.ConnectionType   = VaultManager.DecryptString(wifiToDecrypt.ConnectionType);
            wifiToDecrypt.Notes            = VaultManager.DecryptString(wifiToDecrypt.Notes);
            return(wifiToDecrypt);
        }
Exemplo n.º 12
0
        public void Can_tell_if_publickey_does_exist()
        {
            string folder  = GetFolder("Public");
            var    manager = new VaultManager(folder);

            manager.CreateKeyFiles(true);
            var reader = new VaultReader(folder);

            var publicKeyExists = reader.PublicKeyExists;

            Assert.True(publicKeyExists);
        }
Exemplo n.º 13
0
 private void OkButton_Click(object sender, RoutedEventArgs e)
 {
     if (vaultFileName != null &&
         VaultManager.IsValidPassword(passwordBox.Password))
     {
         CloseMyself();
     }
     else
     {
         MessageBox.Show("You must enter a valid password");
     }
 }
Exemplo n.º 14
0
        private static void MakeChoices(VaultReader reader, VaultManager manager, string folder)
        {
            var choices = new Dictionary <int, Choice>();

            do
            {
                Output.Flush();
                SetupChoices(choices, reader, manager);
                PrintChoices(choices, reader, manager, folder);
            } while (Choose(choices, reader, manager));
            Output.Flush();
        }
Exemplo n.º 15
0
        public static string GetGCPCredentialJson(IConfiguration _configuration, VaultManager _vaultClient)
        {
            var credential = new GCPCredentials();

            _configuration.GetSection("GCP").Bind(credential);
            credential.PrivateKeyId  = _vaultClient.GetSecret(_configuration["KeyVault:FirebasePrivateKeyIdKey"]);
            credential.PrivateKey    = Regex.Unescape(_vaultClient.GetSecret(_configuration["KeyVault:FirebasePrivateKey"]));
            credential.ClientId      = _configuration["KeyVault:FirebaseClientIdKey"];
            credential.ClientEmail   = _configuration["KeyVault:FirebaseClientEmailKey"];
            credential.ProjectId     = _configuration["KeyVault:FirebaseProjectIdKey"];
            credential.ClientCertURL = _configuration["KeyVault:FirebaseClientCertURLKey"];
            return(JsonConvert.SerializeObject(credential));
        }
Exemplo n.º 16
0
        public CertRequestDialog(VaultManager vaultManager) : this()
        {
            this.vaultManager = vaultManager;

            lstRequestType.SelectedIndex = 0;
            //share the vault manager with the current request control type

            if (!this.vaultManager.HasContacts())
            {
                MessageBox.Show("You need to register a valid contact before you can proceed.");
                this.DialogResult = DialogResult.Cancel;
                this.Close();
            }
        }
Exemplo n.º 17
0
        public void Can_set_key()
        {
            var folder  = GetFolder("SetKey");
            var manager = new VaultManager(folder);

            manager.CreateKeyFiles(true);
            string key   = TestHelper.GenerateValue();
            string value = TestHelper.GenerateValue();

            manager.SetValue(key, value);

            var reader = new VaultReader(folder);

            Assert.Equal(value, reader[key]);
        }
Exemplo n.º 18
0
        public void Can_read_value()
        {
            string folder  = GetFolder("Keys");
            var    manager = new VaultManager(folder);

            manager.CreateKeyFiles(true);
            var key   = TestHelper.GenerateValue();
            var value = TestHelper.GenerateValue();

            manager.SetValue(key, value);
            var reader = new VaultReader(folder);

            var content = reader[key];

            Assert.Equal(value, content);
        }
Exemplo n.º 19
0
        public void Can_delete_key()
        {
            var folder  = GetFolder("DeleteKey");
            var manager = new VaultManager(folder);

            manager.CreateKeyFiles(true);
            string key   = TestHelper.GenerateValue();
            string value = TestHelper.GenerateValue();

            manager.SetValue(key, value);

            manager.Delete(key);

            var reader = new VaultReader(folder);

            Assert.True(reader[key] == null);
        }
Exemplo n.º 20
0
        public IActionResult GetAll(int id)
        {
            VaultsResponse response = new VaultsResponse();

            response.status         = new Status();
            response.status.success = false;
            try
            {
                VaultManager manager = new VaultManager(context);
                response.vaults         = manager.getAll(id);
                response.status.success = true;
            }
            catch (Exception exception)
            {
                response.status.errorMessage = exception.Message;
            }
            return(Json(response));
        }
Exemplo n.º 21
0
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Welcome to the QuickVault tool.");
                Console.WriteLine("");
                string folder = GetQuickVaultFolder(Directory.GetCurrentDirectory());

                var manager = new VaultManager(folder);
                var reader  = new VaultReader(folder);

                MakeChoices(reader, manager, folder);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Exemplo n.º 22
0
        public void Can_access_all_keys()
        {
            string folder  = GetFolder("Keys");
            var    manager = new VaultManager(folder);

            manager.CreateKeyFiles(true);
            var key1  = TestHelper.GenerateValue();
            var key2  = TestHelper.GenerateValue();
            var value = TestHelper.GenerateValue();

            manager.SetValue(key1, value);
            manager.SetValue(key2, value);
            var reader = new VaultReader(folder);

            var keys = reader.Keys.ToHashSet();

            Assert.Contains(key1, keys);
            Assert.Contains(key2, keys);
        }
Exemplo n.º 23
0
        public IActionResult SaveVault([FromBody] OVault vault)
        {
            VaultResponse response = new VaultResponse();

            response.status         = new Status();
            response.status.success = false;
            try
            {
                using (var transaction = context.Database.BeginTransaction())
                {
                    VaultManager manager = new VaultManager(context);
                    response.vault          = manager.Save(vault);
                    response.status.success = true;

                    transaction.Commit();
                }
            }
            catch (Exception exception)
            {
                response.status.errorMessage = exception.Message;
            }
            return(Json(response));
        }
Exemplo n.º 24
0
        public void ReloadVault()
        {
            this.VaultManager = ((MainForm)this.Parent.FindForm()).VaultManager;
            VaultManager.ReloadVaultConfig();
            var vaultInfo = VaultManager.GetVaultConfig();

            if (vaultInfo != null)
            {
                this.lblVaultLocation.Text = VaultManager.VaultFolderPath;
                this.lblAPIBaseURI.Text    = vaultInfo.BaseUri;

                populateTreeView(vaultInfo);

                this.UpdateLogView(VaultManager.GetActionLogSummary());

                //store setting for current vault path
                if (Properties.Settings.Default.VaultPath != VaultManager.VaultFolderPath)
                {
                    Properties.Settings.Default.VaultPath = VaultManager.VaultFolderPath;
                    Properties.Settings.Default.Save();
                }
            }
        }
Exemplo n.º 25
0
        public IActionResult DeleteVault(int vaultId)
        {
            ServiceResponse response = new ServiceResponse();

            response.status         = new Status();
            response.status.success = false;
            try
            {
                using (var transaction = context.Database.BeginTransaction())
                {
                    VaultManager manager = new VaultManager(context);
                    manager.Delete(vaultId);
                    response.status.success = true;

                    transaction.Commit();
                }
            }
            catch (Exception exception)
            {
                response.status.errorMessage = exception.Message;
            }
            return(Json(response));
        }
Exemplo n.º 26
0
        public async Task <List <CertificateRequestResult> > PerformRenewalAllManagedSites(bool autoRenewalOnly = true)
        {
            siteManager.LoadSettings();

            var vaultManager = new VaultManager(Properties.Settings.Default.VaultPath, ACMESharp.Vault.Providers.LocalDiskVault.VAULT);

            IEnumerable <ManagedSite> sites = siteManager.GetManagedSites();

            var results = new List <CertificateRequestResult>();

            if (autoRenewalOnly)
            {
                sites = sites.Where(s => s.IncludeInAutoRenew == true);
            }

            foreach (var s in sites.Where(s => s.IncludeInAutoRenew == true))
            {
                results.Add(await this.PerformCertificateRequest(vaultManager, s));
            }

            siteManager.StoreSettings();

            return(results);
        }
Exemplo n.º 27
0
        private void btnRequestCertificate_Click(object sender, EventArgs e)
        {
            if (lstSites.SelectedItem == null)
            {
                MessageBox.Show("No IIS Site Selected");
                return;
            }

            if (VaultManager == null)
            {
                MessageBox.Show("Vault Manager is null. Please report this problem.");
            }

            //prevent further clicks on request button
            btnRequestCertificate.Enabled = false;
            ShowProgressBar();
            this.Cursor = Cursors.WaitCursor;

            bool certsApproved = false;
            bool certsStored   = false;

            CertRequestConfig config = new CertRequestConfig();
            var selectItem           = (SiteListItem)lstSites.SelectedItem;

            config.Domain = selectItem.Host;
            config.PerformChallengeFileCopy = true;
            config.WebsiteRootPath          = Environment.ExpandEnvironmentVariables(selectItem.PhysicalPath);

            var vaultConfig = VaultManager.GetVaultConfig();

            //check if domain already has an associated identifier
            var identifierAlias = VaultManager.ComputeIdentifierAlias(config.Domain);

            //try alias or DNS name before creating a new identifier
            var identifier = VaultManager.GetIdentifier(identifierAlias);

            if (identifier == null)
            {
                identifier = VaultManager.GetIdentifier(config.Domain);
            }

            if (identifier != null)
            {
                //domain already exists in vault
                //check if has pending authorization challenges
                if (identifier.Authorization != null && identifier.Authorization.Challenges != null)
                {
                    var challenge = identifier.Authorization.Challenges.FirstOrDefault(c => c.Type == "http-01");
                    if (challenge != null)
                    {
                        if (challenge.Status != "invalid")
                        {
                            //update challenge status
                            MessageBox.Show("An existing challenge was already in progress, status will now be updated. " + challenge.Token);
                            VaultManager.UpdateIdentifierStatus(identifierAlias);

                            identifier = VaultManager.GetIdentifier(identifierAlias
                                                                    , true);

                            challenge = identifier.Authorization.Challenges.FirstOrDefault(c => c.Type == "http-01");
                            if (challenge.Status == "valid")
                            {
                                certsApproved = true;
                            }
                        }
                        else
                        {
                            MessageBox.Show("The existing challenge for this identifier failed. We will need to create a new one.");
                            identifierAlias += "_" + Guid.NewGuid().ToString().Substring(0, 6);
                        }
                    }
                }
            }

            if (!certsApproved)
            {
                var authorization = VaultManager.DomainInitAndRegistration(config, identifierAlias);

                if (authorization != null)
                {
                    if (!authorization.ExtensionlessConfigCheckedOK)
                    {
                        MessageBox.Show("Automated checks for extensionless content failed. Authorisations will not be able to complete. Change the web.config in <your site>\\.well-known\\acme-challenge and ensure you can browse to http://<your site>/.well-known/acme-challenge/configcheck before proceeding.");
                        return;
                    }
                    //at this point we can either get the user to manually copy the file to web site folder structure
                    //if file has already been copied we can go ahead and ask the server to verify it

                    //ask server to check our challenge answer is present and correct
                    VaultManager.SubmitChallenge(authorization.Identifier.Alias);

                    //give LE time to check our challenge answer stored on our server
                    Thread.Sleep(2000);

                    VaultManager.UpdateIdentifierStatus(authorization.Identifier.Alias);
                    VaultManager.ReloadVaultConfig();

                    //check status of the challenge
                    var updatedIdentifier = VaultManager.GetIdentifier(authorization.Identifier.Alias);

                    var challenge = updatedIdentifier.Authorization.Challenges.FirstOrDefault(c => c.Type == "http-01");

                    //if all OK, we will be ready to fetch our certificate
                    if (challenge?.Status == "valid")
                    {
                        certsApproved = true;
                    }
                    else
                    {
                        if (challenge != null)
                        {
                            MessageBox.Show("Challenge not yet completed. Check that http://" + config.Domain + "/" + challenge.ToString() + " path/file is present and accessible in your web browser.");
                        }
                        else
                        {
                            if (challenge.Status == "invalid")
                            {
                                MessageBox.Show("Challenge failed to complete. Check that http://" + config.Domain + "/" + challenge.ToString() + " path/file is present and accessible in your web browser. You may require extensionless file type mappings");
                            }
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Could not begin authorization. Check Logs. Ensure the domain being authorized is whitelisted with LetsEncrypt service.");
                }
            }

            //create certs for current authorization
            string certRef = null;
            //if (certsApproved)
            {
                certRef = VaultManager.CreateCertificate(identifierAlias);
                VaultManager.UpdateIdentifierStatus(identifierAlias);
                identifier = VaultManager.GetIdentifier(identifierAlias, true);

                VaultManager.ReloadVaultConfig();
                if (VaultManager.CertExists(identifierAlias))
                {
                    certsStored = true;
                }
            }

            //auto setup/install
            var certInfo = VaultManager.GetCertificate(certRef);

            if (certInfo != null && certInfo.CrtDerFile == null)
            {
                //failed to get cert first time, try again
                certRef = VaultManager.CreateCertificate(identifierAlias);
                VaultManager.UpdateIdentifierStatus(identifierAlias);

                certInfo = VaultManager.GetCertificate(certRef);
            }

            //txtOutput.Text = "To complete this request copy the file " + CurrentAuthorization.TempFilePath + " to the following location under your website root (note: no file extension): " + CurrentAuthorization.Challenge.ChallengeAnswer.Key;
            //ReloadVault();

            this.Cursor = Cursors.Default;

            if (!certsStored)
            {
                if (certsApproved)
                {
                    MessageBox.Show("Certificates approved but not yet stored in vault. Try again later.");
                    CloseParentForm();
                    return;
                }
                else
                {
                    MessageBox.Show("Certificates not approved yet. Authorization challenge may have failed. Try again later.");
                    CloseParentForm();
                    return;
                }
            }
            else
            {
                if (certInfo != null)
                {
                    string certFolderPath = VaultManager.GetCertificateFilePath(certInfo.Id, LocalDiskVault.ASSET);
                    string pfxFile        = certInfo.Id.ToString() + "-all.pfx";
                    string pfxPath        = Path.Combine(certFolderPath, pfxFile);

                    if (!System.IO.Directory.Exists(certFolderPath))
                    {
                        System.IO.Directory.CreateDirectory(certFolderPath);
                    }
                    if (!File.Exists(pfxPath))
                    {
                        //hmm, no pfx, try to create pfx again TODO: shouldn't need this
                        VaultManager.ExportCertificate("=" + certInfo.Id.ToString(), pfxOnly: true);
                    }

                    if (File.Exists(pfxPath))
                    {
                        //VaultManager.UpdateIdentifierStatus(certInfo.IdentifierRef);
                        //identifier = VaultManager.GetIdentifier(certInfo.IdentifierRef, true);

                        IISManager iisManager = new IISManager();
                        if (identifier == null || identifier.Dns == null)
                        {
                            MessageBox.Show("Error: identifier/dns is null. Cannot match domain for binding");
                        }
                        else
                        {
                            if (iisManager.InstallCertForDomain(identifier.Dns, pfxPath, cleanupCertStore: true, skipBindings: !chkAutoBindings.Checked))
                            {
                                //all done
                                MessageBox.Show("Certificate installed and SSL bindings updated for " + identifier.Dns, Properties.Resources.AppName);
                                CloseParentForm();
                                return;
                            }

                            if (chkAutoBindings.Checked)
                            {
                                //auto store and create site bindings
                                MessageBox.Show("Your certificate has been imported and SSL bindings updated for " + config.Domain, Properties.Resources.AppName);
                                CloseParentForm();
                                return;
                            }
                            else
                            {
                                //auto store cert
                                MessageBox.Show("Your certificate has been imported and is ready for you to configure IIS bindings.", Properties.Resources.AppName);
                                CloseParentForm();
                                return;
                            }
                        }
                    }
                    else
                    {
                        MessageBox.Show("Failed to generate PFX file for Certificate.", Properties.Resources.AppName);
                        CloseParentForm();
                        return;
                    }
                }
                else
                {
                    //cert was null
                    MessageBox.Show("Certification was not successful. Certificate not valid or not yet authorized.", Properties.Resources.AppName);
                    CloseParentForm();
                    return;
                }
            }
        }
Exemplo n.º 28
0
        public List <ManagedSite> ImportManagedSitesFromVault(bool mergeSitesAsSan = false)
        {
            var sites = new List <ManagedSite>();

            //get dns identifiers from vault
            var vaultManager = new VaultManager(Properties.Settings.Default.VaultPath, ACMESharp.Vault.Providers.LocalDiskVault.VAULT);
            var iisManager   = new IISManager();

            var identifiers = vaultManager.GetIdentifiers();
            var iisSites    = iisManager.GetSiteBindingList(ignoreStoppedSites: Certify.Properties.Settings.Default.IgnoreStoppedSites);

            foreach (var identifier in identifiers)
            {
                //identify IIS site related to this identifier (if any)
                var iisSite = iisSites.FirstOrDefault(d => d.Host == identifier.Dns);
                var site    = new ManagedSite
                {
                    Id                 = Guid.NewGuid().ToString(),
                    GroupId            = iisSite?.SiteId,
                    Name               = identifier.Dns + (iisSite != null ? " : " + iisSite.SiteName : ""),
                    IncludeInAutoRenew = true,
                    Comments           = "Imported from vault",
                    ItemType           = ManagedItemType.SSL_LetsEncrypt_LocalIIS,
                    TargetHost         = "localhost",
                    RequestConfig      = new CertRequestConfig
                    {
                        BindingIPAddress                 = iisSite?.IP,
                        BindingPort                      = iisSite?.Port.ToString(),
                        ChallengeType                    = "http-01",
                        EnableFailureNotifications       = true,
                        PerformAutoConfig                = true,
                        PerformAutomatedCertBinding      = true,
                        PerformChallengeFileCopy         = true,
                        PerformExtensionlessConfigChecks = true,
                        PrimaryDomain                    = identifier.Dns,
                        SubjectAlternativeNames          = new string[] { identifier.Dns },
                        WebsiteRootPath                  = iisSite?.PhysicalPath
                    },
                    DomainOptions = new List <DomainOption>()
                    {
                        new DomainOption {
                            Domain = identifier.Dns, IsPrimaryDomain = true, IsSelected = true
                        }
                    }
                };

                sites.Add(site);
            }

            if (mergeSitesAsSan)
            {
                foreach (var s in sites)
                {
                    //merge sites with same group (iis site etc) and different primary domain
                    if (sites.Any(m => m.GroupId != null && m.GroupId == s.GroupId && m.RequestConfig.PrimaryDomain != s.RequestConfig.PrimaryDomain))
                    {
                        //existing site to merge into
                        //add san for dns
                        var mergedSite = sites.FirstOrDefault(m =>
                                                              m.GroupId != null && m.GroupId == s.GroupId &&
                                                              m.RequestConfig.PrimaryDomain != s.RequestConfig.PrimaryDomain &&
                                                              m.RequestConfig.PrimaryDomain != null
                                                              );
                        if (mergedSite != null)
                        {
                            mergedSite.DomainOptions.Add(new DomainOption {
                                Domain = s.RequestConfig.PrimaryDomain, IsPrimaryDomain = false, IsSelected = true
                            });

                            //use shortest version of domain name as site name
                            if (mergedSite.RequestConfig.PrimaryDomain.Contains(s.RequestConfig.PrimaryDomain))
                            {
                                mergedSite.Name = mergedSite.Name.Replace(mergedSite.RequestConfig.PrimaryDomain, s.RequestConfig.PrimaryDomain);
                            }

                            //flag spare site config to be discar
                            s.RequestConfig.PrimaryDomain = null;
                        }
                    }
                }

                //discard sites which have been merged into other sites
                sites.RemoveAll(s => s.RequestConfig.PrimaryDomain == null);
            }
            return(sites);
        }
Exemplo n.º 29
0
        public async Task <CertificateRequestResult> PerformCertificateRequest(VaultManager vaultManager, ManagedSite managedSite, IProgress <RequestProgressState> progress = null)
        {
            // FIXME: refactor into different concerns, there's way to much being done here

            return(await Task.Run(async() =>
            {
                try
                {
                    ManagedSiteLog.AppendLog(managedSite.Id, new ManagedSiteLogItem {
                        EventDate = DateTime.UtcNow, LogItemType = LogItemType.GeneralInfo, Message = "Beginning Certificate Request Process: " + managedSite.Name
                    });

                    bool enableIdentifierReuse = false;

                    if (vaultManager == null)
                    {
                        vaultManager = GetVaultManager();
                    }

                    //enable or disable EFS flag on private key certs based on preference
                    vaultManager.UseEFSForSensitiveFiles = Properties.Settings.Default.EnableEFS;

                    //primary domain and each subject alternative name must now be registered as an identifier with LE and validated

                    if (progress != null)
                    {
                        progress.Report(new RequestProgressState {
                            IsRunning = true, CurrentState = RequestState.Running, Message = "Registering Domain Identifiers"
                        });
                    }

                    await Task.Delay(200); //allow UI update

                    var config = managedSite.RequestConfig;

                    List <string> allDomains = new List <string> {
                        config.PrimaryDomain
                    };

                    if (config.SubjectAlternativeNames != null)
                    {
                        allDomains.AddRange(config.SubjectAlternativeNames);
                    }

                    bool allIdentifiersValidated = true;

                    if (config.ChallengeType == null)
                    {
                        config.ChallengeType = "http-01";
                    }

                    List <PendingAuthorization> identifierAuthorizations = new List <PendingAuthorization>();
                    var distinctDomains = allDomains.Distinct();

                    foreach (var domain in distinctDomains)
                    {
                        var identifierAlias = vaultManager.ComputeIdentifierAlias(domain);

                        //check if this domain already has an associated identifier registerd with LetsEncrypt which hasn't expired yet
                        //await Task.Delay(200); //allow UI update

                        ACMESharp.Vault.Model.IdentifierInfo existingIdentifier = null;

                        if (enableIdentifierReuse)
                        {
                            existingIdentifier = vaultManager.GetIdentifier(domain.Trim().ToLower());
                        }

                        bool identifierAlreadyValid = false;
                        if (existingIdentifier != null &&
                            existingIdentifier.Authorization != null &&
                            (existingIdentifier.Authorization.Status == "valid" || existingIdentifier.Authorization.Status == "pending") &&
                            existingIdentifier.Authorization.Expires > DateTime.Now.AddDays(1))
                        {
                            //we have an existing validated identifier, reuse that for this certificate request
                            identifierAlias = existingIdentifier.Alias;

                            if (existingIdentifier.Authorization.Status == "valid")
                            {
                                identifierAlreadyValid = true;
                            }

                            // managedSite.AppendLog(new ManagedSiteLogItem { EventDate =
                            // DateTime.UtcNow, LogItemType = LogItemType.CertificateRequestStarted,
                            // Message = "Attempting Certificate Request: " + managedSite.SiteType });
                            System.Diagnostics.Debug.WriteLine("Reusing existing valid non-expired identifier for the domain " + domain);
                        }

                        ManagedSiteLog.AppendLog(managedSite.Id, new ManagedSiteLogItem {
                            EventDate = DateTime.UtcNow, LogItemType = LogItemType.CertificateRequestStarted, Message = "Attempting Domain Validation: " + domain
                        });

                        //begin authorization process (register identifier, request authorization if not already given)
                        if (progress != null)
                        {
                            progress.Report(new RequestProgressState {
                                Message = "Registering and Validating " + domain
                            });
                        }

                        //TODO: make operations async and yeild IO of vault

                        /*var authorization = await Task.Run(() =>
                         * {
                         *  return vaultManager.BeginRegistrationAndValidation(config, identifierAlias, challengeType: config.ChallengeType, domain: domain);
                         * });*/

                        var authorization = vaultManager.BeginRegistrationAndValidation(config, identifierAlias, challengeType: config.ChallengeType, domain: domain);

                        if (authorization != null && authorization.Identifier != null && !identifierAlreadyValid)
                        {
                            if (authorization.Identifier.Authorization.IsPending())
                            {
                                if (managedSite.ItemType == ManagedItemType.SSL_LetsEncrypt_LocalIIS)
                                {
                                    if (progress != null)
                                    {
                                        progress.Report(new RequestProgressState {
                                            Message = "Performing Challenge Response via IIS: " + domain
                                        });
                                    }

                                    //ask LE to check our answer to their authorization challenge (http), LE will then attempt to fetch our answer, if all accessible and correct (authorized) LE will then allow us to request a certificate
                                    //prepare IIS with answer for the LE challenege
                                    authorization = vaultManager.PerformIISAutomatedChallengeResponse(config, authorization);

                                    //if we attempted extensionless config checks, report any errors
                                    if (config.PerformAutoConfig && !authorization.ExtensionlessConfigCheckedOK)
                                    {
                                        ManagedSiteLog.AppendLog(managedSite.Id, new ManagedSiteLogItem {
                                            EventDate = DateTime.UtcNow, LogItemType = LogItemType.CertficateRequestFailed, Message = "Failed prerequisite configuration (" + managedSite.ItemType + ")"
                                        });
                                        siteManager.StoreSettings();

                                        var result = new CertificateRequestResult {
                                            ManagedItem = managedSite, IsSuccess = false, Message = "Automated configuration checks failed. Authorizations will not be able to complete.\nCheck you have http bindings for your site and ensure you can browse to http://" + domain + "/.well-known/acme-challenge/configcheck before proceeding."
                                        };
                                        if (progress != null)
                                        {
                                            progress.Report(new RequestProgressState {
                                                CurrentState = RequestState.Error, Message = result.Message, Result = result
                                            });
                                        }

                                        return result;
                                    }
                                    else
                                    {
                                        if (progress != null)
                                        {
                                            progress.Report(new RequestProgressState {
                                                CurrentState = RequestState.Running, Message = "Requesting Validation from Lets Encrypt: " + domain
                                            });
                                        }

                                        //ask LE to validate our challenge response
                                        vaultManager.SubmitChallenge(identifierAlias, config.ChallengeType);

                                        bool identifierValidated = vaultManager.CompleteIdentifierValidationProcess(authorization.Identifier.Alias);

                                        if (!identifierValidated)
                                        {
                                            if (progress != null)
                                            {
                                                progress.Report(new RequestProgressState {
                                                    CurrentState = RequestState.Error, Message = "Domain validation failed: " + domain
                                                });
                                            }

                                            allIdentifiersValidated = false;
                                        }
                                        else
                                        {
                                            if (progress != null)
                                            {
                                                progress.Report(new RequestProgressState {
                                                    CurrentState = RequestState.Running, Message = "Domain validation completed: " + domain
                                                });
                                            }

                                            identifierAuthorizations.Add(authorization);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (authorization.Identifier.Authorization.Status == "valid")
                                {
                                    identifierAuthorizations.Add(new PendingAuthorization {
                                        Identifier = authorization.Identifier
                                    });
                                }
                            }
                        }
                        else
                        {
                            if (identifierAlreadyValid)
                            {
                                //we have previously validated this identifier and it has not yet expired, so we can just reuse it in our cert request
                                identifierAuthorizations.Add(new PendingAuthorization {
                                    Identifier = existingIdentifier
                                });
                            }
                        }
                    }

                    //check if all identifiers validates
                    if (identifierAuthorizations.Count == distinctDomains.Count())
                    {
                        allIdentifiersValidated = true;
                    }

                    if (allIdentifiersValidated)
                    {
                        string primaryDnsIdentifier = identifierAuthorizations.First().Identifier.Alias;
                        string[] alternativeDnsIdentifiers = identifierAuthorizations.Where(i => i.Identifier.Alias != primaryDnsIdentifier).Select(i => i.Identifier.Alias).ToArray();

                        if (progress != null)
                        {
                            progress.Report(new RequestProgressState {
                                CurrentState = RequestState.Running, Message = "Requesting Certificate via Lets Encrypt"
                            });
                        }
                        //await Task.Delay(200); //allow UI update

                        var certRequestResult = vaultManager.PerformCertificateRequestProcess(primaryDnsIdentifier, alternativeDnsIdentifiers);
                        if (certRequestResult.IsSuccess)
                        {
                            if (progress != null)
                            {
                                progress.Report(new RequestProgressState {
                                    CurrentState = RequestState.Success, Message = "Completed Certificate Request."
                                });
                            }

                            string pfxPath = certRequestResult.Result.ToString();

                            if (managedSite.ItemType == ManagedItemType.SSL_LetsEncrypt_LocalIIS && config.PerformAutomatedCertBinding)
                            {
                                if (progress != null)
                                {
                                    progress.Report(new RequestProgressState {
                                        CurrentState = RequestState.Running, Message = "Performing Automated Certificate Binding"
                                    });
                                }
                                //await Task.Delay(200); //allow UI update

                                var iisManager = new IISManager();

                                //Install certificate into certificate store and bind to IIS site
                                if (iisManager.InstallCertForRequest(managedSite.RequestConfig, pfxPath, cleanupCertStore: true))
                                {
                                    //all done
                                    ManagedSiteLog.AppendLog(managedSite.Id, new ManagedSiteLogItem {
                                        EventDate = DateTime.UtcNow, LogItemType = LogItemType.CertificateRequestSuccessful, Message = "Completed certificate request and automated bindings update (IIS)"
                                    });

                                    //udpate managed site summary

                                    try
                                    {
                                        var certInfo = new CertificateManager().GetCertificate(pfxPath);
                                        managedSite.DateStart = certInfo.NotBefore;
                                        managedSite.DateExpiry = certInfo.NotAfter;
                                        managedSite.DateRenewed = DateTime.Now;

                                        managedSite.CertificatePath = pfxPath;
                                    }
                                    catch (Exception)
                                    {
                                        ManagedSiteLog.AppendLog(managedSite.Id, new ManagedSiteLogItem {
                                            EventDate = DateTime.UtcNow, LogItemType = LogItemType.GeneralWarning, Message = "Failed to parse certificate dates"
                                        });
                                    }
                                    siteManager.UpdatedManagedSite(managedSite);

                                    var result = new CertificateRequestResult {
                                        ManagedItem = managedSite, IsSuccess = true, Message = "Certificate installed and SSL bindings updated for " + config.PrimaryDomain
                                    };
                                    if (progress != null)
                                    {
                                        progress.Report(new RequestProgressState {
                                            IsRunning = false, CurrentState = RequestState.Success, Message = result.Message
                                        });
                                    }

                                    return result;
                                }
                                else
                                {
                                    return new CertificateRequestResult {
                                        ManagedItem = managedSite, IsSuccess = false, Message = "An error occurred installing the certificate. Certificate file may not be valid: " + pfxPath
                                    };
                                }
                            }
                            else
                            {
                                //user has opted for manual binding of certificate
                                try
                                {
                                    var certInfo = new CertificateManager().GetCertificate(pfxPath);
                                    managedSite.DateStart = certInfo.NotBefore;
                                    managedSite.DateExpiry = certInfo.NotAfter;
                                    managedSite.DateRenewed = DateTime.Now;

                                    managedSite.CertificatePath = pfxPath;
                                }
                                catch (Exception)
                                {
                                    ManagedSiteLog.AppendLog(managedSite.Id, new ManagedSiteLogItem {
                                        EventDate = DateTime.UtcNow, LogItemType = LogItemType.GeneralWarning, Message = "Failed to parse certificate dates"
                                    });
                                }
                                siteManager.UpdatedManagedSite(managedSite);

                                return new CertificateRequestResult {
                                    ManagedItem = managedSite, IsSuccess = true, Message = "Certificate created ready for manual binding: " + pfxPath
                                };
                            }
                        }
                        else
                        {
                            return new CertificateRequestResult {
                                ManagedItem = managedSite, IsSuccess = false, Message = "The Let's Encrypt service did not issue a valid certificate in the time allowed. " + (certRequestResult.ErrorMessage ?? "")
                            };
                        }
                    }
                    else
                    {
                        return new CertificateRequestResult {
                            ManagedItem = managedSite, IsSuccess = false, Message = "Validation of the required challenges did not complete successfully. Please ensure all domains to be referenced in the Certificate can be used to access this site without redirection. "
                        };
                    }
                }
                catch (Exception exp)
                {
                    System.Diagnostics.Debug.WriteLine(exp.ToString());
                    return new CertificateRequestResult {
                        ManagedItem = managedSite, IsSuccess = false, Message = managedSite.Name + ": Request failed - " + exp.Message
                    };
                }
            }));
        }
Exemplo n.º 30
0
        private bool PerformCertRequestAndIISBinding(string certDomain, string[] alternativeNames)
        {
            // ACME service requires international domain names in ascii mode
            certDomain = _idnMapping.GetAscii(certDomain);

            //create cert and binding it

            //Typical command sequence for a new certificate

            //Initialize-ACMEVault -BaseURI https://acme-staging.api.letsencrypt.org/

            // Get-Module -ListAvailable ACMESharp
            // New-ACMEIdentifier -Dns test7.examplesite.co.uk -Alias test7_examplesite_co_uk636213616564101276 -Label Identifier:test7.examplesite.co.uk
            // Complete-ACMEChallenge -Ref test7_examplesite_co_uk636213616564101276 -ChallengeType http-01 -Handler manual  -Regenerate
            // Submit-ACMEChallenge -Ref test7_examplesite_co_uk636213616564101276 -Challenge http-01
            // Update-ACMEIdentifier -Ref test7_examplesite_co_uk636213616564101276
            // Update-ACMEIdentifier -Ref test7_examplesite_co_uk636213616564101276
            // New-ACMECertificate -Identifier test7_examplesite_co_uk636213616564101276 -Alias cert_test7_examplesite_co_uk636213616564101276 -Generate
            // Update-ACMEIdentifier -Ref test7_examplesite_co_uk636213616564101276
            // Update-ACMEIdentifier -Ref test7_examplesite_co_uk636213616564101276
            // Get-ACMECertificate -Ref = ac22dbfe - b75f - 4cac-9247-b40c1d9bf9eb -ExportPkcs12 C:\ProgramData\ACMESharp\sysVault\99-ASSET\ac22dbfe-b75f-4cac-9247-b40c1d9bf9eb-all.pfx -Overwrite

            //get info on existing IIS site we want to create/update SSL binding for
            IISManager iisManager = new IISManager();
            var        iisSite    = iisManager.GetSiteBindingByDomain(certDomain);
            var        certConfig = new CertRequestConfig()
            {
                PrimaryDomain            = certDomain,
                PerformChallengeFileCopy = true,
                WebsiteRootPath          = Environment.ExpandEnvironmentVariables(iisSite.PhysicalPath)
            };

            var certifyManager = new VaultManager(Properties.Settings.Default.VaultPath, LocalDiskVault.VAULT);

            certifyManager.UsePowershell = false;

            //init vault if not already created
            certifyManager.InitVault(staging: true);

            //domain alias is used as an ID in both the vault and the LE server, it's specific to one authorization attempt and cannot be reused for renewal
            var domainIdentifierAlias = certifyManager.ComputeIdentifierAlias(certDomain);

            //NOTE: to support a SAN certificate (multiple alternative domains on one site) the domain validation steps need to be repeat for each name:

            //register identifier with LE, get http challenge spec back
            //create challenge response answer file under site .well-known, auto configure web.config for extenstionless content, mark challenge prep completed
            var authState = certifyManager.BeginRegistrationAndValidation(certConfig, domainIdentifierAlias);

            //ask LE to check our answer to their authorization challenge (http), LE will then attempt to fetch our answer, if all accessible and correct (authorized) LE will then allow us to request a certificate
            if (authState.Identifier.Authorization.IsPending())
            {
                //prepare IIS with answer for the LE challenege
                certifyManager.PerformIISAutomatedChallengeResponse(certConfig, authState);

                //ask LE to validate our challenge response
                certifyManager.SubmitChallenge(domainIdentifierAlias, "http-01");
            }

            //now check if LE has validated our challenge answer
            bool validated = certifyManager.CompleteIdentifierValidationProcess(domainIdentifierAlias);

            if (validated)
            {
                var certRequestResult = certifyManager.PerformCertificateRequestProcess(domainIdentifierAlias, alternativeIdentifierRefs: null);
                if (certRequestResult.IsSuccess)
                {
                    string pfxPath = certRequestResult.Result.ToString();
                    //Install certificate into certificate store and bind to IIS site
                    //TODO, match by site id?
                    if (iisManager.InstallCertForDomain(certDomain, pfxPath, cleanupCertStore: true, skipBindings: false))
                    {
                        //all done
                        System.Diagnostics.Debug.WriteLine("Certificate installed and SSL bindings updated for " + certDomain);
                        return(true);
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Failed to install PFX file for Certificate.");
                        return(false);
                    }
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("LE did not issue a valid certificate in the time allowed.");
                    return(false);
                }
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("Validation of the required challenges did not complete successfully.");
                return(false);
            }
        }