aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Arnson <bob@firegiant.com>2025-02-17 22:30:31 -0500
committerBob Arnson <bob@firegiant.com>2025-02-25 17:17:56 -0500
commit085ba380e7991013c6bb6dce48dc89f02eca4808 (patch)
tree7b27ad1e329277c204dee8c5c72451d475727630
parent1be4e0930eb296f44b8cecd10fc9632a867149ce (diff)
downloadwix-bob/HttpNonSniSslCerts.tar.gz
wix-bob/HttpNonSniSslCerts.tar.bz2
wix-bob/HttpNonSniSslCerts.zip
Support non-SNI SSL certificates in Http extensionbob/HttpNonSniSslCerts
Implements https://github.com/wixtoolset/issues/issues/7622
-rw-r--r--src/ext/Http/ca/httpca.vcxproj13
-rw-r--r--src/ext/Http/ca/httpca.vcxproj.filters3
-rw-r--r--src/ext/Http/ca/httpcerts.cpp (renamed from src/ext/Http/ca/snisslcert.cpp)656
-rw-r--r--src/ext/Http/ca/precomp.h6
-rw-r--r--src/ext/Http/ca/wixhttpca.def6
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs36
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs12
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.en-us.wxl (renamed from src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl)0
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.wxs (renamed from src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs)2
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/PackageComponents.wxs17
-rw-r--r--src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/example.txt (renamed from src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt)0
-rw-r--r--src/ext/Http/wixext/HttpCompiler.cs31
-rw-r--r--src/ext/Http/wixext/HttpTableDefinitions.cs13
-rw-r--r--src/ext/Http/wixext/Symbols/CertificateType.cs13
-rw-r--r--src/ext/Http/wixext/Symbols/HttpCertificateSymbol.cs103
-rw-r--r--src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs6
-rw-r--r--src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs95
-rw-r--r--src/ext/Http/wixlib/HttpExtension_Platform.wxi52
-rw-r--r--src/ext/Http/wixlib/en-us.wxl12
19 files changed, 672 insertions, 404 deletions
diff --git a/src/ext/Http/ca/httpca.vcxproj b/src/ext/Http/ca/httpca.vcxproj
index 42acd85d..73ded72e 100644
--- a/src/ext/Http/ca/httpca.vcxproj
+++ b/src/ext/Http/ca/httpca.vcxproj
@@ -1,6 +1,5 @@
1<?xml version="1.0" encoding="utf-8"?> 1<?xml version="1.0" encoding="utf-8"?>
2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> 2<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
3
4<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <ItemGroup Label="ProjectConfigurations"> 4 <ItemGroup Label="ProjectConfigurations">
6 <ProjectConfiguration Include="Debug|Win32"> 5 <ProjectConfiguration Include="Debug|Win32">
@@ -28,7 +27,6 @@
28 <Platform>ARM64</Platform> 27 <Platform>ARM64</Platform>
29 </ProjectConfiguration> 28 </ProjectConfiguration>
30 </ItemGroup> 29 </ItemGroup>
31
32 <PropertyGroup Label="Globals"> 30 <PropertyGroup Label="Globals">
33 <ProjectGuid>{90743805-C043-47C7-B5FF-8F5EE5C8A2DE}</ProjectGuid> 31 <ProjectGuid>{90743805-C043-47C7-B5FF-8F5EE5C8A2DE}</ProjectGuid>
34 <ConfigurationType>DynamicLibrary</ConfigurationType> 32 <ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -37,35 +35,28 @@
37 <ProjectModuleDefinitionFile>wixhttpca.def</ProjectModuleDefinitionFile> 35 <ProjectModuleDefinitionFile>wixhttpca.def</ProjectModuleDefinitionFile>
38 <Description>WiX Toolset Http CustomAction</Description> 36 <Description>WiX Toolset Http CustomAction</Description>
39 </PropertyGroup> 37 </PropertyGroup>
40
41 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> 38 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
42 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 39 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
43
44 <PropertyGroup> 40 <PropertyGroup>
45 <ProjectAdditionalLinkLibraries>crypt32.lib;httpapi.lib;msi.lib;rpcrt4.lib;ws2_32.lib</ProjectAdditionalLinkLibraries> 41 <ProjectAdditionalLinkLibraries>crypt32.lib;httpapi.lib;msi.lib;rpcrt4.lib;ws2_32.lib</ProjectAdditionalLinkLibraries>
46 </PropertyGroup> 42 </PropertyGroup>
47
48 <ItemGroup> 43 <ItemGroup>
49 <ClCompile Include="dllmain.cpp"> 44 <ClCompile Include="dllmain.cpp">
50 <PrecompiledHeader>Create</PrecompiledHeader> 45 <PrecompiledHeader>Create</PrecompiledHeader>
51 </ClCompile> 46 </ClCompile>
52 <ClCompile Include="snisslcert.cpp" /> 47 <ClCompile Include="httpcerts.cpp" />
53 <ClCompile Include="wixhttpca.cpp" /> 48 <ClCompile Include="wixhttpca.cpp" />
54 </ItemGroup> 49 </ItemGroup>
55
56 <ItemGroup> 50 <ItemGroup>
57 <ClInclude Include="cost.h" /> 51 <ClInclude Include="cost.h" />
58 <ClInclude Include="precomp.h" /> 52 <ClInclude Include="precomp.h" />
59 </ItemGroup> 53 </ItemGroup>
60
61 <ItemGroup> 54 <ItemGroup>
62 <None Include="wixhttpca.def" /> 55 <None Include="wixhttpca.def" />
63 </ItemGroup> 56 </ItemGroup>
64
65 <ItemGroup> 57 <ItemGroup>
66 <PackageReference Include="WixToolset.WcaUtil" /> 58 <PackageReference Include="WixToolset.WcaUtil" />
67 <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" /> 59 <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
68 </ItemGroup> 60 </ItemGroup>
69
70 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 61 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
71</Project> 62</Project> \ No newline at end of file
diff --git a/src/ext/Http/ca/httpca.vcxproj.filters b/src/ext/Http/ca/httpca.vcxproj.filters
index 2ccd604d..4f91b946 100644
--- a/src/ext/Http/ca/httpca.vcxproj.filters
+++ b/src/ext/Http/ca/httpca.vcxproj.filters
@@ -21,7 +21,7 @@
21 <ClCompile Include="dllmain.cpp"> 21 <ClCompile Include="dllmain.cpp">
22 <Filter>Source Files</Filter> 22 <Filter>Source Files</Filter>
23 </ClCompile> 23 </ClCompile>
24 <ClCompile Include="snisslcert.cpp"> 24 <ClCompile Include="httpcerts.cpp">
25 <Filter>Source Files</Filter> 25 <Filter>Source Files</Filter>
26 </ClCompile> 26 </ClCompile>
27 </ItemGroup> 27 </ItemGroup>
@@ -37,6 +37,5 @@
37 <None Include="wixhttpca.def"> 37 <None Include="wixhttpca.def">
38 <Filter>Source Files</Filter> 38 <Filter>Source Files</Filter>
39 </None> 39 </None>
40 <None Include="packages.config" />
41 </ItemGroup> 40 </ItemGroup>
42</Project> \ No newline at end of file 41</Project> \ No newline at end of file
diff --git a/src/ext/Http/ca/snisslcert.cpp b/src/ext/Http/ca/httpcerts.cpp
index 81cd5298..c91dbbe1 100644
--- a/src/ext/Http/ca/snisslcert.cpp
+++ b/src/ext/Http/ca/httpcerts.cpp
@@ -27,10 +27,19 @@ typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_QUERY
27 27
28#endif 28#endif
29 29
30static UINT SchedHttpSniSslCerts( 30static UINT SchedHttpCertificates(
31 __in WCA_TODO todoSched 31 __in WCA_TODO todoSched
32); 32);
33static HRESULT WriteExistingSniSslCert( 33static HRESULT FindExistingSniSslCertificate(
34 __in_z LPWSTR wzHost,
35 __in int nPort,
36 __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet
37);
38static HRESULT FindExistingIpSslCertificate(
39 __in int nPort,
40 __out HTTP_SERVICE_CONFIG_SSL_SET** ppSet
41);
42static HRESULT WriteSniSslCertCustomActionData(
34 __in WCA_TODO action, 43 __in WCA_TODO action,
35 __in_z LPCWSTR wzId, 44 __in_z LPCWSTR wzId,
36 __in_z LPCWSTR wzHost, 45 __in_z LPCWSTR wzHost,
@@ -39,25 +48,14 @@ static HRESULT WriteExistingSniSslCert(
39 __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet, 48 __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet,
40 __inout_z LPWSTR* psczCustomActionData 49 __inout_z LPWSTR* psczCustomActionData
41); 50);
42static HRESULT WriteSniSslCert( 51static HRESULT WriteIpSslCertCustomActionData(
43 __in WCA_TODO action, 52 __in WCA_TODO action,
44 __in_z LPCWSTR wzId, 53 __in_z LPCWSTR wzId,
45 __in_z LPCWSTR wzHost,
46 __in int iPort, 54 __in int iPort,
47 __in int iHandleExisting, 55 __in int iHandleExisting,
48 __in_z LPCWSTR wzCertificateThumbprint, 56 __in HTTP_SERVICE_CONFIG_SSL_SET* pSniSslSet,
49 __in_z LPCWSTR wzAppId,
50 __in_z_opt LPCWSTR wzCertificateStore,
51 __inout_z LPWSTR* psczCustomActionData 57 __inout_z LPWSTR* psczCustomActionData
52); 58);
53static HRESULT EnsureAppId(
54 __inout_z LPWSTR* psczAppId,
55 __in_opt HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet
56);
57static HRESULT StringFromGuid(
58 __in REFGUID rguid,
59 __inout_z LPWSTR* psczGuid
60);
61static HRESULT AddSniSslCert( 59static HRESULT AddSniSslCert(
62 __in_z LPCWSTR wzId, 60 __in_z LPCWSTR wzId,
63 __in_z LPWSTR wzHost, 61 __in_z LPWSTR wzHost,
@@ -67,43 +65,75 @@ static HRESULT AddSniSslCert(
67 __in GUID* pAppId, 65 __in GUID* pAppId,
68 __in_z LPWSTR wzSslCertStore 66 __in_z LPWSTR wzSslCertStore
69); 67);
70static HRESULT GetSniSslCert( 68static HRESULT AddIpSslCert(
71 __in_z LPWSTR wzHost, 69 __in_z LPCWSTR wzId,
72 __in int nPort, 70 __in int iPort,
73 __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet 71 __in BYTE rgbCertificateThumbprint[],
72 __in DWORD cbCertificateThumbprint,
73 __in GUID* pAppId,
74 __in_z LPWSTR wzSslCertStore
74); 75);
75static HRESULT RemoveSniSslCert( 76static HRESULT RemoveSniSslCert(
76 __in_z LPCWSTR wzId, 77 __in_z_opt LPCWSTR wzId,
77 __in_z LPWSTR wzHost, 78 __in_z LPWSTR wzHost,
78 __in int iPort 79 __in int iPort
79); 80);
80static void SetSniSslCertSetKey( 81static HRESULT RemoveIpSslCert(
82 __in_z_opt LPCWSTR wzId,
83 __in int iPort
84);
85static void SetSniSslCertificateKeyPort(
81 __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey, 86 __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey,
82 __in_z LPWSTR wzHost, 87 __in_z LPWSTR wzHost,
83 __in int iPort 88 __in int iPort
84); 89);
90static void SetIpSslCertificateKeyPort(
91 __in HTTP_SERVICE_CONFIG_SSL_KEY* pKey,
92 __in SOCKADDR_IN* pSin,
93 __in int iPort
94);
95static HRESULT EnsureAppId(
96 __inout_z LPWSTR* psczAppId,
97 __in_opt GUID* pGuid
98);
99static HRESULT StringFromGuid(
100 __in REFGUID rguid,
101 __inout_z LPWSTR* psczGuid
102);
103static HRESULT WriteCertificateCaData(
104 __in eCertificateType certType,
105 __in WCA_TODO action,
106 __in_z LPCWSTR wzId,
107 __in_z_opt LPCWSTR wzHost,
108 __in int iPort,
109 __in int iHandleExisting,
110 __in_z LPCWSTR wzCertificateThumbprint,
111 __in_z_opt LPCWSTR wzAppId,
112 __in_z_opt LPCWSTR wzCertificateStore,
113 __inout_z LPWSTR* psczCustomActionData
114);
85 115
86 116
87LPCWSTR vcsWixHttpSniSslCertQuery = 117LPCWSTR vcsHttpCertificatesQuery =
88L"SELECT `WixHttpSniSslCert`, `Host`, `Port`, `Thumbprint`, `AppId`, `Store`, `HandleExisting`, `Component_` " 118L"SELECT `HttpCertificate`, `Host`, `Port`, `Thumbprint`, `AppId`, `Store`, `HandleExisting`, `Type`, `Component_` "
89L"FROM `Wix4HttpSniSslCert`"; 119L"FROM `Wix6HttpCertificate`";
90enum eWixHttpSniSslCertQuery { hurqId = 1, hurqHost, hurqPort, hurqCertificateThumbprint, hurqAppId, hurqCertificateStore, hurqHandleExisting, hurqComponent }; 120enum eHttpCertificatesQuery { hcqId = 1, hcqHost, hcqPort, hcqCertificateThumbprint, hcqAppId, hcqCertificateStore, hcqHandleExisting, hcqType, hcqComponent };
91 121
92/****************************************************************** 122/******************************************************************
93 SchedWixHttpSniSslCertsInstall - immediate custom action entry 123 SchedHttpCertificatesInstall - immediate custom action entry
94 point to prepare adding URL reservations. 124 point to prepare adding certificates.
95 125
96********************************************************************/ 126********************************************************************/
97extern "C" UINT __stdcall SchedHttpSniSslCertsInstall( 127extern "C" UINT __stdcall SchedHttpCertificatesInstall(
98 __in MSIHANDLE hInstall 128 __in MSIHANDLE hInstall
99) 129)
100{ 130{
101 HRESULT hr = S_OK; 131 HRESULT hr = S_OK;
102 132
103 hr = WcaInitialize(hInstall, "SchedHttpSniSslCertsInstall"); 133 hr = WcaInitialize(hInstall, "SchedHttpCertificatesInstall");
104 ExitOnFailure(hr, "Failed to initialize"); 134 ExitOnFailure(hr, "Failed to initialize");
105 135
106 hr = SchedHttpSniSslCerts(WCA_TODO_INSTALL); 136 hr = SchedHttpCertificates(WCA_TODO_INSTALL);
107 137
108LExit: 138LExit:
109 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); 139 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
@@ -111,30 +141,30 @@ LExit:
111 141
112/****************************************************************** 142/******************************************************************
113 SchedWixHttpSniSslCertsUninstall - immediate custom action entry 143 SchedWixHttpSniSslCertsUninstall - immediate custom action entry
114 point to prepare removing URL reservations. 144 point to prepare removing certificates.
115 145
116********************************************************************/ 146********************************************************************/
117extern "C" UINT __stdcall SchedHttpSniSslCertsUninstall( 147extern "C" UINT __stdcall SchedHttpCertificatesUninstall(
118 __in MSIHANDLE hInstall 148 __in MSIHANDLE hInstall
119) 149)
120{ 150{
121 HRESULT hr = S_OK; 151 HRESULT hr = S_OK;
122 152
123 hr = WcaInitialize(hInstall, "SchedHttpSniSslCertsUninstall"); 153 hr = WcaInitialize(hInstall, "SchedHttpCertificatesUninstall");
124 ExitOnFailure(hr, "Failed to initialize"); 154 ExitOnFailure(hr, "Failed to initialize");
125 155
126 hr = SchedHttpSniSslCerts(WCA_TODO_UNINSTALL); 156 hr = SchedHttpCertificates(WCA_TODO_UNINSTALL);
127 157
128LExit: 158LExit:
129 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); 159 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
130} 160}
131 161
132/****************************************************************** 162/******************************************************************
133 ExecHttpSniSslCerts - deferred custom action entry point to 163 ExecHttpCertificates - deferred custom action entry point to
134 register and remove URL reservations. 164 bind/unbind certificates.
135 165
136********************************************************************/ 166********************************************************************/
137extern "C" UINT __stdcall ExecHttpSniSslCerts( 167extern "C" UINT __stdcall ExecHttpCertificates(
138 __in MSIHANDLE hInstall 168 __in MSIHANDLE hInstall
139) 169)
140{ 170{
@@ -147,6 +177,7 @@ extern "C" UINT __stdcall ExecHttpSniSslCerts(
147 LPWSTR sczHost = NULL; 177 LPWSTR sczHost = NULL;
148 int iPort = 0; 178 int iPort = 0;
149 eHandleExisting handleExisting = heIgnore; 179 eHandleExisting handleExisting = heIgnore;
180 eCertificateType certificateType = ctSniSsl;
150 LPWSTR sczCertificateThumbprint = NULL; 181 LPWSTR sczCertificateThumbprint = NULL;
151 LPWSTR sczAppId = NULL; 182 LPWSTR sczAppId = NULL;
152 LPWSTR sczCertificateStore = NULL; 183 LPWSTR sczCertificateStore = NULL;
@@ -161,7 +192,7 @@ extern "C" UINT __stdcall ExecHttpSniSslCerts(
161 DWORD cbCertificateThumbprint = 0; 192 DWORD cbCertificateThumbprint = 0;
162 193
163 // Initialize. 194 // Initialize.
164 hr = WcaInitialize(hInstall, "ExecHttpSniSslCerts"); 195 hr = WcaInitialize(hInstall, "ExecHttpCertificates");
165 ExitOnFailure(hr, "Failed to initialize"); 196 ExitOnFailure(hr, "Failed to initialize");
166 197
167 hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL)); 198 hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL));
@@ -177,6 +208,9 @@ extern "C" UINT __stdcall ExecHttpSniSslCerts(
177 while (wz && *wz) 208 while (wz && *wz)
178 { 209 {
179 // Extract the custom action data and if rolling back, swap INSTALL and UNINSTALL. 210 // Extract the custom action data and if rolling back, swap INSTALL and UNINSTALL.
211 hr = WcaReadIntegerFromCaData(&wz, reinterpret_cast<int*>(&certificateType));
212 ExitOnFailure(hr, "Failed to read Type from custom action data");
213
180 hr = WcaReadIntegerFromCaData(&wz, &iTodo); 214 hr = WcaReadIntegerFromCaData(&wz, &iTodo);
181 ExitOnFailure(hr, "Failed to read todo from custom action data"); 215 ExitOnFailure(hr, "Failed to read todo from custom action data");
182 216
@@ -219,35 +253,50 @@ extern "C" UINT __stdcall ExecHttpSniSslCerts(
219 253
220 if (fRemove) 254 if (fRemove)
221 { 255 {
222 hr = RemoveSniSslCert(sczId, sczHost, iPort); 256 if (ctSniSsl == certificateType)
257 {
258 hr = RemoveSniSslCert(sczId, sczHost, iPort);
259 }
260 else
261 {
262 hr = RemoveIpSslCert(sczId, iPort);
263 }
264
223 if (S_OK == hr) 265 if (S_OK == hr)
224 { 266 {
225 WcaLog(LOGMSG_STANDARD, "Removed SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); 267 WcaLog(LOGMSG_STANDARD, "Removed SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort);
226 } 268 }
227 else if (FAILED(hr)) 269 else if (FAILED(hr))
228 { 270 {
229 if (fRollback) 271 if (fRollback)
230 { 272 {
231 WcaLogError(hr, "Failed to remove SNI SSL certificate to rollback '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); 273 WcaLogError(hr, "Failed to remove SSL certificate to rollback '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort);
232 } 274 }
233 else 275 else
234 { 276 {
235 ExitOnFailure(hr, "Failed to remove SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); 277 ExitOnFailure(hr, "Failed to remove SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort);
236 } 278 }
237 } 279 }
238 } 280 }
239 281
240 if (fAdd) 282 if (fAdd)
241 { 283 {
242 WcaLog(LOGMSG_STANDARD, "Adding SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); 284 WcaLog(LOGMSG_STANDARD, "Adding SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort);
243 285
244 hr = StrAllocHexDecode(sczCertificateThumbprint, &pbCertificateThumbprint, &cbCertificateThumbprint); 286 hr = StrAllocHexDecode(sczCertificateThumbprint, &pbCertificateThumbprint, &cbCertificateThumbprint);
245 ExitOnFailure(hr, "Failed to convert thumbprint to bytes for SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); 287 ExitOnFailure(hr, "Failed to convert thumbprint to bytes for SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort);
246 288
247 hr = ::IIDFromString(sczAppId, &guidAppId); 289 hr = ::IIDFromString(sczAppId, &guidAppId);
248 ExitOnFailure(hr, "Failed to convert AppId '%ls' back to GUID for SNI SSL certificate '%ls' for hostname: %ls:%d", sczAppId, sczId, sczHost, iPort); 290 ExitOnFailure(hr, "Failed to convert AppId '%ls' back to GUID for SSL certificate '%ls' for hostname: %ls:%d", sczAppId, sczId, sczHost, iPort);
291 if (ctSniSsl == certificateType)
292 {
293 hr = AddSniSslCert(sczId, sczHost, iPort, pbCertificateThumbprint, cbCertificateThumbprint, &guidAppId, sczCertificateStore && *sczCertificateStore ? sczCertificateStore : L"MY");
294 }
295 else
296 {
297 hr = AddIpSslCert(sczId, iPort, pbCertificateThumbprint, cbCertificateThumbprint, &guidAppId, sczCertificateStore && *sczCertificateStore ? sczCertificateStore : L"MY");
298 }
249 299
250 hr = AddSniSslCert(sczId, sczHost, iPort, pbCertificateThumbprint, cbCertificateThumbprint, &guidAppId, sczCertificateStore && *sczCertificateStore ? sczCertificateStore : L"MY");
251 if (S_FALSE == hr && fFailOnExisting) 300 if (S_FALSE == hr && fFailOnExisting)
252 { 301 {
253 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); 302 hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
@@ -255,17 +304,17 @@ extern "C" UINT __stdcall ExecHttpSniSslCerts(
255 304
256 if (S_OK == hr) 305 if (S_OK == hr)
257 { 306 {
258 WcaLog(LOGMSG_STANDARD, "Added SNI SSL certificate '%ls' for hostname: %ls:%d with thumbprint: %ls", sczId, sczHost, iPort, sczCertificateThumbprint); 307 WcaLog(LOGMSG_STANDARD, "Added SSL certificate '%ls' for hostname: %ls:%d with thumbprint: %ls.", sczId, sczHost, iPort, sczCertificateThumbprint);
259 } 308 }
260 else if (FAILED(hr)) 309 else if (FAILED(hr))
261 { 310 {
262 if (fRollback) 311 if (fRollback)
263 { 312 {
264 WcaLogError(hr, "Failed to add SNI SSL certificate to rollback '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); 313 WcaLogError(hr, "Failed to add SSL certificate to rollback '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort);
265 } 314 }
266 else 315 else
267 { 316 {
268 ExitOnFailure(hr, "Failed to add SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); 317 ExitOnFailure(hr, "Failed to add SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort);
269 } 318 }
270 } 319 }
271 320
@@ -290,7 +339,7 @@ LExit:
290 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); 339 return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS);
291} 340}
292 341
293static UINT SchedHttpSniSslCerts( 342static UINT SchedHttpCertificates(
294 __in WCA_TODO todoSched 343 __in WCA_TODO todoSched
295) 344)
296{ 345{
@@ -309,6 +358,7 @@ static UINT SchedHttpSniSslCerts(
309 358
310 LPWSTR sczId = NULL; 359 LPWSTR sczId = NULL;
311 LPWSTR sczComponent = NULL; 360 LPWSTR sczComponent = NULL;
361 eCertificateType certificateType = ctSniSsl;
312 WCA_TODO todoComponent = WCA_TODO_UNKNOWN; 362 WCA_TODO todoComponent = WCA_TODO_UNKNOWN;
313 LPWSTR sczHost = NULL; 363 LPWSTR sczHost = NULL;
314 int iPort = 0; 364 int iPort = 0;
@@ -318,19 +368,20 @@ static UINT SchedHttpSniSslCerts(
318 int iHandleExisting = 0; 368 int iHandleExisting = 0;
319 369
320 HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet = NULL; 370 HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet = NULL;
371 HTTP_SERVICE_CONFIG_SSL_SET* pExistingIpSslSet = NULL;
321 372
322 // Anything to do? 373 // Anything to do?
323 hr = WcaTableExists(L"Wix4HttpSniSslCert"); 374 hr = WcaTableExists(L"Wix6HttpCertificate");
324 ExitOnFailure(hr, "Failed to check if the Wix4HttpSniSslCert table exists"); 375 ExitOnFailure(hr, "Failed to check if the Wix6HttpCertificate table exists");
325 if (S_FALSE == hr) 376 if (S_FALSE == hr)
326 { 377 {
327 WcaLog(LOGMSG_STANDARD, "Wix4HttpSniSslCert table doesn't exist, so there are no URL reservations to configure"); 378 WcaLog(LOGMSG_STANDARD, "Wix6HttpCertificate table doesn't exist, so there are no certificates to configure.");
328 ExitFunction(); 379 ExitFunction();
329 } 380 }
330 381
331 // Query and loop through all the SNI SSL certificates. 382 // Query and loop through all the SNI SSL certificates.
332 hr = WcaOpenExecuteView(vcsWixHttpSniSslCertQuery, &hView); 383 hr = WcaOpenExecuteView(vcsHttpCertificatesQuery, &hView);
333 ExitOnFailure(hr, "Failed to open view on the Wix4HttpSniSslCert table"); 384 ExitOnFailure(hr, "Failed to open view on the Wix6HttpCertificate table");
334 385
335 hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL)); 386 hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL));
336 ExitOnFailure(hr, "Failed to initialize HTTP Server configuration"); 387 ExitOnFailure(hr, "Failed to initialize HTTP Server configuration");
@@ -339,70 +390,92 @@ static UINT SchedHttpSniSslCerts(
339 390
340 while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) 391 while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
341 { 392 {
342 hr = WcaGetRecordString(hRec, hurqId, &sczId); 393 hr = WcaGetRecordString(hRec, hcqId, &sczId);
343 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Wix4HttpSniSslCert"); 394 ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Wix6HttpCertificate");
344 395
345 hr = WcaGetRecordString(hRec, hurqComponent, &sczComponent); 396 hr = WcaGetRecordString(hRec, hcqComponent, &sczComponent);
346 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Component_"); 397 ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Component_");
347 398
348 // Figure out what we're doing for this reservation, treating reinstall the same as install. 399 // Figure out what we're doing for this certificate, treating reinstall the same as install.
349 todoComponent = WcaGetComponentToDo(sczComponent); 400 todoComponent = WcaGetComponentToDo(sczComponent);
350 if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched) 401 if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched)
351 { 402 {
352 WcaLog(LOGMSG_STANDARD, "Component '%ls' action state (%d) doesn't match request (%d) for Wix4HttpSniSslCert '%ls'", sczComponent, todoComponent, todoSched, sczId); 403 WcaLog(LOGMSG_VERBOSE, "Component '%ls' action state (%d) doesn't match request (%d) for Wix6HttpCertificate '%ls'.", sczComponent, todoComponent, todoSched, sczId);
353 continue; 404 continue;
354 } 405 }
355 406
356 hr = WcaGetRecordFormattedString(hRec, hurqHost, &sczHost); 407 hr = WcaGetRecordInteger(hRec, hcqType, reinterpret_cast<int*>(&certificateType));
357 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Host"); 408 ExitOnFailure(hr, "Failed to get Type for Wix6HttpCertificate '%ls'", sczId);
358 409
359 hr = WcaGetRecordFormattedInteger(hRec, hurqPort, &iPort); 410 hr = WcaGetRecordFormattedString(hRec, hcqHost, &sczHost);
360 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Port"); 411 ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Host");
361 412
362 hr = WcaGetRecordFormattedString(hRec, hurqCertificateThumbprint, &sczCertificateThumbprint); 413 hr = WcaGetRecordFormattedInteger(hRec, hcqPort, &iPort);
363 ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.CertificateThumbprint"); 414 ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Port");
364 415
365 if (!sczHost || !*sczHost) 416 hr = WcaGetRecordFormattedString(hRec, hcqCertificateThumbprint, &sczCertificateThumbprint);
366 { 417 ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.CertificateThumbprint");
367 hr = E_INVALIDARG;
368 ExitOnFailure(hr, "Require a Host value for Wix4HttpSniSslCert '%ls'", sczId);
369 }
370 418
371 if (!iPort) 419 if (!iPort)
372 { 420 {
373 hr = E_INVALIDARG; 421 hr = E_INVALIDARG;
374 ExitOnFailure(hr, "Require a Port value for Wix4HttpSniSslCert '%ls'", sczId); 422 ExitOnFailure(hr, "Missing Port value for Wix6HttpCertificate '%ls'", sczId);
375 } 423 }
376 424
377 if (!sczCertificateThumbprint || !*sczCertificateThumbprint) 425 if (!sczCertificateThumbprint || !*sczCertificateThumbprint)
378 { 426 {
379 hr = E_INVALIDARG; 427 hr = E_INVALIDARG;
380 ExitOnFailure(hr, "Require a CertificateThumbprint value for Wix4HttpSniSslCert '%ls'", sczId); 428 ExitOnFailure(hr, "Missing CertificateThumbprint value for Wix6HttpCertificate '%ls'", sczId);
381 } 429 }
382 430
383 hr = WcaGetRecordFormattedString(hRec, hurqAppId, &sczAppId); 431 hr = WcaGetRecordFormattedString(hRec, hcqAppId, &sczAppId);
384 ExitOnFailure(hr, "Failed to get AppId for Wix4HttpSniSslCert '%ls'", sczId); 432 ExitOnFailure(hr, "Failed to get AppId for Wix6HttpCertificate '%ls'", sczId);
385 433
386 hr = WcaGetRecordFormattedString(hRec, hurqCertificateStore, &sczCertificateStore); 434 hr = WcaGetRecordFormattedString(hRec, hcqCertificateStore, &sczCertificateStore);
387 ExitOnFailure(hr, "Failed to get CertificateStore for Wix4HttpSniSslCert '%ls'", sczId); 435 ExitOnFailure(hr, "Failed to get CertificateStore for Wix6HttpCertificate '%ls'", sczId);
388 436
389 hr = WcaGetRecordInteger(hRec, hurqHandleExisting, &iHandleExisting); 437 hr = WcaGetRecordInteger(hRec, hcqHandleExisting, &iHandleExisting);
390 ExitOnFailure(hr, "Failed to get HandleExisting for Wix4HttpSniSslCert '%ls'", sczId); 438 ExitOnFailure(hr, "Failed to get HandleExisting for Wix6HttpCertificate '%ls'", sczId);
391 439
392 hr = GetSniSslCert(sczHost, iPort, &pExistingSniSslSet); 440 if (ctIpSsl == certificateType)
393 ExitOnFailure(hr, "Failed to get the existing SNI SSL certificate for Wix4HttpSniSslCert '%ls'", sczId); 441 {
442 WcaLog(LOGMSG_STANDARD, "Processing IP SSL certificate: %ls on port %d.", sczId, iPort);
443
444 hr = FindExistingIpSslCertificate(iPort, &pExistingIpSslSet);
445 ExitOnFailure(hr, "Failed to search for an existing IP SSL certificate for '%ls' on port %d", sczId, iPort);
394 446
395 hr = EnsureAppId(&sczAppId, pExistingSniSslSet); 447 if (S_FALSE != hr)
396 ExitOnFailure(hr, "Failed to ensure AppId for Wix4HttpSniSslCert '%ls'", sczId); 448 {
449 hr = WriteIpSslCertCustomActionData(todoComponent, sczId, iPort, iHandleExisting, pExistingIpSslSet, &sczRollbackCustomActionData);
450 ExitOnFailure(hr, "Failed to write rollback custom action data for IP SSL '%ls' on port %d", sczId, iPort);
451 }
397 452
398 hr = WriteExistingSniSslCert(todoComponent, sczId, sczHost, iPort, iHandleExisting, pExistingSniSslSet, &sczRollbackCustomActionData); 453 hr = EnsureAppId(&sczAppId, pExistingIpSslSet ? &(pExistingIpSslSet->ParamDesc.AppId) : NULL);
399 ExitOnFailure(hr, "Failed to write rollback custom action data for Wix4HttpSniSslCert '%ls'", sczId); 454 ExitOnFailure(hr, "Failed to ensure AppId for IP SSL '%ls'", sczId);
455 }
456 else if (ctSniSsl == certificateType)
457 {
458 WcaLog(LOGMSG_STANDARD, "Processing SNI SSL certificate: %ls on host %ls:%d.", sczId, sczHost, iPort);
400 459
401 hr = WriteSniSslCert(todoComponent, sczId, sczHost, iPort, iHandleExisting, sczCertificateThumbprint, sczAppId, sczCertificateStore, &sczCustomActionData); 460 hr = FindExistingSniSslCertificate(sczHost, iPort, &pExistingSniSslSet);
402 ExitOnFailure(hr, "Failed to write custom action data for Wix4HttpSniSslCert '%ls'", sczId); 461 ExitOnFailure(hr, "Failed to search for an existing SNI SSL certificate for '%ls' on host '%ls', port %d", sczId, sczHost, iPort);
462
463 if (S_FALSE != hr)
464 {
465 hr = WriteSniSslCertCustomActionData(todoComponent, sczId, sczHost, iPort, iHandleExisting, pExistingSniSslSet, &sczRollbackCustomActionData);
466 ExitOnFailure(hr, "Failed to write rollback custom action data for SNI SSL Wix6HttpCertificate '%ls' on host '%ls', port %d", sczId, sczHost, iPort);
467 }
468
469 hr = EnsureAppId(&sczAppId, pExistingSniSslSet ? &(pExistingSniSslSet->ParamDesc.AppId) : NULL);
470 ExitOnFailure(hr, "Failed to ensure AppId for SNI SSL '%ls'", sczId);
471 }
472
473 hr = WriteCertificateCaData(certificateType, todoComponent, sczId, sczHost, iPort, iHandleExisting, sczCertificateThumbprint, sczAppId, sczCertificateStore, &sczCustomActionData);
474 ExitOnFailure(hr, "Failed to write custom action data for SSL '%ls'", sczId);
403 ++cCertificates; 475 ++cCertificates;
404 476
405 ReleaseNullMem(pExistingSniSslSet); 477 ReleaseNullMem(pExistingSniSslSet);
478 ReleaseNullMem(pExistingIpSslSet);
406 } 479 }
407 480
408 // Reaching the end of the list is not an error. 481 // Reaching the end of the list is not an error.
@@ -410,36 +483,39 @@ static UINT SchedHttpSniSslCerts(
410 { 483 {
411 hr = S_OK; 484 hr = S_OK;
412 } 485 }
413 ExitOnFailure(hr, "Failure occurred while processing Wix4HttpSniSslCert table"); 486 ExitOnFailure(hr, "Failure occurred while processing Wix6HttpCertificate table");
487
488 WcaLog(LOGMSG_VERBOSE, "Scheduling %d certificates", cCertificates);
414 489
415 // Schedule ExecHttpSniSslCerts if there's anything to do. 490 // Schedule ExecHttpSniSslCerts if there's anything to do.
416 if (cCertificates) 491 if (cCertificates)
417 { 492 {
418 WcaLog(LOGMSG_STANDARD, "Scheduling SNI SSL certificate (%ls)", sczCustomActionData); 493 WcaLog(LOGMSG_TRACEONLY, "Scheduling SSL certificate: `%ls`", sczCustomActionData);
419 WcaLog(LOGMSG_STANDARD, "Scheduling rollback SNI SSL certificate (%ls)", sczRollbackCustomActionData); 494 WcaLog(LOGMSG_TRACEONLY, "Scheduling rollback SSL certificate: `%ls`", sczRollbackCustomActionData);
420 495
421 if (WCA_TODO_INSTALL == todoSched) 496 if (WCA_TODO_INSTALL == todoSched)
422 { 497 {
423 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackHttpSniSslCertsInstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL); 498 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RollbackHttpCertificatesInstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
424 ExitOnFailure(hr, "Failed to schedule install SNI SSL certificate rollback"); 499 ExitOnFailure(hr, "Failed to schedule install SSL certificate rollback");
425 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ExecHttpSniSslCertsInstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL); 500 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"ExecHttpCertificatesInstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
426 ExitOnFailure(hr, "Failed to schedule install SNI SSL certificate execution"); 501 ExitOnFailure(hr, "Failed to schedule install SSL certificate execution");
427 } 502 }
428 else 503 else
429 { 504 {
430 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackHttpSniSslCertsUninstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL); 505 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RollbackHttpCertificatesUninstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
431 ExitOnFailure(hr, "Failed to schedule uninstall SNI SSL certificate rollback"); 506 ExitOnFailure(hr, "Failed to schedule uninstall SSL certificate rollback");
432 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ExecHttpSniSslCertsUninstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL); 507 hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"ExecHttpCertificatesUninstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL);
433 ExitOnFailure(hr, "Failed to schedule uninstall SNI SSL certificate execution"); 508 ExitOnFailure(hr, "Failed to schedule uninstall SSL certificate execution");
434 } 509 }
435 } 510 }
436 else 511 else
437 { 512 {
438 WcaLog(LOGMSG_STANDARD, "No SNI SSL certificates scheduled"); 513 WcaLog(LOGMSG_STANDARD, "No SNI SSL certificates scheduled.");
439 } 514 }
440 515
441LExit: 516LExit:
442 ReleaseMem(pExistingSniSslSet); 517 ReleaseMem(pExistingSniSslSet);
518 ReleaseMem(pExistingIpSslSet);
443 ReleaseStr(sczCertificateStore); 519 ReleaseStr(sczCertificateStore);
444 ReleaseStr(sczAppId); 520 ReleaseStr(sczAppId);
445 ReleaseStr(sczCertificateThumbprint); 521 ReleaseStr(sczCertificateThumbprint);
@@ -457,133 +533,171 @@ LExit:
457 return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er); 533 return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er);
458} 534}
459 535
460static HRESULT WriteExistingSniSslCert( 536static HRESULT FindExistingSniSslCertificate(
461 __in WCA_TODO action, 537 __in_z LPWSTR wzHost,
462 __in_z LPCWSTR wzId, 538 __in int nPort,
463 __in_z LPCWSTR wzHost, 539 __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet
464 __in int iPort,
465 __in int iHandleExisting,
466 __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet,
467 __inout_z LPWSTR* psczCustomActionData
468) 540)
469{ 541{
470 HRESULT hr = S_OK; 542 HRESULT hr = S_OK;
471 LPWSTR sczCertificateThumbprint = NULL; 543 DWORD er = ERROR_SUCCESS;
472 LPWSTR sczAppId = NULL; 544 HTTP_SERVICE_CONFIG_SSL_SNI_QUERY query = { };
473 LPCWSTR wzCertificateStore = NULL; 545 HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSet = NULL;
546 ULONG cbSet = 0;
474 547
475 if (pSniSslSet) 548 *ppSet = NULL;
476 {
477 hr = StrAllocHexEncode(reinterpret_cast<BYTE*>(pSniSslSet->ParamDesc.pSslHash), pSniSslSet->ParamDesc.SslHashLength, &sczCertificateThumbprint);
478 ExitOnFailure(hr, "Failed to convert existing certificate thumbprint to hex for Wix4HttpSniSslCert '%ls'", wzId);
479 549
480 hr = StringFromGuid(pSniSslSet->ParamDesc.AppId, &sczAppId); 550 query.QueryDesc = HttpServiceConfigQueryExact;
481 ExitOnFailure(hr, "Failed to copy existing AppId for Wix4HttpSniSslCert '%ls'", wzId); 551 SetSniSslCertificateKeyPort(&query.KeyDesc, wzHost, nPort);
482 552
483 wzCertificateStore = pSniSslSet->ParamDesc.pSslCertStoreName; 553 WcaLog(LOGMSG_TRACEONLY, "Querying for SNI SSL certificate on port %d...", nPort);
554
555 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
556 if (ERROR_INSUFFICIENT_BUFFER == er)
557 {
558 pSet = reinterpret_cast<HTTP_SERVICE_CONFIG_SSL_SNI_SET*>(MemAlloc(cbSet, TRUE));
559 ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query SN SSL certificate buffer");
560
561 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
484 } 562 }
485 563
486 hr = WriteSniSslCert(action, wzId, wzHost, iPort, iHandleExisting, sczCertificateThumbprint ? sczCertificateThumbprint : L"", sczAppId ? sczAppId : L"", wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData); 564 if (ERROR_SUCCESS == er)
487 ExitOnFailure(hr, "Failed to write custom action data for Wix4HttpSniSslCert '%ls'", wzId); 565 {
566 *ppSet = pSet;
567 pSet = NULL;
568 }
569 else if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er)
570 {
571 hr = S_FALSE;
572 }
573 else
574 {
575 hr = HRESULT_FROM_WIN32(er);
576 }
488 577
489LExit: 578LExit:
490 ReleaseStr(sczAppId); 579 ReleaseMem(pSet);
491 ReleaseStr(sczCertificateThumbprint);
492 580
493 return hr; 581 return hr;
494} 582}
495 583
496static HRESULT WriteSniSslCert( 584static HRESULT FindExistingIpSslCertificate(
497 __in WCA_TODO action, 585 __in int nPort,
498 __in_z LPCWSTR wzId, 586 __out HTTP_SERVICE_CONFIG_SSL_SET** ppSet
499 __in_z LPCWSTR wzHost,
500 __in int iPort,
501 __in int iHandleExisting,
502 __in_z LPCWSTR wzCertificateThumbprint,
503 __in_z LPCWSTR wzAppId,
504 __in_z_opt LPCWSTR wzCertificateStore,
505 __inout_z LPWSTR* psczCustomActionData
506) 587)
507{ 588{
508 HRESULT hr = S_OK; 589 HRESULT hr = S_OK;
590 DWORD er = ERROR_SUCCESS;
591 HTTP_SERVICE_CONFIG_SSL_QUERY query = { };
592 SOCKADDR_IN sin = { };
593 HTTP_SERVICE_CONFIG_SSL_SET* pSet = NULL;
594 ULONG cbSet = 0;
509 595
510 hr = WcaWriteIntegerToCaData(action, psczCustomActionData); 596 *ppSet = NULL;
511 ExitOnFailure(hr, "Failed to write action to custom action data");
512
513 hr = WcaWriteStringToCaData(wzId, psczCustomActionData);
514 ExitOnFailure(hr, "Failed to write id to custom action data");
515 597
516 hr = WcaWriteStringToCaData(wzHost, psczCustomActionData); 598 query.QueryDesc = HttpServiceConfigQueryNext;
517 ExitOnFailure(hr, "Failed to write Host to custom action data");
518 599
519 hr = WcaWriteIntegerToCaData(iPort, psczCustomActionData); 600 SetIpSslCertificateKeyPort(&query.KeyDesc, &sin, nPort);
520 ExitOnFailure(hr, "Failed to write Port to custom action data");
521 601
522 hr = WcaWriteIntegerToCaData(iHandleExisting, psczCustomActionData); 602 WcaLog(LOGMSG_TRACEONLY, "Querying for IP SSL certificate on port %d...", nPort);
523 ExitOnFailure(hr, "Failed to write HandleExisting to custom action data");
524 603
525 hr = WcaWriteStringToCaData(wzCertificateThumbprint, psczCustomActionData); 604 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
526 ExitOnFailure(hr, "Failed to write CertificateThumbprint to custom action data"); 605 if (ERROR_INSUFFICIENT_BUFFER == er)
606 {
607 pSet = reinterpret_cast<HTTP_SERVICE_CONFIG_SSL_SET*>(MemAlloc(cbSet, TRUE));
608 ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query IP SSL certificate buffer");
527 609
528 hr = WcaWriteStringToCaData(wzAppId, psczCustomActionData); 610 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
529 ExitOnFailure(hr, "Failed to write AppId to custom action data"); 611 }
530 612
531 hr = WcaWriteStringToCaData(wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData); 613 if (ERROR_SUCCESS == er)
532 ExitOnFailure(hr, "Failed to write CertificateStore to custom action data"); 614 {
615 *ppSet = pSet;
616 pSet = NULL;
617 }
618 else if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er)
619 {
620 hr = S_FALSE;
621 }
622 else
623 {
624 hr = HRESULT_FROM_WIN32(er);
625 }
533 626
534LExit: 627LExit:
628 ReleaseMem(pSet);
629
535 return hr; 630 return hr;
536} 631}
537 632
538static HRESULT EnsureAppId( 633static HRESULT WriteSniSslCertCustomActionData(
539 __inout_z LPWSTR* psczAppId, 634 __in WCA_TODO action,
540 __in_opt HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet 635 __in_z LPCWSTR wzId,
636 __in_z LPCWSTR wzHost,
637 __in int iPort,
638 __in int iHandleExisting,
639 __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet,
640 __inout_z LPWSTR* psczCustomActionData
541) 641)
542{ 642{
543 HRESULT hr = S_OK; 643 HRESULT hr = S_OK;
544 RPC_STATUS rs = RPC_S_OK; 644 LPWSTR sczCertificateThumbprint = NULL;
545 GUID guid = { }; 645 LPWSTR sczAppId = NULL;
646 LPCWSTR wzCertificateStore = NULL;
546 647
547 if (!psczAppId || !*psczAppId || !**psczAppId) 648 if (pSniSslSet)
548 { 649 {
549 if (pExistingSniSslSet) 650 hr = StrAllocHexEncode(reinterpret_cast<BYTE*>(pSniSslSet->ParamDesc.pSslHash), pSniSslSet->ParamDesc.SslHashLength, &sczCertificateThumbprint);
550 { 651 ExitOnFailure(hr, "Failed to convert existing certificate thumbprint to hex for Wix6HttpCertificate '%ls'", wzId);
551 hr = StringFromGuid(pExistingSniSslSet->ParamDesc.AppId, psczAppId);
552 ExitOnFailure(hr, "Failed to ensure AppId guid");
553 }
554 else
555 {
556 rs = ::UuidCreate(&guid);
557 hr = HRESULT_FROM_RPC(rs);
558 ExitOnRootFailure(hr, "Failed to create guid for AppId");
559 652
560 hr = StringFromGuid(guid, psczAppId); 653 hr = StringFromGuid(pSniSslSet->ParamDesc.AppId, &sczAppId);
561 ExitOnFailure(hr, "Failed to ensure AppId guid"); 654 ExitOnFailure(hr, "Failed to copy existing AppId for Wix6HttpCertificate '%ls'", wzId);
562 } 655
656 wzCertificateStore = pSniSslSet->ParamDesc.pSslCertStoreName;
563 } 657 }
564 658
659 hr = WriteCertificateCaData(ctSniSsl, action, wzId, wzHost, iPort, iHandleExisting, sczCertificateThumbprint ? sczCertificateThumbprint : L"", sczAppId ? sczAppId : L"", wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData);
660 ExitOnFailure(hr, "Failed to write custom action data for Wix6HttpCertificate '%ls'", wzId);
661
565LExit: 662LExit:
663 ReleaseStr(sczAppId);
664 ReleaseStr(sczCertificateThumbprint);
665
566 return hr; 666 return hr;
567} 667}
568 668
569static HRESULT StringFromGuid( 669static HRESULT WriteIpSslCertCustomActionData(
570 __in REFGUID rguid, 670 __in WCA_TODO action,
571 __inout_z LPWSTR* psczGuid 671 __in_z LPCWSTR wzId,
672 __in int iPort,
673 __in int iHandleExisting,
674 __in HTTP_SERVICE_CONFIG_SSL_SET* pSslSet,
675 __inout_z LPWSTR* psczCustomActionData
572) 676)
573{ 677{
574 HRESULT hr = S_OK; 678 HRESULT hr = S_OK;
575 WCHAR wzGuid[39]; 679 LPWSTR sczCertificateThumbprint = NULL;
680 LPWSTR sczAppId = NULL;
681 LPCWSTR wzCertificateStore = NULL;
576 682
577 if (!::StringFromGUID2(rguid, wzGuid, countof(wzGuid))) 683 if (pSslSet)
578 { 684 {
579 hr = E_OUTOFMEMORY; 685 hr = StrAllocHexEncode(reinterpret_cast<BYTE*>(pSslSet->ParamDesc.pSslHash), pSslSet->ParamDesc.SslHashLength, &sczCertificateThumbprint);
580 ExitOnRootFailure(hr, "Failed to convert guid into string"); 686 ExitOnFailure(hr, "Failed to convert existing IP SSL certificate thumbprint to hex for Wix6HttpCertificate '%ls'", wzId);
687
688 hr = StringFromGuid(pSslSet->ParamDesc.AppId, &sczAppId);
689 ExitOnFailure(hr, "Failed to copy existing IP SSL AppId for Wix6HttpCertificate '%ls'", wzId);
690
691 wzCertificateStore = pSslSet->ParamDesc.pSslCertStoreName;
581 } 692 }
582 693
583 hr = StrAllocString(psczGuid, wzGuid, 0); 694 hr = WriteCertificateCaData(ctIpSsl, action, wzId, /*wzHost*/NULL, iPort, iHandleExisting, sczCertificateThumbprint ? sczCertificateThumbprint : L"", sczAppId ? sczAppId : L"", wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData);
584 ExitOnFailure(hr, "Failed to copy guid"); 695 ExitOnFailure(hr, "Failed to write custom action data for IP SSL Wix6HttpCertificate '%ls'", wzId);
585 696
586LExit: 697LExit:
698 ReleaseStr(sczAppId);
699 ReleaseStr(sczCertificateThumbprint);
700
587 return hr; 701 return hr;
588} 702}
589 703
@@ -601,7 +715,7 @@ static HRESULT AddSniSslCert(
601 DWORD er = ERROR_SUCCESS; 715 DWORD er = ERROR_SUCCESS;
602 HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { }; 716 HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { };
603 717
604 SetSniSslCertSetKey(&set.KeyDesc, wzHost, iPort); 718 SetSniSslCertificateKeyPort(&set.KeyDesc, wzHost, iPort);
605 set.ParamDesc.SslHashLength = cbCertificateThumbprint; 719 set.ParamDesc.SslHashLength = cbCertificateThumbprint;
606 set.ParamDesc.pSslHash = rgbCertificateThumbprint; 720 set.ParamDesc.pSslHash = rgbCertificateThumbprint;
607 set.ParamDesc.AppId = *pAppId; 721 set.ParamDesc.AppId = *pAppId;
@@ -620,38 +734,28 @@ static HRESULT AddSniSslCert(
620 return hr; 734 return hr;
621} 735}
622 736
623static HRESULT GetSniSslCert( 737static HRESULT AddIpSslCert(
624 __in_z LPWSTR wzHost, 738 __in_z LPCWSTR /*wzId*/,
625 __in int nPort, 739 __in int iPort,
626 __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet 740 __in BYTE rgbCertificateThumbprint[],
741 __in DWORD cbCertificateThumbprint,
742 __in GUID* pAppId,
743 __in_z LPWSTR wzSslCertStore
627) 744)
628{ 745{
629 HRESULT hr = S_OK; 746 HRESULT hr = S_OK;
630 DWORD er = ERROR_SUCCESS; 747 DWORD er = ERROR_SUCCESS;
631 HTTP_SERVICE_CONFIG_SSL_SNI_QUERY query = { }; 748 HTTP_SERVICE_CONFIG_SSL_SET set = { };
632 HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSet = NULL; 749 SOCKADDR_IN sin = { };
633 ULONG cbSet = 0;
634
635 *ppSet = NULL;
636
637 query.QueryDesc = HttpServiceConfigQueryExact;
638 SetSniSslCertSetKey(&query.KeyDesc, wzHost, nPort);
639
640 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL);
641 if (ERROR_INSUFFICIENT_BUFFER == er)
642 {
643 pSet = reinterpret_cast<HTTP_SERVICE_CONFIG_SSL_SNI_SET*>(MemAlloc(cbSet, TRUE));
644 ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query SN SSL certificate buffer");
645 750
646 er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL); 751 SetIpSslCertificateKeyPort(&set.KeyDesc, &sin, iPort);
647 } 752 set.ParamDesc.SslHashLength = cbCertificateThumbprint;
753 set.ParamDesc.pSslHash = rgbCertificateThumbprint;
754 set.ParamDesc.AppId = *pAppId;
755 set.ParamDesc.pSslCertStoreName = wzSslCertStore;
648 756
649 if (ERROR_SUCCESS == er) 757 er = ::HttpSetServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &set, sizeof(set), NULL);
650 { 758 if (ERROR_ALREADY_EXISTS == er)
651 *ppSet = pSet;
652 pSet = NULL;
653 }
654 else if (ERROR_FILE_NOT_FOUND == er)
655 { 759 {
656 hr = S_FALSE; 760 hr = S_FALSE;
657 } 761 }
@@ -660,14 +764,11 @@ static HRESULT GetSniSslCert(
660 hr = HRESULT_FROM_WIN32(er); 764 hr = HRESULT_FROM_WIN32(er);
661 } 765 }
662 766
663LExit:
664 ReleaseMem(pSet);
665
666 return hr; 767 return hr;
667} 768}
668 769
669static HRESULT RemoveSniSslCert( 770static HRESULT RemoveSniSslCert(
670 __in_z LPCWSTR /*wzId*/, 771 __in_z_opt LPCWSTR /*wzId*/,
671 __in_z LPWSTR wzHost, 772 __in_z LPWSTR wzHost,
672 __in int iPort 773 __in int iPort
673) 774)
@@ -676,10 +777,35 @@ static HRESULT RemoveSniSslCert(
676 DWORD er = ERROR_SUCCESS; 777 DWORD er = ERROR_SUCCESS;
677 HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { }; 778 HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { };
678 779
679 SetSniSslCertSetKey(&set.KeyDesc, wzHost, iPort); 780 SetSniSslCertificateKeyPort(&set.KeyDesc, wzHost, iPort);
680 781
681 er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL); 782 er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL);
682 if (ERROR_FILE_NOT_FOUND == er) 783 if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er)
784 {
785 hr = S_FALSE;
786 }
787 else
788 {
789 hr = HRESULT_FROM_WIN32(er);
790 }
791
792 return hr;
793}
794
795static HRESULT RemoveIpSslCert(
796 __in_z_opt LPCWSTR /*wzId*/,
797 __in int iPort
798)
799{
800 HRESULT hr = S_OK;
801 DWORD er = ERROR_SUCCESS;
802 HTTP_SERVICE_CONFIG_SSL_SET set = { };
803 SOCKADDR_IN sin = { };
804
805 SetIpSslCertificateKeyPort(&set.KeyDesc, &sin, iPort);
806
807 er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &set, sizeof(set), NULL);
808 if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er)
683 { 809 {
684 hr = S_FALSE; 810 hr = S_FALSE;
685 } 811 }
@@ -691,7 +817,7 @@ static HRESULT RemoveSniSslCert(
691 return hr; 817 return hr;
692} 818}
693 819
694static void SetSniSslCertSetKey( 820static void SetSniSslCertificateKeyPort(
695 __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey, 821 __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey,
696 __in_z LPWSTR wzHost, 822 __in_z LPWSTR wzHost,
697 __in int iPort 823 __in int iPort
@@ -702,3 +828,111 @@ static void SetSniSslCertSetKey(
702 pss->sin_family = AF_INET; 828 pss->sin_family = AF_INET;
703 pss->sin_port = htons(static_cast<USHORT>(iPort)); 829 pss->sin_port = htons(static_cast<USHORT>(iPort));
704} 830}
831
832static void SetIpSslCertificateKeyPort(
833 __in HTTP_SERVICE_CONFIG_SSL_KEY* pKey,
834 __in SOCKADDR_IN* pSin,
835 __in int iPort
836)
837{
838 pSin->sin_family = AF_INET;
839 pSin->sin_port = htons(static_cast<USHORT>(iPort));
840 pKey->pIpPort = reinterpret_cast<PSOCKADDR>(pSin);
841}
842
843static HRESULT EnsureAppId(
844 __inout_z LPWSTR* psczAppId,
845 __in_opt GUID* pGuid
846)
847{
848 HRESULT hr = S_OK;
849 GUID guid = { };
850
851 if (!psczAppId || !*psczAppId || !**psczAppId)
852 {
853 if (pGuid)
854 {
855 hr = StringFromGuid(*pGuid, psczAppId);
856 ExitOnFailure(hr, "Failed to ensure AppId guid");
857 }
858 else
859 {
860 hr = HRESULT_FROM_RPC(::UuidCreate(&guid));
861 ExitOnRootFailure(hr, "Failed to create guid for AppId");
862
863 hr = StringFromGuid(guid, psczAppId);
864 ExitOnFailure(hr, "Failed to ensure AppId guid");
865 }
866 }
867
868LExit:
869 return hr;
870}
871
872static HRESULT StringFromGuid(
873 __in REFGUID rguid,
874 __inout_z LPWSTR* psczGuid
875)
876{
877 HRESULT hr = S_OK;
878 WCHAR wzGuid[39];
879
880 if (!::StringFromGUID2(rguid, wzGuid, countof(wzGuid)))
881 {
882 hr = E_OUTOFMEMORY;
883 ExitOnRootFailure(hr, "Failed to convert guid into string");
884 }
885
886 hr = StrAllocString(psczGuid, wzGuid, 0);
887 ExitOnFailure(hr, "Failed to copy guid");
888
889LExit:
890 return hr;
891}
892
893static HRESULT WriteCertificateCaData(
894 __in eCertificateType certType,
895 __in WCA_TODO action,
896 __in_z LPCWSTR wzId,
897 __in_z_opt LPCWSTR wzHost,
898 __in int iPort,
899 __in int iHandleExisting,
900 __in_z LPCWSTR wzCertificateThumbprint,
901 __in_z_opt LPCWSTR wzAppId,
902 __in_z_opt LPCWSTR wzCertificateStore,
903 __inout_z LPWSTR* psczCustomActionData
904)
905{
906 HRESULT hr = S_OK;
907
908 hr = WcaWriteIntegerToCaData(certType, psczCustomActionData);
909 ExitOnFailure(hr, "Failed to write IP SSL certificate type to custom action data");
910
911 hr = WcaWriteIntegerToCaData(action, psczCustomActionData);
912 ExitOnFailure(hr, "Failed to write action to custom action data");
913
914 hr = WcaWriteStringToCaData(wzId, psczCustomActionData);
915 ExitOnFailure(hr, "Failed to write id to custom action data");
916
917 hr = WcaWriteStringToCaData(wzHost ? wzHost : L"", psczCustomActionData);
918 ExitOnFailure(hr, "Failed to write Host to custom action data");
919
920 hr = WcaWriteIntegerToCaData(iPort, psczCustomActionData);
921 ExitOnFailure(hr, "Failed to write Port to custom action data");
922
923 hr = WcaWriteIntegerToCaData(iHandleExisting, psczCustomActionData);
924 ExitOnFailure(hr, "Failed to write HandleExisting to custom action data");
925
926 hr = WcaWriteStringToCaData(wzCertificateThumbprint, psczCustomActionData);
927 ExitOnFailure(hr, "Failed to write CertificateThumbprint to custom action data");
928
929 hr = WcaWriteStringToCaData(wzAppId ? wzAppId : L"", psczCustomActionData);
930 ExitOnFailure(hr, "Failed to write AppId to custom action data");
931
932 hr = WcaWriteStringToCaData(wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData);
933 ExitOnFailure(hr, "Failed to write CertificateStore to custom action data");
934
935LExit:
936 return hr;
937}
938
diff --git a/src/ext/Http/ca/precomp.h b/src/ext/Http/ca/precomp.h
index 42287cb2..bbd79ccf 100644
--- a/src/ext/Http/ca/precomp.h
+++ b/src/ext/Http/ca/precomp.h
@@ -23,3 +23,9 @@ enum eHandleExisting
23 heIgnore = 1, 23 heIgnore = 1,
24 heFail = 2 24 heFail = 2
25}; 25};
26
27enum eCertificateType
28{
29 ctSniSsl = 0,
30 ctIpSsl = 1,
31};
diff --git a/src/ext/Http/ca/wixhttpca.def b/src/ext/Http/ca/wixhttpca.def
index 281c5631..244bd987 100644
--- a/src/ext/Http/ca/wixhttpca.def
+++ b/src/ext/Http/ca/wixhttpca.def
@@ -7,6 +7,6 @@ EXPORTS
7 SchedHttpUrlReservationsInstall 7 SchedHttpUrlReservationsInstall
8 SchedHttpUrlReservationsUninstall 8 SchedHttpUrlReservationsUninstall
9 ExecHttpUrlReservations 9 ExecHttpUrlReservations
10 SchedHttpSniSslCertsInstall 10 SchedHttpCertificatesInstall
11 SchedHttpSniSslCertsUninstall 11 SchedHttpCertificatesUninstall
12 ExecHttpSniSslCerts 12 ExecHttpCertificates
diff --git a/src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs b/src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs
index 14b40bc8..ffd698f5 100644
--- a/src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs
+++ b/src/ext/Http/test/WixToolsetTest.Http/HttpExtensionFixture.cs
@@ -10,21 +10,22 @@ namespace WixToolsetTest.Http
10 public class HttpExtensionFixture 10 public class HttpExtensionFixture
11 { 11 {
12 [Fact] 12 [Fact]
13 public void CanBuildUsingSniSssl() 13 public void CanBuildUsingSsl()
14 { 14 {
15 var folder = TestData.Get("TestData", "SniSsl"); 15 var folder = TestData.Get("TestData", "Ssl");
16 var build = new Builder(folder, typeof(HttpExtensionFactory), new[] { folder }); 16 var build = new Builder(folder, typeof(HttpExtensionFactory), new[] { folder });
17 17
18 var results = build.BuildAndQuery(Build, "CustomAction", "Wix4HttpSniSslCert"); 18 var results = build.BuildAndQuery(Build, "CustomAction", "Wix6HttpCertificate");
19 WixAssert.CompareLineByLine(new[] 19 WixAssert.CompareLineByLine(new[]
20 { 20 {
21 "CustomAction:Wix4ExecHttpSniSslCertsInstall_X86\t3073\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", 21 "CustomAction:Wix6ExecHttpCertificatesInstall_X86\t3073\tWix6HttpCA_X86\tExecHttpCertificates\t",
22 "CustomAction:Wix4ExecHttpSniSslCertsUninstall_X86\t3073\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", 22 "CustomAction:Wix6ExecHttpCertificatesUninstall_X86\t3073\tWix6HttpCA_X86\tExecHttpCertificates\t",
23 "CustomAction:Wix4RollbackHttpSniSslCertsInstall_X86\t3329\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", 23 "CustomAction:Wix6RollbackHttpCertificatesInstall_X86\t3329\tWix6HttpCA_X86\tExecHttpCertificates\t",
24 "CustomAction:Wix4RollbackHttpSniSslCertsUninstall_X86\t3329\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", 24 "CustomAction:Wix6RollbackHttpCertificatesUninstall_X86\t3329\tWix6HttpCA_X86\tExecHttpCertificates\t",
25 "CustomAction:Wix4SchedHttpSniSslCertsInstall_X86\t1\tWix4HttpCA_X86\tSchedHttpSniSslCertsInstall\t", 25 "CustomAction:Wix6SchedHttpCertificatesInstall_X86\t1\tWix6HttpCA_X86\tSchedHttpCertificatesInstall\t",
26 "CustomAction:Wix4SchedHttpSniSslCertsUninstall_X86\t1\tWix4HttpCA_X86\tSchedHttpSniSslCertsUninstall\t", 26 "CustomAction:Wix6SchedHttpCertificatesUninstall_X86\t1\tWix6HttpCA_X86\tSchedHttpCertificatesUninstall\t",
27 "Wix4HttpSniSslCert:sslC9YX6_H7UL_WGBx4DoDGI.Sj.D0\texample.com\t8080\t[SOME_THUMBPRINT]\t\t\t2\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo", 27 "Wix6HttpCertificate:ipsFO5EwsJKZPxl2W2V1nI59m1pDQs\t\t[PORTMANTEAU]\t[SOME_OTHER_THUMBPRINT]\t\t\t0\t1\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo",
28 "Wix6HttpCertificate:sniC9YX6_H7UL_WGBx4DoDGI.Sj.D0\texample.com\t8080\t[SOME_THUMBPRINT]\t\t\t2\t0\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo",
28 }, results); 29 }, results);
29 } 30 }
30 31
@@ -37,12 +38,12 @@ namespace WixToolsetTest.Http
37 var results = build.BuildAndQuery(Build, "CustomAction", "Wix4HttpUrlAce", "Wix4HttpUrlReservation"); 38 var results = build.BuildAndQuery(Build, "CustomAction", "Wix4HttpUrlAce", "Wix4HttpUrlReservation");
38 WixAssert.CompareLineByLine(new[] 39 WixAssert.CompareLineByLine(new[]
39 { 40 {
40 "CustomAction:Wix4ExecHttpUrlReservationsInstall_X86\t3073\tWix4HttpCA_X86\tExecHttpUrlReservations\t", 41 "CustomAction:Wix4ExecHttpUrlReservationsInstall_X86\t3073\tWix6HttpCA_X86\tExecHttpUrlReservations\t",
41 "CustomAction:Wix4ExecHttpUrlReservationsUninstall_X86\t3073\tWix4HttpCA_X86\tExecHttpUrlReservations\t", 42 "CustomAction:Wix4ExecHttpUrlReservationsUninstall_X86\t3073\tWix6HttpCA_X86\tExecHttpUrlReservations\t",
42 "CustomAction:Wix4RollbackHttpUrlReservationsInstall_X86\t3329\tWix4HttpCA_X86\tExecHttpUrlReservations\t", 43 "CustomAction:Wix4RollbackHttpUrlReservationsInstall_X86\t3329\tWix6HttpCA_X86\tExecHttpUrlReservations\t",
43 "CustomAction:Wix4RollbackHttpUrlReservationsUninstall_X86\t3329\tWix4HttpCA_X86\tExecHttpUrlReservations\t", 44 "CustomAction:Wix4RollbackHttpUrlReservationsUninstall_X86\t3329\tWix6HttpCA_X86\tExecHttpUrlReservations\t",
44 "CustomAction:Wix4SchedHttpUrlReservationsInstall_X86\t1\tWix4HttpCA_X86\tSchedHttpUrlReservationsInstall\t", 45 "CustomAction:Wix4SchedHttpUrlReservationsInstall_X86\t1\tWix6HttpCA_X86\tSchedHttpUrlReservationsInstall\t",
45 "CustomAction:Wix4SchedHttpUrlReservationsUninstall_X86\t1\tWix4HttpCA_X86\tSchedHttpUrlReservationsUninstall\t", 46 "CustomAction:Wix4SchedHttpUrlReservationsUninstall_X86\t1\tWix6HttpCA_X86\tSchedHttpUrlReservationsUninstall\t",
46 "Wix4HttpUrlAce:aceu5os2gQoblRmzwjt85LQf997uD4\turlO23FkY2xzEY54lY6E6sXFW6glXc\tNT SERVICE\\TestService\t268435456", 47 "Wix4HttpUrlAce:aceu5os2gQoblRmzwjt85LQf997uD4\turlO23FkY2xzEY54lY6E6sXFW6glXc\tNT SERVICE\\TestService\t268435456",
47 "Wix4HttpUrlReservation:urlO23FkY2xzEY54lY6E6sXFW6glXc\t0\t\thttp://+:80/vroot/\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo", 48 "Wix4HttpUrlReservation:urlO23FkY2xzEY54lY6E6sXFW6glXc\t0\t\thttp://+:80/vroot/\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo",
48 }, results); 49 }, results);
@@ -50,8 +51,7 @@ namespace WixToolsetTest.Http
50 51
51 private static void Build(string[] args) 52 private static void Build(string[] args)
52 { 53 {
53 var result = WixRunner.Execute(args) 54 /*var result =*/ WixRunner.Execute(args).AssertSuccess();
54 .AssertSuccess();
55 } 55 }
56 } 56 }
57} 57}
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs
deleted file mode 100644
index f0aae485..00000000
--- a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs
+++ /dev/null
@@ -1,12 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:http="http://wixtoolset.org/schemas/v4/wxs/http">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
6 <Component>
7 <File Source="example.txt" />
8 <http:SniSslCertificate Host="example.com" Port="8080" Thumbprint="[SOME_THUMBPRINT]" HandleExisting="fail" />
9 </Component>
10 </ComponentGroup>
11 </Fragment>
12</Wix>
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.en-us.wxl
index f1df1234..f1df1234 100644
--- a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.en-us.wxl
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.wxs
index c85e9bba..69bdbccb 100644
--- a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.wxs
@@ -1,6 +1,6 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a"> 2 <Package Name="MsiPackage" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3 <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" /> 3 <MediaTemplate EmbedCab="yes" />
4 4
5 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)"> 5 <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
6 <ComponentGroupRef Id="ProductComponents" /> 6 <ComponentGroupRef Id="ProductComponents" />
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/PackageComponents.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/PackageComponents.wxs
new file mode 100644
index 00000000..126d2944
--- /dev/null
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/PackageComponents.wxs
@@ -0,0 +1,17 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3 xmlns:http="http://wixtoolset.org/schemas/v4/wxs/http">
4 <Fragment>
5 <Property Id="PORTMANTEAU" Value="8088" />
6 <Property Id="SOME_THUMBPRINT" Value="8E64C2AB0A9F730C7D06C58441362A6376BD72FB" />
7 <Property Id="SOME_OTHER_THUMBPRINT" Value="14C1B207A930E29AE34778F3CE0680A1811E1AE1" />
8
9 <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
10 <Component>
11 <File Source="example.txt" />
12 <http:SniSslCertificate Host="example.com" Port="8080" Thumbprint="[SOME_THUMBPRINT]" HandleExisting="fail" />
13 <http:SslCertificate Port="[PORTMANTEAU]" Thumbprint="[SOME_OTHER_THUMBPRINT]" HandleExisting="replace" />
14 </Component>
15 </ComponentGroup>
16 </Fragment>
17</Wix>
diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/example.txt
index 1b4ffe8a..1b4ffe8a 100644
--- a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt
+++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/example.txt
diff --git a/src/ext/Http/wixext/HttpCompiler.cs b/src/ext/Http/wixext/HttpCompiler.cs
index 51fdfebc..27ddeb0e 100644
--- a/src/ext/Http/wixext/HttpCompiler.cs
+++ b/src/ext/Http/wixext/HttpCompiler.cs
@@ -49,7 +49,11 @@ namespace WixToolset.Http
49 switch (element.Name.LocalName) 49 switch (element.Name.LocalName)
50 { 50 {
51 case "SniSslCertificate": 51 case "SniSslCertificate":
52 this.ParseSniSslCertificateElement(intermediate, section, element, componentId); 52 this.ParseCertificateElement(intermediate, section, element, componentId, CertificateType.SniSsl);
53 break;
54
55 case "SslCertificate":
56 this.ParseCertificateElement(intermediate, section, element, componentId, CertificateType.IpSsl);
53 break; 57 break;
54 58
55 case "UrlReservation": 59 case "UrlReservation":
@@ -71,7 +75,7 @@ namespace WixToolset.Http
71 /// </summary> 75 /// </summary>
72 /// <param name="node">The element to parse.</param> 76 /// <param name="node">The element to parse.</param>
73 /// <param name="componentId">Identifier of the component that owns this SNI SSL Certificate.</param> 77 /// <param name="componentId">Identifier of the component that owns this SNI SSL Certificate.</param>
74 private void ParseSniSslCertificateElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId) 78 private void ParseCertificateElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId, CertificateType type)
75 { 79 {
76 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); 80 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node);
77 Identifier id = null; 81 Identifier id = null;
@@ -138,13 +142,25 @@ namespace WixToolset.Http
138 // Need the element ID for child element processing, so generate now if not authored. 142 // Need the element ID for child element processing, so generate now if not authored.
139 if (null == id) 143 if (null == id)
140 { 144 {
141 id = this.ParseHelper.CreateIdentifier("ssl", componentId, host, port); 145 var prefix = type == CertificateType.IpSsl ? "ips" : "sni";
146
147 id = this.ParseHelper.CreateIdentifier(prefix, componentId, host, port);
142 } 148 }
143 149
144 // Required attributes. 150 // Required attributes.
145 if (null == host) 151 if (null == host)
146 { 152 {
147 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Host")); 153 if (type == CertificateType.SniSsl)
154 {
155 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Host"));
156 }
157 }
158 else
159 {
160 if (type == CertificateType.IpSsl)
161 {
162 this.Messaging.Write(ErrorMessages.IllegalAttributeExceptOnElement(sourceLineNumbers, node.Name.LocalName, "Host", "SniSslCertificate"));
163 }
148 } 164 }
149 165
150 if (null == port) 166 if (null == port)
@@ -162,7 +178,7 @@ namespace WixToolset.Http
162 178
163 if (!this.Messaging.EncounteredError) 179 if (!this.Messaging.EncounteredError)
164 { 180 {
165 section.AddSymbol(new WixHttpSniSslCertSymbol(sourceLineNumbers, id) 181 section.AddSymbol(new HttpCertificateSymbol(sourceLineNumbers, id)
166 { 182 {
167 Host = host, 183 Host = host,
168 Port = port, 184 Port = port,
@@ -170,11 +186,12 @@ namespace WixToolset.Http
170 AppId = appId, 186 AppId = appId,
171 Store = store, 187 Store = store,
172 HandleExisting = handleExisting, 188 HandleExisting = handleExisting,
189 CertificateType = type,
173 ComponentRef = componentId, 190 ComponentRef = componentId,
174 }); 191 });
175 192
176 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpSniSslCertsInstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); 193 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix6SchedHttpCertificatesInstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
177 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpSniSslCertsUninstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); 194 this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix6SchedHttpCertificatesUninstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64);
178 } 195 }
179 } 196 }
180 197
diff --git a/src/ext/Http/wixext/HttpTableDefinitions.cs b/src/ext/Http/wixext/HttpTableDefinitions.cs
index ea08337f..ac469b47 100644
--- a/src/ext/Http/wixext/HttpTableDefinitions.cs
+++ b/src/ext/Http/wixext/HttpTableDefinitions.cs
@@ -6,18 +6,19 @@ namespace WixToolset.Http
6 6
7 public static class HttpTableDefinitions 7 public static class HttpTableDefinitions
8 { 8 {
9 public static readonly TableDefinition WixHttpSniSslCert = new TableDefinition( 9 public static readonly TableDefinition HttpCertificate = new TableDefinition(
10 "Wix4HttpSniSslCert", 10 "Wix6HttpCertificate",
11 HttpSymbolDefinitions.WixHttpSniSslCert, 11 HttpSymbolDefinitions.HttpCertificate,
12 new[] 12 new[]
13 { 13 {
14 new ColumnDefinition("Wix4HttpSniSslCert", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column), 14 new ColumnDefinition("HttpCertificate", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column),
15 new ColumnDefinition("Host", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Host for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), 15 new ColumnDefinition("Host", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Host for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
16 new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Port for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), 16 new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Port for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
17 new ColumnDefinition("Thumbprint", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "humbprint of the SNI SSL certificate to find.", modularizeType: ColumnModularizeType.Property), 17 new ColumnDefinition("Thumbprint", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "humbprint of the SNI SSL certificate to find.", modularizeType: ColumnModularizeType.Property),
18 new ColumnDefinition("AppId", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), 18 new ColumnDefinition("AppId", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
19 new ColumnDefinition("Store", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), 19 new ColumnDefinition("Store", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property),
20 new ColumnDefinition("HandleExisting", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2, description: "The behavior when trying to install a SNI SSL certificate and it already exists."), 20 new ColumnDefinition("HandleExisting", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 2, description: "The behavior when trying to install a SNI SSL certificate and it already exists."),
21 new ColumnDefinition("Type", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 1, description: "0: SNI; 1: non-SNI"),
21 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key into the Component table referencing the component that controls the URL reservation.", modularizeType: ColumnModularizeType.Column), 22 new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key into the Component table referencing the component that controls the URL reservation.", modularizeType: ColumnModularizeType.Column),
22 }, 23 },
23 symbolIdIsPrimaryKey: true 24 symbolIdIsPrimaryKey: true
@@ -52,7 +53,7 @@ namespace WixToolset.Http
52 53
53 public static readonly TableDefinition[] All = new[] 54 public static readonly TableDefinition[] All = new[]
54 { 55 {
55 WixHttpSniSslCert, 56 HttpCertificate,
56 WixHttpUrlReservation, 57 WixHttpUrlReservation,
57 WixHttpUrlAce, 58 WixHttpUrlAce,
58 }; 59 };
diff --git a/src/ext/Http/wixext/Symbols/CertificateType.cs b/src/ext/Http/wixext/Symbols/CertificateType.cs
new file mode 100644
index 00000000..1e57ff13
--- /dev/null
+++ b/src/ext/Http/wixext/Symbols/CertificateType.cs
@@ -0,0 +1,13 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Http.Symbols
4{
5 /// <summary>
6 /// Must match constants in httpcerts.cpp
7 /// </summary>
8 public enum CertificateType
9 {
10 SniSsl = 0,
11 IpSsl = 1,
12 }
13}
diff --git a/src/ext/Http/wixext/Symbols/HttpCertificateSymbol.cs b/src/ext/Http/wixext/Symbols/HttpCertificateSymbol.cs
new file mode 100644
index 00000000..1e361b54
--- /dev/null
+++ b/src/ext/Http/wixext/Symbols/HttpCertificateSymbol.cs
@@ -0,0 +1,103 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Http
4{
5 using WixToolset.Data;
6 using WixToolset.Http.Symbols;
7
8 public static partial class HttpSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition HttpCertificate = new IntermediateSymbolDefinition(
11 HttpSymbolDefinitionType.HttpCertificate.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Host), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Port), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Thumbprint), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.AppId), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Store), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.HandleExisting), IntermediateFieldType.Number),
20 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.CertificateType), IntermediateFieldType.Number),
21 new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.ComponentRef), IntermediateFieldType.String),
22 },
23 typeof(HttpCertificateSymbol));
24 }
25}
26
27namespace WixToolset.Http.Symbols
28{
29 using WixToolset.Data;
30
31 public enum HttpCertificateSymbolFields
32 {
33 Host,
34 Port,
35 Thumbprint,
36 AppId,
37 Store,
38 HandleExisting,
39 CertificateType,
40 ComponentRef,
41 }
42
43 public class HttpCertificateSymbol : IntermediateSymbol
44 {
45 public HttpCertificateSymbol() : base(HttpSymbolDefinitions.HttpCertificate, null, null)
46 {
47 }
48
49 public HttpCertificateSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(HttpSymbolDefinitions.HttpCertificate, sourceLineNumber, id)
50 {
51 }
52
53 public IntermediateField this[HttpCertificateSymbolFields index] => this.Fields[(int)index];
54
55 public string Host
56 {
57 get => this.Fields[(int)HttpCertificateSymbolFields.Host].AsString();
58 set => this.Set((int)HttpCertificateSymbolFields.Host, value);
59 }
60
61 public string Port
62 {
63 get => this.Fields[(int)HttpCertificateSymbolFields.Port].AsString();
64 set => this.Set((int)HttpCertificateSymbolFields.Port, value);
65 }
66
67 public string Thumbprint
68 {
69 get => this.Fields[(int)HttpCertificateSymbolFields.Thumbprint].AsString();
70 set => this.Set((int)HttpCertificateSymbolFields.Thumbprint, value);
71 }
72
73 public string AppId
74 {
75 get => this.Fields[(int)HttpCertificateSymbolFields.AppId].AsString();
76 set => this.Set((int)HttpCertificateSymbolFields.AppId, value);
77 }
78
79 public string Store
80 {
81 get => this.Fields[(int)HttpCertificateSymbolFields.Store].AsString();
82 set => this.Set((int)HttpCertificateSymbolFields.Store, value);
83 }
84
85 public HandleExisting HandleExisting
86 {
87 get => (HandleExisting)this.Fields[(int)HttpCertificateSymbolFields.HandleExisting].AsNumber();
88 set => this.Set((int)HttpCertificateSymbolFields.HandleExisting, (int)value);
89 }
90
91 public CertificateType CertificateType
92 {
93 get => (CertificateType)this.Fields[(int)HttpCertificateSymbolFields.CertificateType].AsNumber();
94 set => this.Set((int)HttpCertificateSymbolFields.CertificateType, (int)value);
95 }
96
97 public string ComponentRef
98 {
99 get => this.Fields[(int)HttpCertificateSymbolFields.ComponentRef].AsString();
100 set => this.Set((int)HttpCertificateSymbolFields.ComponentRef, value);
101 }
102 }
103}
diff --git a/src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs b/src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs
index ff46ce3b..37a7abf0 100644
--- a/src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs
+++ b/src/ext/Http/wixext/Symbols/HttpSymbolDefinitions.cs
@@ -7,7 +7,7 @@ namespace WixToolset.Http
7 7
8 public enum HttpSymbolDefinitionType 8 public enum HttpSymbolDefinitionType
9 { 9 {
10 WixHttpSniSslCert, 10 HttpCertificate,
11 WixHttpUrlAce, 11 WixHttpUrlAce,
12 WixHttpUrlReservation, 12 WixHttpUrlReservation,
13 } 13 }
@@ -28,8 +28,8 @@ namespace WixToolset.Http
28 { 28 {
29 switch (type) 29 switch (type)
30 { 30 {
31 case HttpSymbolDefinitionType.WixHttpSniSslCert: 31 case HttpSymbolDefinitionType.HttpCertificate:
32 return HttpSymbolDefinitions.WixHttpSniSslCert; 32 return HttpSymbolDefinitions.HttpCertificate;
33 33
34 case HttpSymbolDefinitionType.WixHttpUrlAce: 34 case HttpSymbolDefinitionType.WixHttpUrlAce:
35 return HttpSymbolDefinitions.WixHttpUrlAce; 35 return HttpSymbolDefinitions.WixHttpUrlAce;
diff --git a/src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs b/src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs
deleted file mode 100644
index ec67a089..00000000
--- a/src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs
+++ /dev/null
@@ -1,95 +0,0 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Http
4{
5 using WixToolset.Data;
6 using WixToolset.Http.Symbols;
7
8 public static partial class HttpSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition WixHttpSniSslCert = new IntermediateSymbolDefinition(
11 HttpSymbolDefinitionType.WixHttpSniSslCert.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Host), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Port), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Thumbprint), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.AppId), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Store), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.HandleExisting), IntermediateFieldType.Number),
20 new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.ComponentRef), IntermediateFieldType.String),
21 },
22 typeof(WixHttpSniSslCertSymbol));
23 }
24}
25
26namespace WixToolset.Http.Symbols
27{
28 using WixToolset.Data;
29
30 public enum WixHttpSniSslCertSymbolFields
31 {
32 Host,
33 Port,
34 Thumbprint,
35 AppId,
36 Store,
37 HandleExisting,
38 ComponentRef,
39 }
40
41 public class WixHttpSniSslCertSymbol : IntermediateSymbol
42 {
43 public WixHttpSniSslCertSymbol() : base(HttpSymbolDefinitions.WixHttpSniSslCert, null, null)
44 {
45 }
46
47 public WixHttpSniSslCertSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(HttpSymbolDefinitions.WixHttpSniSslCert, sourceLineNumber, id)
48 {
49 }
50
51 public IntermediateField this[WixHttpSniSslCertSymbolFields index] => this.Fields[(int)index];
52
53 public string Host
54 {
55 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Host].AsString();
56 set => this.Set((int)WixHttpSniSslCertSymbolFields.Host, value);
57 }
58
59 public string Port
60 {
61 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Port].AsString();
62 set => this.Set((int)WixHttpSniSslCertSymbolFields.Port, value);
63 }
64
65 public string Thumbprint
66 {
67 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Thumbprint].AsString();
68 set => this.Set((int)WixHttpSniSslCertSymbolFields.Thumbprint, value);
69 }
70
71 public string AppId
72 {
73 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.AppId].AsString();
74 set => this.Set((int)WixHttpSniSslCertSymbolFields.AppId, value);
75 }
76
77 public string Store
78 {
79 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Store].AsString();
80 set => this.Set((int)WixHttpSniSslCertSymbolFields.Store, value);
81 }
82
83 public HandleExisting HandleExisting
84 {
85 get => (HandleExisting)this.Fields[(int)WixHttpSniSslCertSymbolFields.HandleExisting].AsNumber();
86 set => this.Set((int)WixHttpSniSslCertSymbolFields.HandleExisting, (int)value);
87 }
88
89 public string ComponentRef
90 {
91 get => this.Fields[(int)WixHttpSniSslCertSymbolFields.ComponentRef].AsString();
92 set => this.Set((int)WixHttpSniSslCertSymbolFields.ComponentRef, value);
93 }
94 }
95}
diff --git a/src/ext/Http/wixlib/HttpExtension_Platform.wxi b/src/ext/Http/wixlib/HttpExtension_Platform.wxi
index d0a1b33d..d3000d42 100644
--- a/src/ext/Http/wixlib/HttpExtension_Platform.wxi
+++ b/src/ext/Http/wixlib/HttpExtension_Platform.wxi
@@ -15,50 +15,44 @@
15 <ProgressText Action="$(var.Prefix)ExecHttpUrlReservationsUninstall$(var.Suffix)" Message="!(loc.WixExecHttpUrlReservationsUninstall)" /> 15 <ProgressText Action="$(var.Prefix)ExecHttpUrlReservationsUninstall$(var.Suffix)" Message="!(loc.WixExecHttpUrlReservationsUninstall)" />
16 </UI> 16 </UI>
17 17
18 <CustomAction Id="$(var.Prefix)SchedHttpUrlReservationsInstall$(var.Suffix)" DllEntry="SchedHttpUrlReservationsInstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" /> 18 <CustomAction Id="$(var.Prefix)SchedHttpUrlReservationsInstall$(var.Suffix)" DllEntry="SchedHttpUrlReservationsInstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" />
19 <CustomAction Id="$(var.Prefix)SchedHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="SchedHttpUrlReservationsUninstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" /> 19 <CustomAction Id="$(var.Prefix)SchedHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="SchedHttpUrlReservationsUninstall" Execute="immediate" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" />
20 <CustomAction Id="$(var.Prefix)RollbackHttpUrlReservationsInstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" /> 20 <CustomAction Id="$(var.Prefix)RollbackHttpUrlReservationsInstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" />
21 <CustomAction Id="$(var.Prefix)ExecHttpUrlReservationsInstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" /> 21 <CustomAction Id="$(var.Prefix)ExecHttpUrlReservationsInstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" />
22 <CustomAction Id="$(var.Prefix)RollbackHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" /> 22 <CustomAction Id="$(var.Prefix)RollbackHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" />
23 <CustomAction Id="$(var.Prefix)ExecHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" /> 23 <CustomAction Id="$(var.Prefix)ExecHttpUrlReservationsUninstall$(var.Suffix)" DllEntry="ExecHttpUrlReservations" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" />
24 24
25 <!--
26 We need the HTTP server on Windows XP SP2 or later.
27 -->
28 <InstallExecuteSequence> 25 <InstallExecuteSequence>
29 <Custom Action="virtual $(var.Prefix)SchedHttpUrlReservationsUninstall$(var.Suffix)" Before="RemoveFiles" Condition="VersionNT &gt;= 600 OR (VersionNT &gt;= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel &gt;= 2) OR (MsiNTProductType &gt; 1)))" /> 26 <Custom Action="virtual $(var.Prefix)SchedHttpUrlReservationsUninstall$(var.Suffix)" Before="RemoveFiles" />
30 <Custom Action="virtual $(var.Prefix)SchedHttpUrlReservationsInstall$(var.Suffix)" After="InstallFiles" Condition="VersionNT &gt;= 600 OR (VersionNT &gt;= 501 AND ((MsiNTProductType = 1 AND ServicePackLevel &gt;= 2) OR (MsiNTProductType &gt; 1)))" /> 27 <Custom Action="virtual $(var.Prefix)SchedHttpUrlReservationsInstall$(var.Suffix)" After="InstallFiles" />
31 </InstallExecuteSequence> 28 </InstallExecuteSequence>
32 </Fragment> 29 </Fragment>
33 30
34 <Fragment> 31 <Fragment>
35 <UIRef Id="WixHttpErrors" /> 32 <UIRef Id="WixHttpErrors" />
36 <UI> 33 <UI>
37 <ProgressText Action="$(var.Prefix)SchedHttpSniSslCertsInstall$(var.Suffix)" Message="!(loc.WixSchedHttpSniSslCertsInstall)" /> 34 <ProgressText Action="$(var.Prefix6)SchedHttpCertificatesInstall$(var.Suffix)" Message="!(loc.SchedHttpCertificatesInstall)" />
38 <ProgressText Action="$(var.Prefix)SchedHttpSniSslCertsUninstall$(var.Suffix)" Message="!(loc.WixSchedHttpSniSslCertsUninstall)" /> 35 <ProgressText Action="$(var.Prefix6)SchedHttpCertificatesUninstall$(var.Suffix)" Message="!(loc.SchedHttpCertificatesUninstall)" />
39 <ProgressText Action="$(var.Prefix)RollbackHttpSniSslCertsInstall$(var.Suffix)" Message="!(loc.WixRollbackHttpSniSslCertsInstall)" /> 36 <ProgressText Action="$(var.Prefix6)RollbackHttpCertificatesInstall$(var.Suffix)" Message="!(loc.RollbackHttpCertificatesInstall)" />
40 <ProgressText Action="$(var.Prefix)ExecHttpSniSslCertsInstall$(var.Suffix)" Message="!(loc.WixExecHttpSniSslCertsInstall)" /> 37 <ProgressText Action="$(var.Prefix6)ExecHttpCertificatesInstall$(var.Suffix)" Message="!(loc.ExecHttpCertificatesInstall)" />
41 <ProgressText Action="$(var.Prefix)RollbackHttpSniSslCertsUninstall$(var.Suffix)" Message="!(loc.WixRollbackHttpSniSslCertsUninstall)" /> 38 <ProgressText Action="$(var.Prefix6)RollbackHttpCertificatesUninstall$(var.Suffix)" Message="!(loc.RollbackHttpCertificatesUninstall)" />
42 <ProgressText Action="$(var.Prefix)ExecHttpSniSslCertsUninstall$(var.Suffix)" Message="!(loc.WixExecHttpSniSslCertsUninstall)" /> 39 <ProgressText Action="$(var.Prefix6)ExecHttpCertificatesUninstall$(var.Suffix)" Message="!(loc.ExecHttpCertificatesUninstall)" />
43 </UI> 40 </UI>
44 41
45 <CustomAction Id="$(var.Prefix)SchedHttpSniSslCertsInstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="SchedHttpSniSslCertsInstall" Execute="immediate" Return="check" SuppressModularization="yes" /> 42 <CustomAction Id="$(var.Prefix6)SchedHttpCertificatesInstall$(var.Suffix)" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" DllEntry="SchedHttpCertificatesInstall" Execute="immediate" Return="check" SuppressModularization="yes" />
46 <CustomAction Id="$(var.Prefix)SchedHttpSniSslCertsUninstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="SchedHttpSniSslCertsUninstall" Execute="immediate" Return="check" SuppressModularization="yes" /> 43 <CustomAction Id="$(var.Prefix6)SchedHttpCertificatesUninstall$(var.Suffix)" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" DllEntry="SchedHttpCertificatesUninstall" Execute="immediate" Return="check" SuppressModularization="yes" />
47 <CustomAction Id="$(var.Prefix)RollbackHttpSniSslCertsInstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" /> 44 <CustomAction Id="$(var.Prefix6)RollbackHttpCertificatesInstall$(var.Suffix)" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" DllEntry="ExecHttpCertificates" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
48 <CustomAction Id="$(var.Prefix)ExecHttpSniSslCertsInstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" /> 45 <CustomAction Id="$(var.Prefix6)ExecHttpCertificatesInstall$(var.Suffix)" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" DllEntry="ExecHttpCertificates" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
49 <CustomAction Id="$(var.Prefix)RollbackHttpSniSslCertsUninstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" /> 46 <CustomAction Id="$(var.Prefix6)RollbackHttpCertificatesUninstall$(var.Suffix)" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" DllEntry="ExecHttpCertificates" Execute="rollback" Impersonate="no" Return="check" SuppressModularization="yes" />
50 <CustomAction Id="$(var.Prefix)ExecHttpSniSslCertsUninstall$(var.Suffix)" BinaryRef="$(var.Prefix)HttpCA$(var.Suffix)" DllEntry="ExecHttpSniSslCerts" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" /> 47 <CustomAction Id="$(var.Prefix6)ExecHttpCertificatesUninstall$(var.Suffix)" BinaryRef="$(var.Prefix6)HttpCA$(var.Suffix)" DllEntry="ExecHttpCertificates" Execute="deferred" Impersonate="no" Return="check" SuppressModularization="yes" />
51 48
52 <!--
53 We need HTTP.SYS on Windows 8 or later for SNI SSL support.
54 -->
55 <InstallExecuteSequence> 49 <InstallExecuteSequence>
56 <Custom Action="virtual $(var.Prefix)SchedHttpSniSslCertsUninstall$(var.Suffix)" Before="RemoveFiles" Condition="VersionNT >= 602" /> 50 <Custom Action="virtual $(var.Prefix6)SchedHttpCertificatesInstall$(var.Suffix)" Before="RemoveFiles" />
57 <Custom Action="virtual $(var.Prefix)SchedHttpSniSslCertsInstall$(var.Suffix)" After="InstallFiles" Condition="VersionNT >= 602" /> 51 <Custom Action="virtual $(var.Prefix6)SchedHttpCertificatesUninstall$(var.Suffix)" After="InstallFiles" />
58 </InstallExecuteSequence> 52 </InstallExecuteSequence>
59 </Fragment> 53 </Fragment>
60 54
61 <Fragment> 55 <Fragment>
62 <Binary Id="$(var.Prefix)HttpCA$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))httpca.dll" /> 56 <Binary Id="$(var.Prefix6)HttpCA$(var.Suffix)" SourceFile="!(bindpath.$(var.platform))httpca.dll" />
63 </Fragment> 57 </Fragment>
64</Include> 58</Include>
diff --git a/src/ext/Http/wixlib/en-us.wxl b/src/ext/Http/wixlib/en-us.wxl
index 44731a5f..a47385e1 100644
--- a/src/ext/Http/wixlib/en-us.wxl
+++ b/src/ext/Http/wixlib/en-us.wxl
@@ -8,10 +8,10 @@
8 <String Id="WixRollbackHttpUrlReservationsUninstall" Overridable="yes" Value="Rolling back Windows HTTP Server configuration" /> 8 <String Id="WixRollbackHttpUrlReservationsUninstall" Overridable="yes" Value="Rolling back Windows HTTP Server configuration" />
9 <String Id="WixExecHttpUrlReservationsUninstall" Overridable="yes" Value="Configuring Windows HTTP Server" /> 9 <String Id="WixExecHttpUrlReservationsUninstall" Overridable="yes" Value="Configuring Windows HTTP Server" />
10 10
11 <String Id="WixSchedHttpSniSslCertsInstall" Overridable="yes" Value="Preparing to configure Windows HTTP Server SSL" /> 11 <String Id="SchedHttpCertificatesInstall" Overridable="yes" Value="Preparing to configure Windows HTTP Server SSL" />
12 <String Id="WixSchedHttpSniSslCertsUninstall" Overridable="yes" Value="Preparing to configure Windows HTTP Server SSL" /> 12 <String Id="SchedHttpCertificatesUninstall" Overridable="yes" Value="Preparing to configure Windows HTTP Server SSL" />
13 <String Id="WixRollbackHttpSniSslCertsInstall" Overridable="yes" Value="Rolling back Windows HTTP Server SSL configuration" /> 13 <String Id="RollbackHttpCertificatesInstall" Overridable="yes" Value="Rolling back Windows HTTP Server SSL configuration" />
14 <String Id="WixExecHttpSniSslCertsInstall" Overridable="yes" Value="Configuring Windows HTTP Server SSL" /> 14 <String Id="ExecHttpCertificatesInstall" Overridable="yes" Value="Configuring Windows HTTP Server SSL" />
15 <String Id="WixRollbackHttpSniSslCertsUninstall" Overridable="yes" Value="Rolling back Windows HTTP Server SSL configuration" /> 15 <String Id="RollbackHttpCertificatesUninstall" Overridable="yes" Value="Rolling back Windows HTTP Server SSL configuration" />
16 <String Id="WixExecHttpSniSslCertsUninstall" Overridable="yes" Value="Configuring Windows HTTP Server SSL" /> 16 <String Id="ExecHttpCertificatesUninstall" Overridable="yes" Value="Configuring Windows HTTP Server SSL" />
17</WixLocalization> 17</WixLocalization>