Tag Archives: certificates

Manifests and Digital Signatures for Self Extracting Scripts

It has been quite in this little corner of the blogosphere lately. Must be because I am not doing anything, right?

Wrong. I have run out of time to blog. But today I will make an exception because I need to provide an update to an old post:

As a substitute for becoming a real programmer, I have for years been writing VBScripts and wrapping them up with the Z-Zip Self-Extracting executable. After the release of Windows 8, this model became more difficult. Out-of-box, the 7-Zip self extractor started generating application compatibility troubleshooter pop-ups on clients. Even prior to that, clients would get warnings asking them “do you really want to execute this scary unsigned possibly-from-a-murdering-hacker” when they launched our executables.

The solution for this is, of course, to add an application manifest to the self-extractor, and then to digitally sign the resulting executable. Easy, right?

I actually did this a few years ago for our venerable Wi-Fi profile installation tool. It was not quite easy, and unfortunately I never did get the process fully automated. The roadblock was in automating the addition of a manifest to the application. Microsoft’s tool for this, “mt.exe”, from the Windows SDK, consistently corrupts my executables. Others in the blogosphere have identified the tool “Resource Hacker” to fill this need:

I added this tool to my ugly-old script packaging batch files, and had good success with eliminating the program compatibility dialogs:

..\bin\resource_hacker\ResourceHacker.exe -addoverwrite %fname%.exe, %fname%.exe, %fname%.manifest, 24,1,

I also was able to streamline the signing process with the following batch code:

set fname=fixThunderbirdMailboxPath
set SDKPath="C:\Program Files (x86)\Windows Kits\10\bin\x86"
set TimeStampURL="http://timestamp.verisign.com/scripts/timstamp.dll"
set /P CertPath="Enter the full path to the PKCS12/PFX signing certificate:"
set /P CertPass="Enter the password for certificate file:"
%SDKPath%\signtool.exe sign /f "%CertPath%" /p "%CertPass%" /t %TimeStampUrl% /v %fname%.exe

Configuring WiFi Profiles Using VBScript

We are in the midst of deploying a WPA2-Enterprise wireless network here at UVM.  During the testing process we have discovered that although domain-joined computers have no trouble using the network (out-of-box settings don’t work very well, but we are pushing profiles using Group Policy to make easy for our clients), stand-alone workstations need very specific WiFi settings that are not overly intuitive.

I decided to see if I could automate installation of wireless profiles using a script.  Three days later, I have the outline of something that appears to work…

Below you will find a VBScript that performs the following procedures:

  • Detects the operating system platform and Service Pack levels
  • Installs the trusted root certificate that is used by our RADIUS server if it is not already present.  The script calls the “certmgr.exe” tool, available from the Windows Platform SDK (I suppose I could have used CAPICOM, but why should I torture myself?)
  • On Windows XP, uses the free utility “zwlancfg.exe” written by ENGL to install our WPA2-Enterprise wireless profile.  The script will install the KB918997 HotFix if it is not already present.  This HotFix adds the WiFi API to Windows, allowing programmatic configuration of wireless on XP Service Pack 2 (Note: XP Service Pack 3 includes this HotFix).
    (I configured a WiFi profile on my XP laptop then used the command:
    zwlancfg.exe /export:”[profile name]”
    to generate the XML profile called by the script.
  • On Windows Vista, we call “netsh wlan import profile” to import a WiFi profile that was generated using:
    netsh wlan export profile –name:”[profile name]” –folder:”[export folder]”

No doubt there are smarter ways to do this, and essential script logic that I am missing.  I welcome your feedback and recommendations on how this script can be enhanced.  Code follows:

option explicit
'Install UVM WPA2 wireless profile
' Supported platforms:  Windows Vista and XP with Service Pack 2 or 3
' Requires external tools: "zwlancfg.exe", "CertMgr.exe" (from the Windows Platform SDK), and HotFix installer for KB918997
' Requires external files:  "IPS Servidores" root certificate file, XML configuration files for XP and Vista

' create constants
const cNetName = "wpa2"
const cLogFile = "uvm_wpa2.log"

' declare variants
dim oShell, oUserEnv, oFSO, oFile
dim iSPVer
dim sTempEnv, strComputer, sOS
dim bSuccess

'define variants
bSuccess = false
strComputer = "."

'instantiate global objects
set oShell = WScript.CreateObject("WScript.Shell")
set oFSO = CreateObject("Scripting.FileSystemObject")
sTempEnv = oShell.ExpandEnvironmentStrings("%TEMP%") & ""
set oFile = oFSO.CreateTextFile(sTempEnv & cLogFile,true)

fDetectOS sOS, iSPVer

if inStr(sOS, "Vista") > 0 then
    elseif inStr(sOS, "XP") > 0 then
        if iSPVer = 2 then
        elseif iSPVer = 3 then
            oFile.WriteLine "Your operating system is not supported for use with this script."
            WScript.Quit -4
        end if
end if


''' begin environment cleanup '''
set oFile = nothing
set oFSO = nothing
set oUserEnv = nothing
set oShell = Nothing
''''' end environment cleanup ''''

function fDetectOS(sOS, iSPVer)
'Detect OS Function - detects OS Caption string and Service Pack integer from WMI WIN32_OperatingSystem.
'Expects to varibles passed, returns the full OS Caption String, and SP Major Version intger
    'Declare variables
    dim colItems
    dim objWMIService, objItem
    'Instantiate local objects/collections
    Set objWMIService = GetObject("winmgmts:" & strComputer & "rootCIMV2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")

    For Each objItem in colItems
      sOS = objItem.Caption
      oFile.Write "Detected Operating System: " & sOS
      iSPVer = cInt(objItem.ServicePackMajorVersion)
      oFile.Write "Detected Service Pack Version: " & iSPVer
      oFile.Write "Service Pack Minor Version: " & objItem.ServicePackMinorVersion

    'Clean local objects/variables
    set objItem = nothing
    set colItems = nothing
    set objWMIService = nothing
end function

sub subImpVistaProfile
'Imports Vista Wireless Profile using NETSH command.
'Requires: a Vista wifi profile file exported using NETSH, defined in cVistaProfile within this function
    const cVistaProfile = ".uvm-wpa2-test.xml"
    const cUserScope = "all"

    dim iStrMatch
    dim oExec, oStdOut
    dim sStdOutLine

    oFile.WriteLine "Executing command: netsh wlan add profile filename=""" & cVistaProfile & """ user=" & cUserScope & ""
    set oExec = oShell.Exec("netsh wlan add profile filename=""" & cVistaProfile & """ user=" & cUserScope & "")
    set oStdOut = oExec.stdOut
    While not oStdOut.AtEndOfStream
        sStdOutLine = oStdOut.ReadLine
        iStrMatch = cInt(inStr(sStdOutLine, "Profile " & cNetName & " is added on interface"))
        if iStrMatch > 0 then
            WScript.Echo "The " & cNetName & " wireless profile was added successfully to your system"
        elseif iStrMatch = 0 then
            WScript.Echo "The wireless profile failed to import.  Please see the manual profile " _
            & "configuration instructions available at http://www.uvm.edu/ets/wireless/wpa/.  A " _
            & "log file named " & cLogFile & " which contains the full error message can be " _
            & "found in the " & sTempEnv & " directory."
            WScript.Quit -3
        End If

    set oStdOut = Nothing
    set oExec = Nothing
end sub

sub subImpXPProfile
    ' Installs an XP wifi profile using zwlancfg.exe.  Requires the HotFix KB918997 be installed on the system before running.
    ' Requires presence of xml wifi profile file defined in cXPProfile
    const cXPProfile = ".wpa2.xml"
    const cForReading = 1
    Dim oZFile
    Dim sZFile

    oFile.WriteLine "Executing command: zwlancfg.exe /import:""" & cXPProfile & """ /log"
    oShell.Run "zwlancfg.exe /import:""" & cXPProfile & """ /log", 1, true

    set oZFile = oFSO.OpenTextFile("zwlancfg.log", cForReading)
    sZFile = oZFile.ReadAll

    oFile.WriteLine "Output from zwlancfg.exe follows..."
    oFile.Write sZFile

    iStrMatch = cInt(inStr(sStdOutLine, "Profile added to interface"))
    if iStrMatch > 0 then
        bSuccess = true
        WScript.Echo "The " & cNetName & " wireless profile was added successfully to your system"
    else WScript.Echo "Import of the WPA2 profile for XP failed.  Please see the manual profile " _
        & "configuration instructions available at " _
        & "http://www.uvm.edu/ets/wireless/wpa/.  A log file named " & cLogFile & " which " _
        & "contains the full error message can be found in the " & sTempEnv & " directory."
        WScript.Quit -1
    End If
end sub

sub subXPPatch
    dim colItems
    dim objWMIService, objItem
    dim iRC
    dim sHFOut
    dim bHFPresent

    bHFPresent = false

    Set objWMIService = GetObject("winmgmts:" & strComputer & "rootCIMV2")
    Set colItems = objWMIService.ExecQuery( _
        "SELECT * FROM Win32_QuickFixEngineering",,48)
    For Each objItem in colItems
        sHFOut = objItem.HotFixID
        if sHFOut = cHotFixID then
            bHFPresent = True
        end if
    oFile.WriteLine "QFE HotFix ID " & cHotFixID & " is present: " & bHFPresent
    if bHFPresent = false then
        oFile.WriteLine "We now will attempt to install QFE HotFix 918997."
        iRC = oShell.Run("WindowsXP-KB918997-v6-x86-ENU.exe /passive /noreboot", 1, true)
        oFile.WriteLine "Return code from HotFix installer: " & iRC
            WScript.Echo "A patch to your operating system was required to enable Wireless " _
            & "access to the UVM network.  The patch was applied successfully.  Please reboot " _
            & "your system and run this script again to complete Wireless configuration."
        else WScript.Echo "Application of the required XP HotFix " & cHotFixID & " " _
            & "failed.  Please see the manual profile configuration instructions available at " _
            & "http://www.uvm.edu/ets/wireless/wpa/.  A log file named " & cLogFile & " which " _
            & "contains the full error message can be found in the " & sTempEnv & " directory."
            WScript.Quit -1
        end if
    end if

    set objItem = nothing
    set colItems = nothing
    set objWMIService = nothing
end sub

sub subInstCert
    'const cRootName = "IPS SERVIDORES"
    'dim oAllCerts, oCert
    'set colCerts = oCerts.Find(CAPICOM_CERTIFICATE_FIND_ROOT_NAME, cRootName, true)
    dim iRC
    iRC = oShell.Run("certmgr.exe -c -s -r localMachine root | find ""IPS SERVIDORES""", 1, true)
    if iRC = -1 then
        oFile.WriteLine "Root Certificate for IPS_SERVIDORES needs to be installed.  Attempting install..."
        iRC = oShell.Run("certmgr.exe -add -c IPS_SERVIDORES.cer -s -r localMachine root", 1, true)
        if iRC = 0 then
            oFile.WriteLine "Certificate installed successfully"
            WScript.Echo "Certificate failed to install... You will need to install the " _
            & "certificate manually.  See the instructions at https://www.uvm.edu/ets/wireless/wpa2 " _
            & ", then run this script again to compelte installation of the UVM wireless profile."
            WScript.Quit -2
        end if
        oFile.WriteLine "Root Certificate for ""IPS SERVIDORES"" is already installed."
    end if
end sub