using System; using System.Data; using System.Configuration; using System.Collections; using System.Text.RegularExpressions; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Collections.Generic; using System.Collections.Specialized; using WebsitePanel.EnterpriseServer; using WebsitePanel.Providers.Web; using WebsitePanel.Providers.Common; using System.IO; using System.Linq; using WebsitePanel.Providers; namespace WebsitePanel.Portal { public partial class WebsitesSSL : WebsitePanelControlBase { public const string WEB_SSL_DELETE = "WEB_SSL_DELETE"; public const string WEB_SSL_EXPORT = "WEB_SSL_EXPORT"; public const string WEB_GEN_CSR = "WEB_GEN_CSR"; public const string ERROR_CSR = "ERROR_CSR"; public SSLCertificate InstalledCert { get { return (SSLCertificate)ViewState["InstalledCert"]; } set { ViewState["InstalledCert"] = value; } } public int SiteId { get { return (int)ViewState["SiteId"]; } set { ViewState["SiteId"] = value; } } public SSLCertificate PendingCert { get; set; } public string State { get { if (ddlStates.Visible) return ddlStates.SelectedValue; else return txtState.Text.Trim(); } set { EnsureChildControls(); // if (ddlStates.Visible) ddlStates.SelectedValue = value; else txtState.Text = value; } } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // Load countries BindCountries(); BindStates(); } } protected void lstCountries_SelectedIndexChanged(object sender, EventArgs e) { BindStates(); } private void BindCountries() { PortalUtils.LoadCountriesDropDownList(lstCountries, null); lstCountries.Items.Insert(0, new ListItem(GetSharedLocalizedString("ListItem.NotSpecified"), "")); } private void BindStates() { ddlStates.Visible = false; txtState.Visible = true; if (lstCountries.SelectedValue != "") { // Load states using default mechanism PortalUtils.LoadStatesDropDownList(ddlStates, lstCountries.SelectedValue); // Correct list values because no abbreviations is allowed in state name foreach (ListItem li in ddlStates.Items) { // Replace state abbreviation with its full name li.Value = li.Text; } if (ddlStates.Items.Count > 0) { ddlStates.Items.Insert(0, new ListItem(GetSharedLocalizedString("ListItem.NotSpecified"))); ddlStates.Visible = true; txtState.Visible = false; } } } private void BindListOfAvailableSslDomains(ServerBinding[] siteBindings, SSLCertificate[] siteCertificates, string websiteName = "") { lstDomains.Items.Clear(); // foreach (ServerBinding binding in siteBindings) { // if (binding.IP.ToString().Length > 0 && binding.Host.Length == 0) { lstDomains.Items.Add(new ListItem(websiteName, websiteName)); lstDomains.Items.Add(new ListItem(String.Format("www.{0}", websiteName), String.Format("www.{0}", websiteName))); } else { lstDomains.Items.Add(new ListItem(binding.Host, binding.Host)); } } } public void BindWebItem(WebVirtualDirectory item) { // var webSite = item as WebSite; // Skip processing virtual directories, otherwise we will likely run into a trouble if (webSite == null) return; // bool hasactive = false; bool haspending = false; SiteId = item.Id; // try { SSLCertificate[] certificates = ES.Services.WebServers.GetCertificatesForSite(item.Id); SSLNotInstalled.Visible = true; // BindListOfAvailableSslDomains(webSite.Bindings, certificates, webSite.Name); if (certificates.Length > 0) { foreach (SSLCertificate cert in certificates) { if (cert.Installed) { hasactive = true; } else { haspending = true; } } } // Web site has active certificate if (hasactive) { tabInstalled.Visible = true; tabInstalled.Enabled = true; tabInstalled.HeaderText = GetLocalizedString("tabInstalled.Text"); InstalledCert = (from c in certificates where c.Installed == true select c).SingleOrDefault(); // BindCertificateFields(); // Attention please, the certificate is about to expire! TimeSpan daystoexp = DateTime.Now - InstalledCert.ExpiryDate; if (daystoexp.Days < 30) { lblInstalledExpiration.ForeColor = System.Drawing.Color.Red; } // Put some data to the ViewState ViewState["SSLID"] = InstalledCert.id; ViewState["SSLSerial"] = InstalledCert.SerialNumber; // if (!haspending) { btnShowpnlCSR.Attributes.Add("OnClientClick", "return confirm('" + GetLocalizedString("btnInstallConfirm.Text") + "');"); btnShowUpload.Attributes.Add("OnClientClick", "return confirm('" + GetLocalizedString("btnInstallConfirm.Text") + "');"); SSLNotInstalledHeading.Text = GetLocalizedString("SSLInstalledNewHeading.Text"); SSLNotInstalledDescription.Text = GetLocalizedString("SSLInstalledNewDescription.Text"); } } // Web site has pending certificate if (haspending) { tabCSR.HeaderText = GetLocalizedString("tabPendingCertificate.HeaderText");//"Pending Certificate"; SSLNotInstalled.Visible = false; pnlInstallCertificate.Visible = true; SSLCertificate pending = (from c in certificates where c.Installed == false select c).Single(); ViewState["CSRID"] = pending.id; txtCSR.Text = pending.CSR; txtCSR.Attributes.Add("onfocus", "this.select();"); if (InstalledCert != null) { btnInstallCertificate.Attributes.Add("OnClientClick", "return confirm('" + GetLocalizedString("btnInstallConfirm.Text") + "');"); } } if (!hasactive && ES.Services.WebServers.CheckCertificate(item.Id).IsSuccess) { SSLNotInstalled.Visible = false; SSLImport.Visible = true; } } catch (Exception ex) { messageBox.ShowErrorMessage("WEB_GET_SSL", ex); } } protected void btnShowpnlCSR_click(object sender, EventArgs e) { SSLNotInstalled.Visible = false; pnlCSR.Visible = true; } protected void btnShowUpload_click(object sender, EventArgs e) { SSLNotInstalled.Visible = false; pnlShowUpload.Visible = true; } protected void btnCSR_Click(object sender, EventArgs e) { string domain = lstDomains.SelectedValue; // Ensure wildcard certificate request is correct if (chkWild.Checked) domain = "*." + domain; // string distinguishedName = string.Format(@"CN={0}, O={1}, OU={2}, L={3}, S={4}, C={5}", domain, txtCompany.Text, txtOU.Text, txtCity.Text, State, lstCountries.SelectedValue); SSLCertificate certificate = new SSLCertificate(); certificate.Hostname = domain; certificate.DistinguishedName = distinguishedName; certificate.CSRLength = Convert.ToInt32(lstBits.SelectedValue); certificate.Organisation = txtCompany.Text; certificate.OrganisationUnit = txtOU.Text; certificate.SiteID = PanelRequest.ItemID; certificate.State = State; certificate.City = txtCity.Text; certificate.Country = lstCountries.SelectedValue; certificate.IsRenewal = false; certificate = ES.Services.WebServers.CertificateRequest(certificate, certificate.SiteID); // Something is wrong if (certificate.CSR == "") { messageBox.ShowErrorMessage(ERROR_CSR); return; } // We are done SSLNotInstalled.Visible = false; pnlCSR.Visible = false; tabCSR.HeaderText = GetLocalizedString("tabPendingCertificate.HeaderText"); ViewState["CSRID"] = certificate.id; pnlInstallCertificate.Visible = true; txtCSR.Text = certificate.CSR; txtCSR.Attributes.Add("onfocus", "this.select();"); } protected void btnRegenCSR_Click(object sender, EventArgs e) { ResultObject result = new ResultObject { IsSuccess = true }; try { result = ES.Services.WebServers.DeleteCertificateRequest(SiteId, (int)ViewState["CSRID"]); } catch (Exception ex) { messageBox.ShowErrorMessage(WEB_SSL_DELETE, ex); } // if (!result.IsSuccess) { messageBox.ShowErrorMessage(WEB_SSL_DELETE); return; } // SSLNotInstalled.Visible = false; pnlCSR.Visible = true; pnlInstallCertificate.Visible = false; } protected void btnRenCSR_Click(object sender, EventArgs e) { // string domain = lstDomains.SelectedValue; // if (chkWild.Checked) domain = "*." + domain; // string distinguishedName = string.Format(@"CN={0}, O={1}, OU={2}, L={3}, S={4}, C={5}", domain, txtCompany.Text, txtOU.Text, txtCity.Text, State, lstCountries.SelectedValue); SSLCertificate certificate = new SSLCertificate(); certificate.Hostname = domain; certificate.DistinguishedName = distinguishedName; certificate.CSRLength = Convert.ToInt32(lstBits.SelectedValue); certificate.Organisation = txtCompany.Text; certificate.OrganisationUnit = txtOU.Text; certificate.SiteID = PanelRequest.ItemID; certificate.State = State; certificate.City = txtCity.Text; certificate.Country = lstCountries.SelectedValue; certificate.PreviousId = InstalledCert.id; certificate.IsRenewal = true; certificate = ES.Services.WebServers.CertificateRequest(certificate, certificate.SiteID); // Something is wrong if (certificate.CSR == "") { messageBox.ShowErrorMessage(WEB_GEN_CSR); return; } // pnlShowUpload.Visible = false; pnlCSR.Visible = false; ViewState["CSRID"] = certificate.id; txtCSR.Attributes.Add("onfocus", "this.select();"); RefreshControlLayout(PanelRequest.ItemID); TabContainer1.ActiveTab = TabContainer1.Tabs[0]; messageBox.ShowSuccessMessage(WEB_GEN_CSR); } protected void btnInstallCertificate_Click(object sender, EventArgs e) { InstallCertificate(PanelRequest.ItemID, txtCertificate.Text); } protected void InstallCertificate(int webSiteId, string certText) { SSLCertificate certificate = ES.Services.WebServers.GetSSLCertificateByID((int)ViewState["CSRID"]); certificate.Certificate = certText; ResultObject result = ES.Services.WebServers.InstallCertificate(certificate, webSiteId); // Check the operation status if (!result.IsSuccess) { messageBox.ShowErrorMessage("WEB_INSTALL_CSR"); return; } // messageBox.ShowSuccessMessage("WEB_INSTALL_CSR"); tabInstalled.Visible = true; tabInstalled.Enabled = true; tabInstalled.HeaderText = "Installed Certificate"; tabCSR.HeaderText = "New Certificate"; pnlInstallCertificate.Visible = false; SSLNotInstalled.Visible = true; // RefreshControlLayout(webSiteId); } protected void btnInstallPFX_Click(object sender, EventArgs e) { InstallPfxFromClient(PanelRequest.ItemID); } protected void InstallPfxFromClient(int webSiteId) { if (upPFX.HasFile.Equals(false)) { messageBox.ShowErrorMessage("WEB_SSL_NOFILE"); return; } byte[] pfx = upPFX.FileBytes; string certPassword = txtPFXInstallPassword.Text; ResultObject result = ES.Services.WebServers.InstallPfx(pfx, webSiteId, txtPFXInstallPassword.Text); // SSLCertificate certificate = ES.Services.WebServers.GetSiteCert(webSiteId); // Check the operation status if (result.IsSuccess.Equals(false)) { messageBox.ShowErrorMessage("WEB_INSTALL_CSR"); return; } // messageBox.ShowSuccessMessage("WEB_INSTALL_CSR"); SSLNotInstalled.Visible = false; tabInstalled.Visible = true; RefreshControlLayout(SiteId); } protected void BindCertificateFields() { // Decode certificate's fields Lookup dnFields = DecodeDn(InstalledCert.DistinguishedName); // Set certificate's Hostname lblInstalledDomain.Text = InstalledCert.Hostname; // Set certificate's Expiration Date lblInstalledExpiration.Text = InstalledCert.ExpiryDate.ToShortDateString(); // Set Organization lblInstalledOrganization.Text = InstalledCert.Organisation = dnFields["O"].SingleOrDefault(); // Set Organizational Unit lblInstalledOU.Text = InstalledCert.OrganisationUnit = dnFields["OU"].LastOrDefault(); // Set City lblInstalledCity.Text = InstalledCert.City = dnFields["L"].FirstOrDefault(); // Set State lblinstalledState.Text = InstalledCert.State = dnFields["S"].FirstOrDefault(); // Set Country lblInstalledCountry.Text = InstalledCert.Country = dnFields["C"].FirstOrDefault(); // Set Certificate Strength lblInstalledBits.Text = InstalledCert.CSRLength.ToString(); } public Lookup DecodeDn(string distinguisedName) { return (Lookup)new Regex(@"(\w{1,2})=([a-zA-Z0-9\.\-\s\(\)]+),*").Matches(distinguisedName).Cast().ToLookup(x => x.Groups[1].Value, x => x.Groups[2].Value); } protected void btnExport_Click(object sender, EventArgs e) { ExportCertificate(PanelRequest.ItemID, InstalledCert.Hostname, InstalledCert.SerialNumber, txtPFXPassConfirm.Text); } protected void ExportCertificate(int webSiteId, string certHostname, string certSerialNumber, string certPassword) { try { byte[] pfx = ES.Services.WebServers.ExportCertificate(webSiteId, certSerialNumber, certPassword); // modalPfxPass.Hide(); // Response.Clear(); Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}.pfx", certHostname)); Response.ContentType = "application/octet-stream"; Response.BinaryWrite(pfx); Response.End(); } catch (Exception ex) { messageBox.ShowErrorMessage(WEB_SSL_EXPORT, ex); } // messageBox.ShowSuccessMessage(WEB_SSL_EXPORT); } protected void btnDelete_Click(object sender, EventArgs e) { DeleteCertificate(PanelRequest.ItemID, InstalledCert); } protected void DeleteCertificate(int webSiteId, SSLCertificate siteCert) { ResultObject result = ES.Services.WebServers.DeleteCertificate(webSiteId, siteCert); if (!result.IsSuccess) { // Show error message messageBox.ShowErrorMessage(WEB_SSL_DELETE); return; } // Show success message messageBox.ShowSuccessMessage(WEB_SSL_DELETE); // tabInstalled.Visible = false; tabInstalled.Enabled = false; tabInstalled.HeaderText = ""; InstalledCert = null; } protected void btnRenew_Click(object sender, EventArgs e) { RenewCertificate(InstalledCert); } protected void RenewCertificate(SSLCertificate cert) { TabContainer1.ActiveTab = TabContainer1.Tabs[1]; SSLNotInstalled.Visible = false; pnlCSR.Visible = true; tabCSR.HeaderText = GetLocalizedString("SSLGenereateRenewal.HeaderText"); string hostname = cert.Hostname; // Check if it is a wildcard certificate if (!String.IsNullOrEmpty(cert.Hostname) && cert.Hostname.StartsWith("*")) { chkWild.Checked = true; hostname = hostname.Remove(0, 2); } // Assign hostname SetCertHostnameSelection(hostname); // Assign state SetCertCountrySelection(cert.Country); // Assign country SetCertStateSelection(cert.State); // Assign certificate strength MakeSafeListSelection(lstBits, cert.CSRLength.ToString()); // txtCompany.Text = cert.Organisation; txtOU.Text = lblInstalledOU.Text; txtCity.Text = cert.City; // Render button controls appropriately btnCSR.Visible = false; btnRenCSR.Visible = true; } protected void btnImport_click(object sender, EventArgs e) { ImportCertificate(PanelRequest.ItemID); } protected void ImportCertificate(int webSiteId) { // Try to importe the certificate ResultObject result = ES.Services.WebServers.ImportCertificate(webSiteId); // Display error message if (!result.IsSuccess) { messageBox.ShowErrorMessage("WEB_INSTALL_CSR"); return; } // Show success message and display appropriate controls messageBox.ShowSuccessMessage("WEB_INSTALL_CSR"); SSLNotInstalled.Visible = false; tabInstalled.Visible = true; // RefreshControlLayout(webSiteId); } protected void RefreshControlLayout(int webSiteId) { bool hasActiveCert = false; bool hasPendingCert = false; // try { SSLCertificate[] certificates = ES.Services.WebServers.GetCertificatesForSite(webSiteId); WebSite item = ES.Services.WebServers.GetWebSite(webSiteId); SSLNotInstalled.Visible = true; // BindListOfAvailableSslDomains(item.Bindings, certificates, item.Name); if (certificates.Length > 0) { foreach (SSLCertificate cert in certificates) { if (cert.Installed) { hasActiveCert = true; } else { hasPendingCert = true; } } } if (hasActiveCert) { tabInstalled.Visible = true; tabInstalled.Enabled = true; tabInstalled.HeaderText = GetLocalizedString("tabInstalled.Text"); InstalledCert = (from c in certificates where c.Installed == true select c).SingleOrDefault(); TimeSpan daystoexp = DateTime.Now - InstalledCert.ExpiryDate; BindCertificateFields(); // bool certAbout2Exp = daystoexp.Days < 30 ? lblInstalledExpiration.ForeColor == System.Drawing.Color.Red : lblInstalledExpiration.ForeColor == System.Drawing.Color.Black; ViewState["SSLID"] = InstalledCert.id; ViewState["SSLSerial"] = InstalledCert.SerialNumber; if (!hasPendingCert) { btnShowpnlCSR.Attributes.Add("OnClientClick", "return confirm('" + GetLocalizedString("btnInstallConfirm.Text") + "');"); btnShowUpload.Attributes.Add("OnClientClick", "return confirm('" + GetLocalizedString("btnInstallConfirm.Text") + "');"); SSLNotInstalledHeading.Text = GetLocalizedString("SSLInstalledNewHeading.Text"); SSLNotInstalledDescription.Text = GetLocalizedString("SSLInstalledNewDescription.Text"); } } if (hasPendingCert) { tabCSR.HeaderText = GetLocalizedString("tabPendingCertificate.HeaderText"); SSLNotInstalled.Visible = false; pnlInstallCertificate.Visible = true; SSLCertificate pending = (from c in certificates where c.Installed == false select c).Single(); ViewState["CSRID"] = pending.id; txtCSR.Text = pending.CSR; txtCSR.Attributes.Add("onfocus", "this.select();"); if (InstalledCert != null) { btnInstallCertificate.Attributes.Add("OnClientClick", "return confirm('" + GetLocalizedString("btnInstallConfirm.Text") + "');"); } } } catch (Exception ex) { messageBox.ShowErrorMessage("WEB_GET_SSL", ex); } } protected void SetCertHostnameSelection(string hostname) { //Bind new CSR with current certificate details var li = lstDomains.Items.FindByValue(hostname); // Select domain name from the existing certificate if (li != null) { lstDomains.ClearSelection(); li.Selected = true; } } protected void SetCertCountrySelection(string country) { MakeSafeListSelection(lstCountries, country); BindStates(); } protected void SetCertStateSelection(string state) { if (ddlStates.Visible) { MakeSafeListSelection(ddlStates, state); return; } // txtState.Text = state; } protected void MakeSafeListSelection(DropDownList listCtl, string valueSelected) { if (listCtl == null) return; // var li = listCtl.Items.FindByValue(valueSelected); // if (li == null) return; // listCtl.ClearSelection(); li.Selected = true; } } }