private void btnCreateContact_Click(object sender, EventArgs e) { bool isValidEmail = true; if (String.IsNullOrEmpty(txtContacts.Text)) { isValidEmail = false; } else { if (!Regex.IsMatch(txtContacts.Text, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" + @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250))) { isValidEmail = false; } } if (!isValidEmail) { MessageBox.Show("Ooops, you forgot to provide a valid email address."); this.DialogResult = DialogResult.None; return; } if (chkAgreeTandCs.Checked) { if (vaultManager != null) { var vaultConfig = vaultManager.GetVaultConfig(); if (vaultConfig != null) { //TODO: check for dupe registration } btnCreateContact.Enabled = false; this.Cursor = Cursors.WaitCursor; vaultManager.AddNewRegistration("mailto:" + txtContacts.Text); this.Cursor = Cursors.Default; } } else { MessageBox.Show("You need to agree to the latest LetsEncrypt.org Subscriber Agreement."); this.DialogResult = DialogResult.None; } }
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(); } } }
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; } } }