mike-obrien.net Curriculum Vitae Blog Labs
Thursday, September 04, 2008

Recently I had the need to setup multiple SSL enabled sites on my local machine for development. These sites all had the same root domain but differed by sub domain. Traditionally you need to have a certificate and an IP address per SSL binding because of a "chicken or the egg" problem resolving the host headers in an encrypted HTTP conversation. If you have multiple sites with a common root domain that require SSL you can get around this limitation by using a wildcard certificate for all those sites.

So first I setup mappings in my hosts file (<SystemRoot>\System32\drivers\etc\hosts) as follows:

# SomeSite Dev Mappings
127.0.0.1          www.dev.somesite.net
127.0.0.1     services.dev.somesite.net
127.0.0.1        admin.dev.somesite.net


Next I need to create a self signed wildcard certificate. If you tried the self signed cert "feature" in IIS7 you probably quickly discovered that it is pretty much worthless since you cannot define the common name (CN), it's automatically set to the host name (Why does MS have a habit of giving you a powerful, feature rich car that can only make right turns?). One way to get around this is to generate your self signed cert with a tool and add it to the local machine store. IIS6 ships with a util called selfssl but this requires you to install the IIS6 ResKit (See more about that here). While this works, it bothers me to install tools from a previous version of IIS to accomplish this. Shouldn't the newer version of IIS do more than it's predecessor? One other alternative I found on the internets is to use the certificate creation tool that ships with the .NET 2.0 SDK. For some reason this "feels" better than using a tool from IIS6, probably just a mental thing... Plus you probably already have the SDK installed and are using it.

First create the self signed issuer certificate which will be set as a root cert authority (Fill in the red items):

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\makecert.exe" -n "CN=My Company Development Root CA,O=My Company,OU=Development,L=Wallkill,S=NY,C=US" -pe -ss Root -sr LocalMachine -sky exchange -m 120 -a sha1 -len 2048 -r

Next create a cert for your sites that is issued from this authority. You must specify the common name (CN=<IssuerName>) you entered above in the issuer name field below (-in <IssuerName>). Also I'm creating a wildcard certificate that will serve all sites with the dev.somesite.net root domain as this is a requirement to use host headers. If I add other sites in the future with a different subdomain I can choose this certificate and all is good. Specifying an asterisk as the subdomain will signify this (Fill in the red items):

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\makecert.exe" -n "CN=*.dev.somesite.net" -pe -ss My -sr LocalMachine -sky exchange -m 120 -in "My Company Development Root CA" -is Root -ir LocalMachine -a sha1 -eku 1.3.6.1.5.5.7.3.1

You should now see this cert show up in the IIS manager on the "Server Certificates" page:

image

Now again, MS gets you part of the way there in the UI but not all the way. As in IIS6 (SP1+) you cannot specify a host header for SSL bindings in the IIS7 UI because of, as mentioned above, issues with resolving the host headers in an encrypted HTTP request. But since we are using a wildcard certificate these issues are moot and IIS can do it but we have to configure it through the command line with the new appcmd util. The following command must be executed on each site that requires SSL. This command will create the SSL binding and set the host header. Make sure you specify the correct site name and host header for each site (In red):

C:\Windows\System32\inetsrv\appcmd set site /site.name:MySite /+bindings.[protocol='https',bindingInformation='*:443:www.dev.somesite.net']

Next go to the site bindings and you'll now see an SSL binding with a host header defined (Before this field would be disabled for SSL). You will need to select the the wildcard certificate you created earlier in the cert drop down and save your changes.

image

.NET 2.0 | IIS 7 | SSL
Thursday, September 04, 2008 7:47:54 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Thursday, June 19, 2008

I never realized this but you can set the default SMTP information in the .config file (Thanks Viktar!). This applies to the new System.Net.Mail.* classes (Not the deprecated System.Web.Mail.* classes). MSDN defines the elements here and here.

<configuration>
  <system.net>
    <mailSettings>
      <smtp deliveryMethod="network" 
         from="appointments@TrepanationNation.com"> <network host="smtp.TrepanationNation.com"
         port="25" defaultCredentials="true"/> </smtp> </mailSettings> </system.net>

The code is the same but you no longer have to specify the from and SMTP server details:

using (MailMessage message = new MailMessage())
{
    message.IsBodyHtml = true;
    message.To.Add("someguy@someserver.com");
    message.Subject = "Trepanation Appointment";
    message.Body = @"<b>This confirms your 
        Trepanation appointment this Friday.</b>";
    SmtpClient mailClient = new SmtpClient();
    mailClient.Send(message);
}
.NET 2.0 | C# | SMTP
Thursday, June 19, 2008 2:56:35 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Tuesday, October 09, 2007

I love WiX, but I hate that you have to specify the id's and short filenames! This really slows you down when you have a lot of files to add. I have read that these may be optional in v3 and auto generated by the compiler. Until then you could use this Visual Studio addin that that allows you to randomly generate and insert id's and short filenames as well as insert some common tags with the aformentioned attributes randomly filled in. n-joy!

Visual Studio 2005

Installer: WiXHelperAddin.EXE (217.21 KB)
Source: WiXHelperSource.zip (258.91 KB)

Visual Studio 2008

Installer: WiXHelperAddin2008.EXE (217 KB)
Source: WiXHelperSource2008.zip (63.89 KB)

PS: Also, check out the GUID inserter (Which also appears in the image below...); this is very helpful for WiX development!

image

Tuesday, October 09, 2007 1:41:54 AM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Tuesday, August 21, 2007

Attached is the source for a simple TCP proxy server. I whipped it up pretty quickly so it probably needs some refactoring if you plan to use it in production. The server class is loosely based on the Cassini implementation. You can set the listen port and forward host/port in the app config:

<configuration>

    <appSettings>

        <add key="listenPort" value="443"/>

        <add key="forwardHost" value="wush.net"/>

        <add key="forwardPort" value="443"/>

    </appSettings>

</configuration>

image

TCPProxy.zip (24.81 KB)
Tuesday, August 21, 2007 5:42:09 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Monday, July 16, 2007

The Stopwatch Class, another great .NET 2.0 feature I keep forgetting to use so I'll blog about it (And hopefully I'll remember ;)... This is a great class for performance monitoring, instead of declaring a start time and subtracting it from the end time, etc. The following snippet checks the performance difference in doing a square root and a tangent over a number of iterations. Internally, when the stopwatch is started, the ticks of the current time are set as the start timestamp. When it is stopped the start ticks and end ticks (Current time) are subtracted and the private elapsed time field (A Long) is updated. The elapsed field is only reset when you explicitly call Reset() as it is accumulative. The public Elapsed property conveniently returns a TimeSpan.

int iterations = 10000000;

 

Stopwatch stopwatch = new Stopwatch();

stopwatch.Start();

 

// Do something...

for (int index = 0; index < iterations; index++)

{ Math.Sqrt(index); }

 

stopwatch.Stop();

 

Console.WriteLine(string.Format("Square root took {0} " +

    "milliseconds for {1} iterations.",

    stopwatch.Elapsed.Milliseconds, iterations));

 

// Do something else...

stopwatch.Reset();

stopwatch.Start();

 

for (int index = 0; index < iterations; index++)

{ Math.Tan(index); }

 

stopwatch.Stop();

 

Console.WriteLine(string.Format(@"Tangent took {0} " +

    "milliseconds for {1} iterations.",

    stopwatch.Elapsed.Milliseconds, iterations));

 

Console.ReadKey();

Monday, July 16, 2007 4:19:51 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  |