We have been doing a lot of work lately with Wix, one of the things that we have been trying to do is to have the setup program encrypt the connection string section of our web.config.    Normally you can use ASPNETREG_IIS to encrypt the connection string section.   In Wix you can achieve the same thing using <CustomActions>.    Let me walk you through the steps.

First thing that you need to do is to find the location of the ASPNET_REGIIS executable.  This can be done using the DirectorySearch element.

<Property Id="FRAMEWORKBASEPATH">

<RegistrySearch Id="FindFrameworkDir" Root="HKLM"  Key="SOFTWARE\Microsoft\.NETFramework"  Name="InstallRoot" Type="raw" >

</RegistrySearch>

</Property><Property Id="ASPNETREGIIS" >

<DirectorySearch Path="[FRAMEWORKBASEPATH]" Depth="4" Id="FindAspNetRegIis">

<FileSearch Name="aspnet_regiis.exe" MinVersion="2.0.5" />

</DirectorySearch>

</Property>

Next you need to create your CustomActions.   When securing a config file the first thing you need to is to create a key container.  This can be done using the following CustomAction

<CustomAction Id='CREATE_RSA_CONTAINER'

                    ExeCommand="[ASPNETREGIIS] -pc "PUT-YOUR-KEY-CONTAINER-HERE" -exp"

                    Return='check'

                    Directory='INSTALLDIR'

                    />

Next CustomAction required is to give the user running you application pool access to the key container.   For this command you need to also specify the user that is running you website.

<CustomAction Id='CREATE_RSA_PERMISSION'

                    ExeCommand='[ASPNETREGIIS] -pa "PUT-YOUR-KEY-CONTAINTER-HERE"

 		     "[USER-DOMAIN]\[USER-NAME]"'

                    Return='check'

                    Directory='INSTALLDIR'/>  

Once the user has permission to the key container, the final step is to encrypt the config file. This is done by the following command.

 <CustomAction Id='ENCRYPT_CONFIG'

                    ExeCommand='[ASPNETREGIIS] -pef "connectionStrings" "[WEBINSTDIR]" -prov "RSAEncryptionProvider"'

                    Return='check'

                    Directory='INSTALLDIR'

                    />

For the eagle eyed, you will notice that their is a new property being used called WEBINSTDIR the ASPNET_REGIIS command requires you to specify the directory of where the location of the web config is. Unfortunately, you cannot use the INSTALLDIR because the command requires that the directory be specified without a trailing slash which the INSTALLDIR has.  To get around this I used another directory search<Property Id="WEBINSTDIR" >

        <DirectorySearch Path="[INSTALLDIR]" Depth="0" Id="FindInstallDirectory">

          <FileSearch Name="web.config"/>

        </DirectorySearch>

</Property>  

This allowed me to get the directory of where the web.config file was located.    The final step that is required is to add the CustomActions to the InstallExecuteSequence

       <InstallExecuteSequence>

        <Custom Action="CREATE_RSA_CONTAINER" After="InstallFiles" >NOT Installed </Custom>

        <Custom Action="REMOVE_RSA_CONTAINER" After="RemoveFiles">Installed</Custom>

        <Custom Action="CREATE_RSA_PERMISSION" After="CREATE_RSA_CONTAINER" >NOT Installed </Custom>

        <Custom Action="ENCRYPT_CONFIG" After="CREATE_RSA_PERMISSION" >NOT Installed AND ENCRYPTCONFIGVALUE = 1</Custom>

      </InstallExecuteSequence>

This install sequence will install the containers.   To allow for the config file to be not encrypted I have also added a property called ENCRYPTCONFIGVALUE.  In addition to this when an uninstall is run we need to the ability to remove the container which we created that can be done using this CustomAction

      <CustomAction Id='REMOVE_RSA_CONTAINER'

                    ExeCommand="[ASPNETREGIIS] -pz "PUT-YOUR-KEY-CONTAINER-HERE""

                    Return='check'

                    Directory='INSTALLDIR'

                    />

And that is it! It needs a bit more testing to ensure that it works in all scenarios

About these ads