Skip to content

Commit

Permalink
Allow Resource AppDomains to shutdown cleanly.
Browse files Browse the repository at this point in the history
When the Bridge exits, it now explicitly shuts down
all AppDomains created for its resources.  This allows
them to release the certificates and ports they acquired.

Without this fix, the certs remain in the cert store and
netsh shows the https SSL cert is still assigned to the
https tests' port.
  • Loading branch information
roncain committed Aug 28, 2015
1 parent 56ece9d commit 87ddfcb
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using WcfTestBridgeCommon;

Expand Down Expand Up @@ -59,6 +60,14 @@ public static string CreateAppDomain(string path)
return friendlyName;
}

public static void ShutdownAllAppDomains()
{
foreach (string domainName in TypeCache.AppDomains.Keys.ToArray())
{
ShutdownAppDomain(domainName);
}
}

public static void ShutdownAppDomain(string appDomainName)
{
if (String.IsNullOrWhiteSpace(appDomainName))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ public HttpResponseMessage Delete(HttpRequestMessage request)

public static void ReleaseAllResources()
{
// Cleanly shutdown all AppDomains we own so they have
// the chance to release resources they've acquired or installed
AppDomainManager.ShutdownAllAppDomains();

// Force the removal of the SSL cert that may have been added
// by another AppDomain or left from a prior run
int httpsPort = ConfigController.BridgeConfiguration.BridgeHttpsPort;
if (httpsPort != 0)
{
CertificateManager.UninstallSslPortCertificate(httpsPort);
}

CertificateManager.UninstallAllCertificates();
PortManager.RemoveAllBridgeFirewallRules();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ public class AssemblyLoader : MarshalByRefObject
{
private const string TypeList = "TypeList";

public AssemblyLoader()
{
AppDomain.CurrentDomain.DomainUnload += (s, e) =>
{
// Uninstall all certificates we explicitly added within this AppDomain
CertificateManager.UninstallAllSslPortCertificates();
CertificateManager.UninstallAllMyCertificates();
CertificateManager.UninstallAllRootCertificates();
};
}

public List<string> GetTypes()
{
return (AppDomain.CurrentDomain.GetData(TypeList) as Dictionary<string, Type>).Keys.ToList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public static string InstallMyCertificate(BridgeConfiguration configuration, str
}
}

private static void UninstallAllRootCertificates()
public static void UninstallAllRootCertificates()
{
lock (s_certificateLock)
{
Expand All @@ -179,7 +179,7 @@ private static void UninstallAllRootCertificates()
}
}

private static void UninstallAllMyCertificates()
public static void UninstallAllMyCertificates()
{
lock (s_certificateLock)
{
Expand Down Expand Up @@ -237,41 +237,62 @@ public static void InstallSSLPortCertificate(string certThumbprint, int port)
{
process.WaitForExit();
Console.WriteLine("Process exit code was {0}", process.ExitCode);
Console.WriteLine("stdout was: {0}", process.StandardOutput.ReadToEnd());
Console.WriteLine("stderr was: {0}", process.StandardError.ReadToEnd());
string output = process.StandardOutput.ReadToEnd();
if (!String.IsNullOrWhiteSpace(output))
{
Console.WriteLine("stdout was: {0}", output);
}

output = process.StandardError.ReadToEnd();
if (!String.IsNullOrWhiteSpace(output))
{
Console.WriteLine("stderr was: {0}", output);
}
}

s_sslPorts[port] = certThumbprint;
}
}

private static void UninstallAllSslPortCertificates()
public static void UninstallAllSslPortCertificates()
{
foreach (int port in s_sslPorts.Keys.ToArray())
{
UninstallSslPortCertificate(port);
}
}

private static void UninstallSslPortCertificate(int port)
public static void UninstallSslPortCertificate(int port)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = String.Format("http delete sslcert ipport=0.0.0.0:{0}",
port);
startInfo.FileName = "netsh";
Console.WriteLine("Executing: {0} {1}", startInfo.FileName, startInfo.Arguments);
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
using (Process process = Process.Start(startInfo))
lock (s_certificateLock)
{
process.WaitForExit();
Console.WriteLine("Process exit code was {0}", process.ExitCode);
Console.WriteLine("stdout was: {0}", process.StandardOutput.ReadToEnd());
Console.WriteLine("stderr was: {0}", process.StandardError.ReadToEnd());
}
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = String.Format("http delete sslcert ipport=0.0.0.0:{0}",
port);
startInfo.FileName = "netsh";
Console.WriteLine("Executing: {0} {1}", startInfo.FileName, startInfo.Arguments);
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
using (Process process = Process.Start(startInfo))
{
process.WaitForExit();
Console.WriteLine("Process exit code was {0}", process.ExitCode);
string output = process.StandardOutput.ReadToEnd();
if (!String.IsNullOrWhiteSpace(output))
{
Console.WriteLine("stdout was: {0}", output);
}

output = process.StandardError.ReadToEnd();
if (!String.IsNullOrWhiteSpace(output))
{
Console.WriteLine("stderr was: {0}", output);
}
}

s_sslPorts.Remove(port);
s_sslPorts.Remove(port);
}
}
}
}

0 comments on commit 87ddfcb

Please sign in to comment.