Skip to content

Commit

Permalink
Merge pull request #365 from david-poindexter/ssl-support
Browse files Browse the repository at this point in the history
Implement support for enabling SSL
  • Loading branch information
valadas committed Feb 6, 2023
2 parents b336b52 + 4dbc448 commit 581205d
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 14 deletions.
54 changes: 52 additions & 2 deletions nvQuickSite/Controllers/IISController.cs
Expand Up @@ -22,6 +22,7 @@ namespace nvQuickSite.Controllers
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;

using Microsoft.Web.Administration;
using nvQuickSite.Controllers.Exceptions;
Expand All @@ -39,7 +40,8 @@ public static class IISController
/// <param name="installFolder">The path to the hosting folder for the site.</param>
/// <param name="useSiteSpecificAppPool">A value indicating whether to use a site specific App Pool.</param>
/// <param name="deleteSiteIfExists">If true will delete and recreate the site.</param>
internal static void CreateSite(string siteName, string installFolder, bool useSiteSpecificAppPool, bool deleteSiteIfExists)
/// <param name="certificate">The certificate to use for the site.</param>
internal static void CreateSite(string siteName, string installFolder, bool useSiteSpecificAppPool, bool deleteSiteIfExists, X509Certificate2 certificate = null)
{
Log.Logger.Information("Creating site {siteName} in {installFolder}", siteName, installFolder);
if (SiteExists(siteName, deleteSiteIfExists))
Expand All @@ -51,10 +53,18 @@ internal static void CreateSite(string siteName, string installFolder, bool useS
try
{
var bindingInfo = "*:80:" + siteName;
var protocol = "http";

using (ServerManager iisManager = new ServerManager())
{
Site site = iisManager.Sites.Add(siteName, "http", bindingInfo, installFolder + "\\Website");
Site site = iisManager.Sites.Add(siteName, protocol, bindingInfo, installFolder + "\\Website");
if (certificate != null)
{
bindingInfo = "*:443:" + siteName;
protocol = "https";
}

site.Bindings.Add(bindingInfo, protocol);
site.TraceFailedRequestsLogging.Enabled = true;
site.TraceFailedRequestsLogging.Directory = installFolder + "\\Logs";
site.LogFile.Directory = installFolder + "\\Logs" + "\\W3svc" + site.Id.ToString(CultureInfo.InvariantCulture);
Expand Down Expand Up @@ -152,6 +162,46 @@ internal static void DeleteAppPool(string appPoolName, IProgress<int> progress)
}
}

/// <summary>
/// Gets a list of SSL certificates available for use within IIS.
/// </summary>
/// <returns>An enumeration of SSL certificates.</returns>
internal static List<X509Certificate2> GetSslCertificates()
{
Log.Logger.Information("Getting a list of SSL certificates");
var certificates = new List<X509Certificate2>();

var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
try
{
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

foreach (var certificate in store.Certificates)
{
foreach (var extension in certificate.Extensions)
{
if (extension.Oid.FriendlyName == "Enhanced Key Usage" && extension is X509EnhancedKeyUsageExtension enhancedKeyUsageExtension)
{
foreach (var item in enhancedKeyUsageExtension.EnhancedKeyUsages)
{
if (item.FriendlyName == "Server Authentication")
{
certificates.Add(certificate);
}
}
}
}
}

Log.Logger.Debug("Found the following SSL certificates {@certicates}", certificates);
return certificates;
}
finally
{
store.Close();
}
}

/// <summary>
/// Gets a list of IIS sites.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions nvQuickSite/Properties/AssemblyInfo.cs
Expand Up @@ -49,6 +49,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.2.0")]
[assembly: AssemblyFileVersion("2.2.0")]
[assembly: AssemblyVersion("2.3.0")]
[assembly: AssemblyFileVersion("2.3.0")]
[assembly: NeutralResourcesLanguage("en")]
26 changes: 25 additions & 1 deletion nvQuickSite/Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions nvQuickSite/Properties/Settings.settings
Expand Up @@ -47,5 +47,11 @@
<Setting Name="EnableLocalPackageInstall" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="EnableSsl" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="CertificateFriendlyName" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>
34 changes: 31 additions & 3 deletions nvQuickSite/Start.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 43 additions & 2 deletions nvQuickSite/Start.cs
Expand Up @@ -26,6 +26,7 @@ namespace nvQuickSite
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;

using Ionic.Zip;
Expand All @@ -52,6 +53,7 @@ public partial class Start : MetroUserControl
private long total;
private long lastVal;
private long sum;
private List<X509Certificate2> certificates;

/// <summary>
/// Initializes a new instance of the <see cref="Start"/> class.
Expand Down Expand Up @@ -128,6 +130,12 @@ private void ReadUserSettings()
this.txtSiteNameSuffix.Text = Properties.Settings.Default.SiteNameSuffixRecent;
this.chkSiteSpecificAppPool.Checked = Properties.Settings.Default.AppPoolRecent;
this.chkDeleteSiteIfExists.Checked = Properties.Settings.Default.DeleteSiteInIISRecent;
this.chkEnableSsl.Checked = Properties.Settings.Default.EnableSsl;
if (Properties.Settings.Default.CertificateFriendlyName != string.Empty)
{
this.cboCertificates.SelectedItem = Properties.Settings.Default.CertificateFriendlyName;
}

this.txtInstallBaseFolder.Text = Properties.Settings.Default.InstallBaseFolderRecent;

this.txtDBServerName.Text = Properties.Settings.Default.DatabaseServerNameRecent;
Expand All @@ -144,6 +152,12 @@ private void SaveUserSettings()
Properties.Settings.Default.SiteNameSuffixRecent = this.txtSiteNameSuffix.Text;
Properties.Settings.Default.AppPoolRecent = this.chkSiteSpecificAppPool.Checked;
Properties.Settings.Default.DeleteSiteInIISRecent = this.chkDeleteSiteIfExists.Checked;
Properties.Settings.Default.EnableSsl = this.chkEnableSsl.Checked;
if (this.cboCertificates.SelectedItem != null)
{
Properties.Settings.Default.CertificateFriendlyName = this.cboCertificates.SelectedItem.ToString();
}

Properties.Settings.Default.InstallBaseFolderRecent = this.txtInstallBaseFolder.Text;

Properties.Settings.Default.DatabaseServerNameRecent = this.txtDBServerName.Text;
Expand Down Expand Up @@ -412,6 +426,31 @@ private void txtSiteNamePrefix_TextChanged(object sender, EventArgs e)
this.txtDBName.Text = this.txtSiteNamePrefix.Text;
}

private void chkEnableSsl_CheckedChanged(object sender, EventArgs e)
{
this.cboCertificates.Visible = false;
if (this.chkEnableSsl.Checked)
{
this.LoadSslCertificates();
this.cboCertificates.Visible = true;
}
}

private void LoadSslCertificates()
{
this.cboCertificates.Items.Clear();
this.certificates = IISController.GetSslCertificates();
this.certificates.ForEach(c => this.cboCertificates.Items.Add(c.FriendlyName != string.Empty ? c.FriendlyName : c.Subject.Split(',')[0].Split('=')[1]));
if (this.cboCertificates.Items.Count > 0)
{
this.cboCertificates.SelectedIndex = 0;
if (Properties.Settings.Default.CertificateFriendlyName != string.Empty)
{
this.cboCertificates.SelectedItem = Properties.Settings.Default.CertificateFriendlyName;
}
}
}

private void btnSiteInfoNext_Click(object sender, EventArgs e)
{
bool proceed;
Expand Down Expand Up @@ -549,7 +588,8 @@ private void btnDatabaseInfoNext_Click(object sender, EventArgs e)
this.SiteName,
this.InstallFolder,
this.chkSiteSpecificAppPool.Checked,
this.chkDeleteSiteIfExists.Checked);
this.chkDeleteSiteIfExists.Checked,
this.certificates[this.cboCertificates.SelectedIndex]);

FileSystemController.UpdateHostsFile(this.SiteName);

Expand Down Expand Up @@ -668,7 +708,8 @@ private void myZip_ExtractProgress(object sender, ExtractProgressEventArgs e)

private void btnVisitSite_Click(object sender, EventArgs e)
{
var url = "http://" + this.SiteName;
var protocol = this.chkEnableSsl.Checked ? "https://" : "http://";
var url = protocol + this.SiteName;
Log.Logger.Information("Visiting {url}", url);
Process.Start(url);
Log.Logger.Information("Closing application");
Expand Down
8 changes: 7 additions & 1 deletion nvQuickSite/app.config
Expand Up @@ -52,14 +52,20 @@
<setting name="EnableLocalPackageInstall" serializeAs="String">
<value>False</value>
</setting>
<setting name="EnableSsl" serializeAs="String">
<value>False</value>
</setting>
<setting name="CertificateFriendlyName" serializeAs="String">
<value />
</setting>
</nvQuickSite.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Expand Down
2 changes: 1 addition & 1 deletion nvQuickSite/data/latestVersion.json
@@ -1,3 +1,3 @@
{
"latestVersion": "2.2.0"
"latestVersion": "2.3.0"
}
4 changes: 2 additions & 2 deletions nvQuickSite/nvQuickSite.csproj
Expand Up @@ -2,7 +2,7 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3D661BAD-45EB-4524-9650-78805CD31682}</ProjectGuid>
Expand Down Expand Up @@ -279,7 +279,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.1</Version>
<Version>13.0.2</Version>
</PackageReference>
<PackageReference Include="Octokit">
<Version>0.32.0</Version>
Expand Down

0 comments on commit 581205d

Please sign in to comment.