We've had quite a bit of hands on experience with this sort of thing lately.
In one project, we bound a certificate to a port during the install so that
we could use SSL (the same as if you were to go into IIS and set the binding
and choose a certificate). In another case, we used ws-security in the
web.config by altering the XML at install time. Here I'll just talk about
the former -- simply binding a certificate to a port.

To get a port to communicate over SSL, you have to bind a certificate to
that port. The *netsh* command-line utility works nicely for this. Given an
IP, port and thumbprint of the certificate you want to use, it can bind that
certificate to the port.

I use the following .cmd script, passing in the necessary thumbprint (which
I call "CERTHASH"), and IP and port to bind to.
*
@ECHO OFF
REM Sets the certificate for for the port where the WCF runs
REM Note that we get the appid values from the GUIDs in the AssemblyInfo.cs
files for the WCF

REM Dev cert hash example: d4675cce6b8e85678826c3d426dd213ce4731e5d

SET CERTHASH=%1
SET IP=%2
SET PORT=%3

ECHO Binding certificate to port %port%

REM Bind the certificate to the WCF port
netsh http add sslcert ipport=%IP%:%PORT% certhash=%CERTHASH%
appid={01C40DD4-FF57-445F-BEDA-06E473DE8589}

ECHO Done.

@ECHO ON*

The appId comes from the Properties\AssemblyInfo.cs file, where I use the
[assembly: Guid ...]. The netsh documentation is actually kind of vague
about this, so I probably could have used any GUID. Oh well. 

I've also got a similar "rollback" script:

*@ECHO OFF

SET IP=%1
SET PORT=%2

ECHO Deleting certificate from port binding for port %PORT%

netsh http delete sslcert ipport=%IP%:%PORT%

ECHO Done.

@ECHO ON*

I install these two shell scripts along with my application. Here are the
components I use:


<Component Id="CMP_BindCertToPortCMD"
                       Guid="30B2D226-03C6-4230-9988-9977889BA8AC">
                <File Id="FILE_BindCertToPortCMD"
                      Source="$(var.sourceDir)bind_cert_to_port.cmd"
                      KeyPath="yes" />
</Component>

<Component Id="CMP_DeleteCertFromPortCMD"
                       Guid="BC5F4999-2B17-420F-84E9-D4768B8A02A0">
                <File Id="FILE_DeleteCertFromPortCMD"
                      Source="$(var.sourceDir)delete_cert_from_port.cmd"
                      KeyPath="yes" />
</Component>

I set up some custom actions:


<CustomAction Id="CA_BindCertToPort"
                      Directory="SystemFolder"
                      Impersonate="yes"
                      Execute="deferred"
                      ExeCommand="[SystemFolder]cmd.exe /C
&quot;[meCCServiceDir]bind_cert_to_port.cmd [WCF_PORT_CERT_THUMBPRINT]
[ASMX_WEBSITE_IP] [WCF_PORT]&quot;"
                      Return="check" />


<CustomAction Id="CA_RollbackBindCertToPort"
                      Directory="SystemFolder"
                      Impersonate="yes"
                      Execute="rollback"
                      ExeCommand="[SystemFolder]cmd.exe /C
&quot;[meCCServiceDir]delete_cert_from_port.cmd [ASMX_WEBSITE_IP]
[WCF_PORT]&quot;"
                      Return="ignore" />

<CustomAction Id="CA_UninstallBindCertToPort"
                      Directory="SystemFolder"
                      Impersonate="yes"
                      Execute="deferred"
                      ExeCommand="[SystemFolder]cmd.exe /C
&quot;[meCCServiceDir]delete_cert_from_port.cmd [ASMX_WEBSITE_IP]
[WCF_PORT]&quot;"
                      Return="ignore" />

And then I schedule them:

<InstallExecuteSequence>
           
           <Custom Action="CA_FindIpsForDnsEntries"
After="InstallInitialize">1</Custom>
           <Custom Action="CA_SetWcfPortFromRegistry"
After="CA_SetAsmxDnsFromRegistry">REMOVE="ALL"</Custom>
           
           
*           <Custom Action="CA_RollbackBindCertToPort"
Before="CA_BindCertToPort">NOT Installed</Custom>
           <Custom Action="CA_BindCertToPort" Before="InstallServices">NOT
Installed</Custom>
           <Custom Action="CA_UninstallBindCertToPort"
Before="RemoveFiles">REMOVE="ALL"</Custom>*
</InstallExecuteSequence>


Notice that I also used another custom action to get the IP address based on
the DNS of the website (I used C# for that) and one to get the port I'd
bound to, if this is happening during an uninstall, from the registry. That
way, I would have the port again, even though the user didn't enter them
into a UI.

If you're going the ws-security route, that's another thing. I'm saying a
lot of stuff here. The main thing is just to use netsh to bind the
certificate to the port and presto you're ready for HTTPS. We even use this
to have SSL over a port other than 443.

--
View this message in context: 
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Installing-https-WCF-Webservices-tp6641855p6645377.html
Sent from the wix-users mailing list archive at Nabble.com.

------------------------------------------------------------------------------
BlackBerry&reg; DevCon Americas, Oct. 18-20, San Francisco, CA
The must-attend event for mobile developers. Connect with experts. 
Get tools for creating Super Apps. See the latest technologies.
Sessions, hands-on labs, demos & much more. Register early & save!
http://p.sf.net/sfu/rim-blackberry-1
_______________________________________________
WiX-users mailing list
WiX-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wix-users

Reply via email to