From 085ba380e7991013c6bb6dce48dc89f02eca4808 Mon Sep 17 00:00:00 2001 From: Bob Arnson Date: Mon, 17 Feb 2025 22:30:31 -0500 Subject: Support non-SNI SSL certificates in Http extension Implements https://github.com/wixtoolset/issues/issues/7622 --- src/ext/Http/ca/httpca.vcxproj | 13 +- src/ext/Http/ca/httpca.vcxproj.filters | 3 +- src/ext/Http/ca/httpcerts.cpp | 938 +++++++++++++++++++++ src/ext/Http/ca/precomp.h | 6 + src/ext/Http/ca/snisslcert.cpp | 704 ---------------- src/ext/Http/ca/wixhttpca.def | 6 +- .../WixToolsetTest.Http/HttpExtensionFixture.cs | 36 +- .../TestData/SniSsl/Package.en-us.wxl | 9 - .../TestData/SniSsl/Package.wxs | 15 - .../TestData/SniSsl/PackageComponents.wxs | 12 - .../TestData/SniSsl/example.txt | 1 - .../TestData/Ssl/Package.en-us.wxl | 9 + .../WixToolsetTest.Http/TestData/Ssl/Package.wxs | 15 + .../TestData/Ssl/PackageComponents.wxs | 17 + .../WixToolsetTest.Http/TestData/Ssl/example.txt | 1 + src/ext/Http/wixext/HttpCompiler.cs | 31 +- src/ext/Http/wixext/HttpTableDefinitions.cs | 13 +- src/ext/Http/wixext/Symbols/CertificateType.cs | 13 + .../Http/wixext/Symbols/HttpCertificateSymbol.cs | 103 +++ .../Http/wixext/Symbols/HttpSymbolDefinitions.cs | 6 +- .../Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs | 95 --- src/ext/Http/wixlib/HttpExtension_Platform.wxi | 52 +- src/ext/Http/wixlib/en-us.wxl | 12 +- 23 files changed, 1189 insertions(+), 921 deletions(-) create mode 100644 src/ext/Http/ca/httpcerts.cpp delete mode 100644 src/ext/Http/ca/snisslcert.cpp delete mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl delete mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs delete mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/PackageComponents.wxs delete mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt create mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.en-us.wxl create mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.wxs create mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/PackageComponents.wxs create mode 100644 src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/example.txt create mode 100644 src/ext/Http/wixext/Symbols/CertificateType.cs create mode 100644 src/ext/Http/wixext/Symbols/HttpCertificateSymbol.cs delete mode 100644 src/ext/Http/wixext/Symbols/WixHttpSniSslCertSymbol.cs (limited to 'src') 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 @@ - @@ -28,7 +27,6 @@ ARM64 - {90743805-C043-47C7-B5FF-8F5EE5C8A2DE} DynamicLibrary @@ -37,35 +35,28 @@ wixhttpca.def WiX Toolset Http CustomAction - - crypt32.lib;httpapi.lib;msi.lib;rpcrt4.lib;ws2_32.lib - Create - + - - - - - + \ 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 @@ Source Files - + Source Files @@ -37,6 +37,5 @@ Source Files - \ No newline at end of file diff --git a/src/ext/Http/ca/httpcerts.cpp b/src/ext/Http/ca/httpcerts.cpp new file mode 100644 index 00000000..c91dbbe1 --- /dev/null +++ b/src/ext/Http/ca/httpcerts.cpp @@ -0,0 +1,938 @@ +// 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. + +#include "precomp.h" + +#if _WIN32_WINNT < 0x0602 + +typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_KEY +{ + SOCKADDR_STORAGE IpPort; + PWSTR Host; +} HTTP_SERVICE_CONFIG_SSL_SNI_KEY, * PHTTP_SERVICE_CONFIG_SSL_SNI_KEY; + +typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_SET +{ + HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc; + HTTP_SERVICE_CONFIG_SSL_PARAM ParamDesc; +} HTTP_SERVICE_CONFIG_SSL_SNI_SET, * PHTTP_SERVICE_CONFIG_SSL_SNI_SET; + +typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_QUERY +{ + HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc; + HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc; + DWORD dwToken; +} HTTP_SERVICE_CONFIG_SSL_SNI_QUERY, * PHTTP_SERVICE_CONFIG_SSL_SNI_QUERY; + +#define HttpServiceConfigSslSniCertInfo static_cast(HttpServiceConfigCache + 1) + +#endif + +static UINT SchedHttpCertificates( + __in WCA_TODO todoSched +); +static HRESULT FindExistingSniSslCertificate( + __in_z LPWSTR wzHost, + __in int nPort, + __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet +); +static HRESULT FindExistingIpSslCertificate( + __in int nPort, + __out HTTP_SERVICE_CONFIG_SSL_SET** ppSet +); +static HRESULT WriteSniSslCertCustomActionData( + __in WCA_TODO action, + __in_z LPCWSTR wzId, + __in_z LPCWSTR wzHost, + __in int iPort, + __in int iHandleExisting, + __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet, + __inout_z LPWSTR* psczCustomActionData +); +static HRESULT WriteIpSslCertCustomActionData( + __in WCA_TODO action, + __in_z LPCWSTR wzId, + __in int iPort, + __in int iHandleExisting, + __in HTTP_SERVICE_CONFIG_SSL_SET* pSniSslSet, + __inout_z LPWSTR* psczCustomActionData +); +static HRESULT AddSniSslCert( + __in_z LPCWSTR wzId, + __in_z LPWSTR wzHost, + __in int iPort, + __in BYTE rgbCertificateThumbprint[], + __in DWORD cbCertificateThumbprint, + __in GUID* pAppId, + __in_z LPWSTR wzSslCertStore +); +static HRESULT AddIpSslCert( + __in_z LPCWSTR wzId, + __in int iPort, + __in BYTE rgbCertificateThumbprint[], + __in DWORD cbCertificateThumbprint, + __in GUID* pAppId, + __in_z LPWSTR wzSslCertStore +); +static HRESULT RemoveSniSslCert( + __in_z_opt LPCWSTR wzId, + __in_z LPWSTR wzHost, + __in int iPort +); +static HRESULT RemoveIpSslCert( + __in_z_opt LPCWSTR wzId, + __in int iPort +); +static void SetSniSslCertificateKeyPort( + __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey, + __in_z LPWSTR wzHost, + __in int iPort +); +static void SetIpSslCertificateKeyPort( + __in HTTP_SERVICE_CONFIG_SSL_KEY* pKey, + __in SOCKADDR_IN* pSin, + __in int iPort +); +static HRESULT EnsureAppId( + __inout_z LPWSTR* psczAppId, + __in_opt GUID* pGuid +); +static HRESULT StringFromGuid( + __in REFGUID rguid, + __inout_z LPWSTR* psczGuid +); +static HRESULT WriteCertificateCaData( + __in eCertificateType certType, + __in WCA_TODO action, + __in_z LPCWSTR wzId, + __in_z_opt LPCWSTR wzHost, + __in int iPort, + __in int iHandleExisting, + __in_z LPCWSTR wzCertificateThumbprint, + __in_z_opt LPCWSTR wzAppId, + __in_z_opt LPCWSTR wzCertificateStore, + __inout_z LPWSTR* psczCustomActionData +); + + +LPCWSTR vcsHttpCertificatesQuery = +L"SELECT `HttpCertificate`, `Host`, `Port`, `Thumbprint`, `AppId`, `Store`, `HandleExisting`, `Type`, `Component_` " +L"FROM `Wix6HttpCertificate`"; +enum eHttpCertificatesQuery { hcqId = 1, hcqHost, hcqPort, hcqCertificateThumbprint, hcqAppId, hcqCertificateStore, hcqHandleExisting, hcqType, hcqComponent }; + +/****************************************************************** + SchedHttpCertificatesInstall - immediate custom action entry + point to prepare adding certificates. + +********************************************************************/ +extern "C" UINT __stdcall SchedHttpCertificatesInstall( + __in MSIHANDLE hInstall +) +{ + HRESULT hr = S_OK; + + hr = WcaInitialize(hInstall, "SchedHttpCertificatesInstall"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = SchedHttpCertificates(WCA_TODO_INSTALL); + +LExit: + return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); +} + +/****************************************************************** + SchedWixHttpSniSslCertsUninstall - immediate custom action entry + point to prepare removing certificates. + +********************************************************************/ +extern "C" UINT __stdcall SchedHttpCertificatesUninstall( + __in MSIHANDLE hInstall +) +{ + HRESULT hr = S_OK; + + hr = WcaInitialize(hInstall, "SchedHttpCertificatesUninstall"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = SchedHttpCertificates(WCA_TODO_UNINSTALL); + +LExit: + return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); +} + +/****************************************************************** + ExecHttpCertificates - deferred custom action entry point to + bind/unbind certificates. + +********************************************************************/ +extern "C" UINT __stdcall ExecHttpCertificates( + __in MSIHANDLE hInstall +) +{ + HRESULT hr = S_OK; + BOOL fHttpInitialized = FALSE; + LPWSTR sczCustomActionData = NULL; + LPWSTR wz = NULL; + int iTodo = WCA_TODO_UNKNOWN; + LPWSTR sczId = NULL; + LPWSTR sczHost = NULL; + int iPort = 0; + eHandleExisting handleExisting = heIgnore; + eCertificateType certificateType = ctSniSsl; + LPWSTR sczCertificateThumbprint = NULL; + LPWSTR sczAppId = NULL; + LPWSTR sczCertificateStore = NULL; + + BOOL fRollback = ::MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK); + BOOL fRemove = FALSE; + BOOL fAdd = FALSE; + BOOL fFailOnExisting = FALSE; + + GUID guidAppId = { }; + BYTE* pbCertificateThumbprint = NULL; + DWORD cbCertificateThumbprint = 0; + + // Initialize. + hr = WcaInitialize(hInstall, "ExecHttpCertificates"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL)); + ExitOnFailure(hr, "Failed to initialize HTTP Server configuration"); + + fHttpInitialized = TRUE; + + hr = WcaGetProperty(L"CustomActionData", &sczCustomActionData); + ExitOnFailure(hr, "Failed to get CustomActionData"); + WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", sczCustomActionData); + + wz = sczCustomActionData; + while (wz && *wz) + { + // Extract the custom action data and if rolling back, swap INSTALL and UNINSTALL. + hr = WcaReadIntegerFromCaData(&wz, reinterpret_cast(&certificateType)); + ExitOnFailure(hr, "Failed to read Type from custom action data"); + + hr = WcaReadIntegerFromCaData(&wz, &iTodo); + ExitOnFailure(hr, "Failed to read todo from custom action data"); + + hr = WcaReadStringFromCaData(&wz, &sczId); + ExitOnFailure(hr, "Failed to read Id from custom action data"); + + hr = WcaReadStringFromCaData(&wz, &sczHost); + ExitOnFailure(hr, "Failed to read Host from custom action data"); + + hr = WcaReadIntegerFromCaData(&wz, &iPort); + ExitOnFailure(hr, "Failed to read Port from custom action data"); + + hr = WcaReadIntegerFromCaData(&wz, reinterpret_cast(&handleExisting)); + ExitOnFailure(hr, "Failed to read HandleExisting from custom action data"); + + hr = WcaReadStringFromCaData(&wz, &sczCertificateThumbprint); + ExitOnFailure(hr, "Failed to read CertificateThumbprint from custom action data"); + + hr = WcaReadStringFromCaData(&wz, &sczAppId); + ExitOnFailure(hr, "Failed to read AppId from custom action data"); + + hr = WcaReadStringFromCaData(&wz, &sczCertificateStore); + ExitOnFailure(hr, "Failed to read CertificateStore from custom action data"); + + switch (iTodo) + { + case WCA_TODO_INSTALL: + case WCA_TODO_REINSTALL: + fRemove = heReplace == handleExisting || fRollback; + fAdd = !fRollback || *sczCertificateThumbprint; + fFailOnExisting = heFail == handleExisting && !fRollback; + break; + + case WCA_TODO_UNINSTALL: + fRemove = !fRollback; + fAdd = fRollback && *sczCertificateThumbprint; + fFailOnExisting = FALSE; + break; + } + + if (fRemove) + { + if (ctSniSsl == certificateType) + { + hr = RemoveSniSslCert(sczId, sczHost, iPort); + } + else + { + hr = RemoveIpSslCert(sczId, iPort); + } + + if (S_OK == hr) + { + WcaLog(LOGMSG_STANDARD, "Removed SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort); + } + else if (FAILED(hr)) + { + if (fRollback) + { + WcaLogError(hr, "Failed to remove SSL certificate to rollback '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort); + } + else + { + ExitOnFailure(hr, "Failed to remove SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort); + } + } + } + + if (fAdd) + { + WcaLog(LOGMSG_STANDARD, "Adding SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort); + + hr = StrAllocHexDecode(sczCertificateThumbprint, &pbCertificateThumbprint, &cbCertificateThumbprint); + ExitOnFailure(hr, "Failed to convert thumbprint to bytes for SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); + + hr = ::IIDFromString(sczAppId, &guidAppId); + ExitOnFailure(hr, "Failed to convert AppId '%ls' back to GUID for SSL certificate '%ls' for hostname: %ls:%d", sczAppId, sczId, sczHost, iPort); + if (ctSniSsl == certificateType) + { + hr = AddSniSslCert(sczId, sczHost, iPort, pbCertificateThumbprint, cbCertificateThumbprint, &guidAppId, sczCertificateStore && *sczCertificateStore ? sczCertificateStore : L"MY"); + } + else + { + hr = AddIpSslCert(sczId, iPort, pbCertificateThumbprint, cbCertificateThumbprint, &guidAppId, sczCertificateStore && *sczCertificateStore ? sczCertificateStore : L"MY"); + } + + if (S_FALSE == hr && fFailOnExisting) + { + hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + } + + if (S_OK == hr) + { + WcaLog(LOGMSG_STANDARD, "Added SSL certificate '%ls' for hostname: %ls:%d with thumbprint: %ls.", sczId, sczHost, iPort, sczCertificateThumbprint); + } + else if (FAILED(hr)) + { + if (fRollback) + { + WcaLogError(hr, "Failed to add SSL certificate to rollback '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort); + } + else + { + ExitOnFailure(hr, "Failed to add SSL certificate '%ls' for hostname: %ls:%d.", sczId, sczHost, iPort); + } + } + + ReleaseNullMem(pbCertificateThumbprint); + } + } + +LExit: + ReleaseMem(pbCertificateThumbprint); + ReleaseStr(sczCertificateStore); + ReleaseStr(sczAppId); + ReleaseStr(sczCertificateThumbprint); + ReleaseStr(sczHost); + ReleaseStr(sczId); + ReleaseStr(sczCustomActionData); + + if (fHttpInitialized) + { + ::HttpTerminate(HTTP_INITIALIZE_CONFIG, NULL); + } + + return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); +} + +static UINT SchedHttpCertificates( + __in WCA_TODO todoSched +) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + BOOL fHttpInitialized = FALSE; + DWORD cCertificates = 0; + + PMSIHANDLE hView = NULL; + PMSIHANDLE hRec = NULL; + PMSIHANDLE hQueryReq = NULL; + PMSIHANDLE hAceView = NULL; + + LPWSTR sczCustomActionData = NULL; + LPWSTR sczRollbackCustomActionData = NULL; + + LPWSTR sczId = NULL; + LPWSTR sczComponent = NULL; + eCertificateType certificateType = ctSniSsl; + WCA_TODO todoComponent = WCA_TODO_UNKNOWN; + LPWSTR sczHost = NULL; + int iPort = 0; + LPWSTR sczCertificateThumbprint = NULL; + LPWSTR sczAppId = NULL; + LPWSTR sczCertificateStore = NULL; + int iHandleExisting = 0; + + HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet = NULL; + HTTP_SERVICE_CONFIG_SSL_SET* pExistingIpSslSet = NULL; + + // Anything to do? + hr = WcaTableExists(L"Wix6HttpCertificate"); + ExitOnFailure(hr, "Failed to check if the Wix6HttpCertificate table exists"); + if (S_FALSE == hr) + { + WcaLog(LOGMSG_STANDARD, "Wix6HttpCertificate table doesn't exist, so there are no certificates to configure."); + ExitFunction(); + } + + // Query and loop through all the SNI SSL certificates. + hr = WcaOpenExecuteView(vcsHttpCertificatesQuery, &hView); + ExitOnFailure(hr, "Failed to open view on the Wix6HttpCertificate table"); + + hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL)); + ExitOnFailure(hr, "Failed to initialize HTTP Server configuration"); + + fHttpInitialized = TRUE; + + while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) + { + hr = WcaGetRecordString(hRec, hcqId, &sczId); + ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Wix6HttpCertificate"); + + hr = WcaGetRecordString(hRec, hcqComponent, &sczComponent); + ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Component_"); + + // Figure out what we're doing for this certificate, treating reinstall the same as install. + todoComponent = WcaGetComponentToDo(sczComponent); + if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched) + { + WcaLog(LOGMSG_VERBOSE, "Component '%ls' action state (%d) doesn't match request (%d) for Wix6HttpCertificate '%ls'.", sczComponent, todoComponent, todoSched, sczId); + continue; + } + + hr = WcaGetRecordInteger(hRec, hcqType, reinterpret_cast(&certificateType)); + ExitOnFailure(hr, "Failed to get Type for Wix6HttpCertificate '%ls'", sczId); + + hr = WcaGetRecordFormattedString(hRec, hcqHost, &sczHost); + ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Host"); + + hr = WcaGetRecordFormattedInteger(hRec, hcqPort, &iPort); + ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.Port"); + + hr = WcaGetRecordFormattedString(hRec, hcqCertificateThumbprint, &sczCertificateThumbprint); + ExitOnFailure(hr, "Failed to get Wix6HttpCertificate.CertificateThumbprint"); + + if (!iPort) + { + hr = E_INVALIDARG; + ExitOnFailure(hr, "Missing Port value for Wix6HttpCertificate '%ls'", sczId); + } + + if (!sczCertificateThumbprint || !*sczCertificateThumbprint) + { + hr = E_INVALIDARG; + ExitOnFailure(hr, "Missing CertificateThumbprint value for Wix6HttpCertificate '%ls'", sczId); + } + + hr = WcaGetRecordFormattedString(hRec, hcqAppId, &sczAppId); + ExitOnFailure(hr, "Failed to get AppId for Wix6HttpCertificate '%ls'", sczId); + + hr = WcaGetRecordFormattedString(hRec, hcqCertificateStore, &sczCertificateStore); + ExitOnFailure(hr, "Failed to get CertificateStore for Wix6HttpCertificate '%ls'", sczId); + + hr = WcaGetRecordInteger(hRec, hcqHandleExisting, &iHandleExisting); + ExitOnFailure(hr, "Failed to get HandleExisting for Wix6HttpCertificate '%ls'", sczId); + + if (ctIpSsl == certificateType) + { + WcaLog(LOGMSG_STANDARD, "Processing IP SSL certificate: %ls on port %d.", sczId, iPort); + + hr = FindExistingIpSslCertificate(iPort, &pExistingIpSslSet); + ExitOnFailure(hr, "Failed to search for an existing IP SSL certificate for '%ls' on port %d", sczId, iPort); + + if (S_FALSE != hr) + { + hr = WriteIpSslCertCustomActionData(todoComponent, sczId, iPort, iHandleExisting, pExistingIpSslSet, &sczRollbackCustomActionData); + ExitOnFailure(hr, "Failed to write rollback custom action data for IP SSL '%ls' on port %d", sczId, iPort); + } + + hr = EnsureAppId(&sczAppId, pExistingIpSslSet ? &(pExistingIpSslSet->ParamDesc.AppId) : NULL); + ExitOnFailure(hr, "Failed to ensure AppId for IP SSL '%ls'", sczId); + } + else if (ctSniSsl == certificateType) + { + WcaLog(LOGMSG_STANDARD, "Processing SNI SSL certificate: %ls on host %ls:%d.", sczId, sczHost, iPort); + + hr = FindExistingSniSslCertificate(sczHost, iPort, &pExistingSniSslSet); + ExitOnFailure(hr, "Failed to search for an existing SNI SSL certificate for '%ls' on host '%ls', port %d", sczId, sczHost, iPort); + + if (S_FALSE != hr) + { + hr = WriteSniSslCertCustomActionData(todoComponent, sczId, sczHost, iPort, iHandleExisting, pExistingSniSslSet, &sczRollbackCustomActionData); + ExitOnFailure(hr, "Failed to write rollback custom action data for SNI SSL Wix6HttpCertificate '%ls' on host '%ls', port %d", sczId, sczHost, iPort); + } + + hr = EnsureAppId(&sczAppId, pExistingSniSslSet ? &(pExistingSniSslSet->ParamDesc.AppId) : NULL); + ExitOnFailure(hr, "Failed to ensure AppId for SNI SSL '%ls'", sczId); + } + + hr = WriteCertificateCaData(certificateType, todoComponent, sczId, sczHost, iPort, iHandleExisting, sczCertificateThumbprint, sczAppId, sczCertificateStore, &sczCustomActionData); + ExitOnFailure(hr, "Failed to write custom action data for SSL '%ls'", sczId); + ++cCertificates; + + ReleaseNullMem(pExistingSniSslSet); + ReleaseNullMem(pExistingIpSslSet); + } + + // Reaching the end of the list is not an error. + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure occurred while processing Wix6HttpCertificate table"); + + WcaLog(LOGMSG_VERBOSE, "Scheduling %d certificates", cCertificates); + + // Schedule ExecHttpSniSslCerts if there's anything to do. + if (cCertificates) + { + WcaLog(LOGMSG_TRACEONLY, "Scheduling SSL certificate: `%ls`", sczCustomActionData); + WcaLog(LOGMSG_TRACEONLY, "Scheduling rollback SSL certificate: `%ls`", sczRollbackCustomActionData); + + if (WCA_TODO_INSTALL == todoSched) + { + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RollbackHttpCertificatesInstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL); + ExitOnFailure(hr, "Failed to schedule install SSL certificate rollback"); + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"ExecHttpCertificatesInstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL); + ExitOnFailure(hr, "Failed to schedule install SSL certificate execution"); + } + else + { + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"RollbackHttpCertificatesUninstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL); + ExitOnFailure(hr, "Failed to schedule uninstall SSL certificate rollback"); + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION6(L"ExecHttpCertificatesUninstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL); + ExitOnFailure(hr, "Failed to schedule uninstall SSL certificate execution"); + } + } + else + { + WcaLog(LOGMSG_STANDARD, "No SNI SSL certificates scheduled."); + } + +LExit: + ReleaseMem(pExistingSniSslSet); + ReleaseMem(pExistingIpSslSet); + ReleaseStr(sczCertificateStore); + ReleaseStr(sczAppId); + ReleaseStr(sczCertificateThumbprint); + ReleaseStr(sczHost); + ReleaseStr(sczComponent); + ReleaseStr(sczId); + ReleaseStr(sczRollbackCustomActionData); + ReleaseStr(sczCustomActionData); + + if (fHttpInitialized) + { + ::HttpTerminate(HTTP_INITIALIZE_CONFIG, NULL); + } + + return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er); +} + +static HRESULT FindExistingSniSslCertificate( + __in_z LPWSTR wzHost, + __in int nPort, + __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet +) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + HTTP_SERVICE_CONFIG_SSL_SNI_QUERY query = { }; + HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSet = NULL; + ULONG cbSet = 0; + + *ppSet = NULL; + + query.QueryDesc = HttpServiceConfigQueryExact; + SetSniSslCertificateKeyPort(&query.KeyDesc, wzHost, nPort); + + WcaLog(LOGMSG_TRACEONLY, "Querying for SNI SSL certificate on port %d...", nPort); + + er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL); + if (ERROR_INSUFFICIENT_BUFFER == er) + { + pSet = reinterpret_cast(MemAlloc(cbSet, TRUE)); + ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query SN SSL certificate buffer"); + + er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL); + } + + if (ERROR_SUCCESS == er) + { + *ppSet = pSet; + pSet = NULL; + } + else if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er) + { + hr = S_FALSE; + } + else + { + hr = HRESULT_FROM_WIN32(er); + } + +LExit: + ReleaseMem(pSet); + + return hr; +} + +static HRESULT FindExistingIpSslCertificate( + __in int nPort, + __out HTTP_SERVICE_CONFIG_SSL_SET** ppSet +) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + HTTP_SERVICE_CONFIG_SSL_QUERY query = { }; + SOCKADDR_IN sin = { }; + HTTP_SERVICE_CONFIG_SSL_SET* pSet = NULL; + ULONG cbSet = 0; + + *ppSet = NULL; + + query.QueryDesc = HttpServiceConfigQueryNext; + + SetIpSslCertificateKeyPort(&query.KeyDesc, &sin, nPort); + + WcaLog(LOGMSG_TRACEONLY, "Querying for IP SSL certificate on port %d...", nPort); + + er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL); + if (ERROR_INSUFFICIENT_BUFFER == er) + { + pSet = reinterpret_cast(MemAlloc(cbSet, TRUE)); + ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query IP SSL certificate buffer"); + + er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL); + } + + if (ERROR_SUCCESS == er) + { + *ppSet = pSet; + pSet = NULL; + } + else if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er) + { + hr = S_FALSE; + } + else + { + hr = HRESULT_FROM_WIN32(er); + } + +LExit: + ReleaseMem(pSet); + + return hr; +} + +static HRESULT WriteSniSslCertCustomActionData( + __in WCA_TODO action, + __in_z LPCWSTR wzId, + __in_z LPCWSTR wzHost, + __in int iPort, + __in int iHandleExisting, + __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet, + __inout_z LPWSTR* psczCustomActionData +) +{ + HRESULT hr = S_OK; + LPWSTR sczCertificateThumbprint = NULL; + LPWSTR sczAppId = NULL; + LPCWSTR wzCertificateStore = NULL; + + if (pSniSslSet) + { + hr = StrAllocHexEncode(reinterpret_cast(pSniSslSet->ParamDesc.pSslHash), pSniSslSet->ParamDesc.SslHashLength, &sczCertificateThumbprint); + ExitOnFailure(hr, "Failed to convert existing certificate thumbprint to hex for Wix6HttpCertificate '%ls'", wzId); + + hr = StringFromGuid(pSniSslSet->ParamDesc.AppId, &sczAppId); + ExitOnFailure(hr, "Failed to copy existing AppId for Wix6HttpCertificate '%ls'", wzId); + + wzCertificateStore = pSniSslSet->ParamDesc.pSslCertStoreName; + } + + hr = WriteCertificateCaData(ctSniSsl, action, wzId, wzHost, iPort, iHandleExisting, sczCertificateThumbprint ? sczCertificateThumbprint : L"", sczAppId ? sczAppId : L"", wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData); + ExitOnFailure(hr, "Failed to write custom action data for Wix6HttpCertificate '%ls'", wzId); + +LExit: + ReleaseStr(sczAppId); + ReleaseStr(sczCertificateThumbprint); + + return hr; +} + +static HRESULT WriteIpSslCertCustomActionData( + __in WCA_TODO action, + __in_z LPCWSTR wzId, + __in int iPort, + __in int iHandleExisting, + __in HTTP_SERVICE_CONFIG_SSL_SET* pSslSet, + __inout_z LPWSTR* psczCustomActionData +) +{ + HRESULT hr = S_OK; + LPWSTR sczCertificateThumbprint = NULL; + LPWSTR sczAppId = NULL; + LPCWSTR wzCertificateStore = NULL; + + if (pSslSet) + { + hr = StrAllocHexEncode(reinterpret_cast(pSslSet->ParamDesc.pSslHash), pSslSet->ParamDesc.SslHashLength, &sczCertificateThumbprint); + ExitOnFailure(hr, "Failed to convert existing IP SSL certificate thumbprint to hex for Wix6HttpCertificate '%ls'", wzId); + + hr = StringFromGuid(pSslSet->ParamDesc.AppId, &sczAppId); + ExitOnFailure(hr, "Failed to copy existing IP SSL AppId for Wix6HttpCertificate '%ls'", wzId); + + wzCertificateStore = pSslSet->ParamDesc.pSslCertStoreName; + } + + hr = WriteCertificateCaData(ctIpSsl, action, wzId, /*wzHost*/NULL, iPort, iHandleExisting, sczCertificateThumbprint ? sczCertificateThumbprint : L"", sczAppId ? sczAppId : L"", wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData); + ExitOnFailure(hr, "Failed to write custom action data for IP SSL Wix6HttpCertificate '%ls'", wzId); + +LExit: + ReleaseStr(sczAppId); + ReleaseStr(sczCertificateThumbprint); + + return hr; +} + +static HRESULT AddSniSslCert( + __in_z LPCWSTR /*wzId*/, + __in_z LPWSTR wzHost, + __in int iPort, + __in BYTE rgbCertificateThumbprint[], + __in DWORD cbCertificateThumbprint, + __in GUID* pAppId, + __in_z LPWSTR wzSslCertStore +) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { }; + + SetSniSslCertificateKeyPort(&set.KeyDesc, wzHost, iPort); + set.ParamDesc.SslHashLength = cbCertificateThumbprint; + set.ParamDesc.pSslHash = rgbCertificateThumbprint; + set.ParamDesc.AppId = *pAppId; + set.ParamDesc.pSslCertStoreName = wzSslCertStore; + + er = ::HttpSetServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL); + if (ERROR_ALREADY_EXISTS == er) + { + hr = S_FALSE; + } + else + { + hr = HRESULT_FROM_WIN32(er); + } + + return hr; +} + +static HRESULT AddIpSslCert( + __in_z LPCWSTR /*wzId*/, + __in int iPort, + __in BYTE rgbCertificateThumbprint[], + __in DWORD cbCertificateThumbprint, + __in GUID* pAppId, + __in_z LPWSTR wzSslCertStore +) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + HTTP_SERVICE_CONFIG_SSL_SET set = { }; + SOCKADDR_IN sin = { }; + + SetIpSslCertificateKeyPort(&set.KeyDesc, &sin, iPort); + set.ParamDesc.SslHashLength = cbCertificateThumbprint; + set.ParamDesc.pSslHash = rgbCertificateThumbprint; + set.ParamDesc.AppId = *pAppId; + set.ParamDesc.pSslCertStoreName = wzSslCertStore; + + er = ::HttpSetServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &set, sizeof(set), NULL); + if (ERROR_ALREADY_EXISTS == er) + { + hr = S_FALSE; + } + else + { + hr = HRESULT_FROM_WIN32(er); + } + + return hr; +} + +static HRESULT RemoveSniSslCert( + __in_z_opt LPCWSTR /*wzId*/, + __in_z LPWSTR wzHost, + __in int iPort +) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { }; + + SetSniSslCertificateKeyPort(&set.KeyDesc, wzHost, iPort); + + er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL); + if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er) + { + hr = S_FALSE; + } + else + { + hr = HRESULT_FROM_WIN32(er); + } + + return hr; +} + +static HRESULT RemoveIpSslCert( + __in_z_opt LPCWSTR /*wzId*/, + __in int iPort +) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + HTTP_SERVICE_CONFIG_SSL_SET set = { }; + SOCKADDR_IN sin = { }; + + SetIpSslCertificateKeyPort(&set.KeyDesc, &sin, iPort); + + er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigSSLCertInfo, &set, sizeof(set), NULL); + if (ERROR_FILE_NOT_FOUND == er || ERROR_NO_MORE_ITEMS == er) + { + hr = S_FALSE; + } + else + { + hr = HRESULT_FROM_WIN32(er); + } + + return hr; +} + +static void SetSniSslCertificateKeyPort( + __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey, + __in_z LPWSTR wzHost, + __in int iPort +) +{ + pKey->Host = wzHost; + SOCKADDR_IN* pss = reinterpret_cast(&pKey->IpPort); + pss->sin_family = AF_INET; + pss->sin_port = htons(static_cast(iPort)); +} + +static void SetIpSslCertificateKeyPort( + __in HTTP_SERVICE_CONFIG_SSL_KEY* pKey, + __in SOCKADDR_IN* pSin, + __in int iPort +) +{ + pSin->sin_family = AF_INET; + pSin->sin_port = htons(static_cast(iPort)); + pKey->pIpPort = reinterpret_cast(pSin); +} + +static HRESULT EnsureAppId( + __inout_z LPWSTR* psczAppId, + __in_opt GUID* pGuid +) +{ + HRESULT hr = S_OK; + GUID guid = { }; + + if (!psczAppId || !*psczAppId || !**psczAppId) + { + if (pGuid) + { + hr = StringFromGuid(*pGuid, psczAppId); + ExitOnFailure(hr, "Failed to ensure AppId guid"); + } + else + { + hr = HRESULT_FROM_RPC(::UuidCreate(&guid)); + ExitOnRootFailure(hr, "Failed to create guid for AppId"); + + hr = StringFromGuid(guid, psczAppId); + ExitOnFailure(hr, "Failed to ensure AppId guid"); + } + } + +LExit: + return hr; +} + +static HRESULT StringFromGuid( + __in REFGUID rguid, + __inout_z LPWSTR* psczGuid +) +{ + HRESULT hr = S_OK; + WCHAR wzGuid[39]; + + if (!::StringFromGUID2(rguid, wzGuid, countof(wzGuid))) + { + hr = E_OUTOFMEMORY; + ExitOnRootFailure(hr, "Failed to convert guid into string"); + } + + hr = StrAllocString(psczGuid, wzGuid, 0); + ExitOnFailure(hr, "Failed to copy guid"); + +LExit: + return hr; +} + +static HRESULT WriteCertificateCaData( + __in eCertificateType certType, + __in WCA_TODO action, + __in_z LPCWSTR wzId, + __in_z_opt LPCWSTR wzHost, + __in int iPort, + __in int iHandleExisting, + __in_z LPCWSTR wzCertificateThumbprint, + __in_z_opt LPCWSTR wzAppId, + __in_z_opt LPCWSTR wzCertificateStore, + __inout_z LPWSTR* psczCustomActionData +) +{ + HRESULT hr = S_OK; + + hr = WcaWriteIntegerToCaData(certType, psczCustomActionData); + ExitOnFailure(hr, "Failed to write IP SSL certificate type to custom action data"); + + hr = WcaWriteIntegerToCaData(action, psczCustomActionData); + ExitOnFailure(hr, "Failed to write action to custom action data"); + + hr = WcaWriteStringToCaData(wzId, psczCustomActionData); + ExitOnFailure(hr, "Failed to write id to custom action data"); + + hr = WcaWriteStringToCaData(wzHost ? wzHost : L"", psczCustomActionData); + ExitOnFailure(hr, "Failed to write Host to custom action data"); + + hr = WcaWriteIntegerToCaData(iPort, psczCustomActionData); + ExitOnFailure(hr, "Failed to write Port to custom action data"); + + hr = WcaWriteIntegerToCaData(iHandleExisting, psczCustomActionData); + ExitOnFailure(hr, "Failed to write HandleExisting to custom action data"); + + hr = WcaWriteStringToCaData(wzCertificateThumbprint, psczCustomActionData); + ExitOnFailure(hr, "Failed to write CertificateThumbprint to custom action data"); + + hr = WcaWriteStringToCaData(wzAppId ? wzAppId : L"", psczCustomActionData); + ExitOnFailure(hr, "Failed to write AppId to custom action data"); + + hr = WcaWriteStringToCaData(wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData); + ExitOnFailure(hr, "Failed to write CertificateStore to custom action data"); + +LExit: + return hr; +} + 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 heIgnore = 1, heFail = 2 }; + +enum eCertificateType +{ + ctSniSsl = 0, + ctIpSsl = 1, +}; diff --git a/src/ext/Http/ca/snisslcert.cpp b/src/ext/Http/ca/snisslcert.cpp deleted file mode 100644 index 81cd5298..00000000 --- a/src/ext/Http/ca/snisslcert.cpp +++ /dev/null @@ -1,704 +0,0 @@ -// 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. - -#include "precomp.h" - -#if _WIN32_WINNT < 0x0602 - -typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_KEY -{ - SOCKADDR_STORAGE IpPort; - PWSTR Host; -} HTTP_SERVICE_CONFIG_SSL_SNI_KEY, * PHTTP_SERVICE_CONFIG_SSL_SNI_KEY; - -typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_SET -{ - HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc; - HTTP_SERVICE_CONFIG_SSL_PARAM ParamDesc; -} HTTP_SERVICE_CONFIG_SSL_SNI_SET, * PHTTP_SERVICE_CONFIG_SSL_SNI_SET; - -typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_QUERY -{ - HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc; - HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc; - DWORD dwToken; -} HTTP_SERVICE_CONFIG_SSL_SNI_QUERY, * PHTTP_SERVICE_CONFIG_SSL_SNI_QUERY; - -#define HttpServiceConfigSslSniCertInfo static_cast(HttpServiceConfigCache + 1) - -#endif - -static UINT SchedHttpSniSslCerts( - __in WCA_TODO todoSched -); -static HRESULT WriteExistingSniSslCert( - __in WCA_TODO action, - __in_z LPCWSTR wzId, - __in_z LPCWSTR wzHost, - __in int iPort, - __in int iHandleExisting, - __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet, - __inout_z LPWSTR* psczCustomActionData -); -static HRESULT WriteSniSslCert( - __in WCA_TODO action, - __in_z LPCWSTR wzId, - __in_z LPCWSTR wzHost, - __in int iPort, - __in int iHandleExisting, - __in_z LPCWSTR wzCertificateThumbprint, - __in_z LPCWSTR wzAppId, - __in_z_opt LPCWSTR wzCertificateStore, - __inout_z LPWSTR* psczCustomActionData -); -static HRESULT EnsureAppId( - __inout_z LPWSTR* psczAppId, - __in_opt HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet -); -static HRESULT StringFromGuid( - __in REFGUID rguid, - __inout_z LPWSTR* psczGuid -); -static HRESULT AddSniSslCert( - __in_z LPCWSTR wzId, - __in_z LPWSTR wzHost, - __in int iPort, - __in BYTE rgbCertificateThumbprint[], - __in DWORD cbCertificateThumbprint, - __in GUID* pAppId, - __in_z LPWSTR wzSslCertStore -); -static HRESULT GetSniSslCert( - __in_z LPWSTR wzHost, - __in int nPort, - __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet -); -static HRESULT RemoveSniSslCert( - __in_z LPCWSTR wzId, - __in_z LPWSTR wzHost, - __in int iPort -); -static void SetSniSslCertSetKey( - __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey, - __in_z LPWSTR wzHost, - __in int iPort -); - - -LPCWSTR vcsWixHttpSniSslCertQuery = -L"SELECT `WixHttpSniSslCert`, `Host`, `Port`, `Thumbprint`, `AppId`, `Store`, `HandleExisting`, `Component_` " -L"FROM `Wix4HttpSniSslCert`"; -enum eWixHttpSniSslCertQuery { hurqId = 1, hurqHost, hurqPort, hurqCertificateThumbprint, hurqAppId, hurqCertificateStore, hurqHandleExisting, hurqComponent }; - -/****************************************************************** - SchedWixHttpSniSslCertsInstall - immediate custom action entry - point to prepare adding URL reservations. - -********************************************************************/ -extern "C" UINT __stdcall SchedHttpSniSslCertsInstall( - __in MSIHANDLE hInstall -) -{ - HRESULT hr = S_OK; - - hr = WcaInitialize(hInstall, "SchedHttpSniSslCertsInstall"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = SchedHttpSniSslCerts(WCA_TODO_INSTALL); - -LExit: - return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); -} - -/****************************************************************** - SchedWixHttpSniSslCertsUninstall - immediate custom action entry - point to prepare removing URL reservations. - -********************************************************************/ -extern "C" UINT __stdcall SchedHttpSniSslCertsUninstall( - __in MSIHANDLE hInstall -) -{ - HRESULT hr = S_OK; - - hr = WcaInitialize(hInstall, "SchedHttpSniSslCertsUninstall"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = SchedHttpSniSslCerts(WCA_TODO_UNINSTALL); - -LExit: - return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); -} - -/****************************************************************** - ExecHttpSniSslCerts - deferred custom action entry point to - register and remove URL reservations. - -********************************************************************/ -extern "C" UINT __stdcall ExecHttpSniSslCerts( - __in MSIHANDLE hInstall -) -{ - HRESULT hr = S_OK; - BOOL fHttpInitialized = FALSE; - LPWSTR sczCustomActionData = NULL; - LPWSTR wz = NULL; - int iTodo = WCA_TODO_UNKNOWN; - LPWSTR sczId = NULL; - LPWSTR sczHost = NULL; - int iPort = 0; - eHandleExisting handleExisting = heIgnore; - LPWSTR sczCertificateThumbprint = NULL; - LPWSTR sczAppId = NULL; - LPWSTR sczCertificateStore = NULL; - - BOOL fRollback = ::MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK); - BOOL fRemove = FALSE; - BOOL fAdd = FALSE; - BOOL fFailOnExisting = FALSE; - - GUID guidAppId = { }; - BYTE* pbCertificateThumbprint = NULL; - DWORD cbCertificateThumbprint = 0; - - // Initialize. - hr = WcaInitialize(hInstall, "ExecHttpSniSslCerts"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL)); - ExitOnFailure(hr, "Failed to initialize HTTP Server configuration"); - - fHttpInitialized = TRUE; - - hr = WcaGetProperty(L"CustomActionData", &sczCustomActionData); - ExitOnFailure(hr, "Failed to get CustomActionData"); - WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", sczCustomActionData); - - wz = sczCustomActionData; - while (wz && *wz) - { - // Extract the custom action data and if rolling back, swap INSTALL and UNINSTALL. - hr = WcaReadIntegerFromCaData(&wz, &iTodo); - ExitOnFailure(hr, "Failed to read todo from custom action data"); - - hr = WcaReadStringFromCaData(&wz, &sczId); - ExitOnFailure(hr, "Failed to read Id from custom action data"); - - hr = WcaReadStringFromCaData(&wz, &sczHost); - ExitOnFailure(hr, "Failed to read Host from custom action data"); - - hr = WcaReadIntegerFromCaData(&wz, &iPort); - ExitOnFailure(hr, "Failed to read Port from custom action data"); - - hr = WcaReadIntegerFromCaData(&wz, reinterpret_cast(&handleExisting)); - ExitOnFailure(hr, "Failed to read HandleExisting from custom action data"); - - hr = WcaReadStringFromCaData(&wz, &sczCertificateThumbprint); - ExitOnFailure(hr, "Failed to read CertificateThumbprint from custom action data"); - - hr = WcaReadStringFromCaData(&wz, &sczAppId); - ExitOnFailure(hr, "Failed to read AppId from custom action data"); - - hr = WcaReadStringFromCaData(&wz, &sczCertificateStore); - ExitOnFailure(hr, "Failed to read CertificateStore from custom action data"); - - switch (iTodo) - { - case WCA_TODO_INSTALL: - case WCA_TODO_REINSTALL: - fRemove = heReplace == handleExisting || fRollback; - fAdd = !fRollback || *sczCertificateThumbprint; - fFailOnExisting = heFail == handleExisting && !fRollback; - break; - - case WCA_TODO_UNINSTALL: - fRemove = !fRollback; - fAdd = fRollback && *sczCertificateThumbprint; - fFailOnExisting = FALSE; - break; - } - - if (fRemove) - { - hr = RemoveSniSslCert(sczId, sczHost, iPort); - if (S_OK == hr) - { - WcaLog(LOGMSG_STANDARD, "Removed SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); - } - else if (FAILED(hr)) - { - if (fRollback) - { - WcaLogError(hr, "Failed to remove SNI SSL certificate to rollback '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); - } - else - { - ExitOnFailure(hr, "Failed to remove SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); - } - } - } - - if (fAdd) - { - WcaLog(LOGMSG_STANDARD, "Adding SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); - - hr = StrAllocHexDecode(sczCertificateThumbprint, &pbCertificateThumbprint, &cbCertificateThumbprint); - ExitOnFailure(hr, "Failed to convert thumbprint to bytes for SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); - - hr = ::IIDFromString(sczAppId, &guidAppId); - ExitOnFailure(hr, "Failed to convert AppId '%ls' back to GUID for SNI SSL certificate '%ls' for hostname: %ls:%d", sczAppId, sczId, sczHost, iPort); - - hr = AddSniSslCert(sczId, sczHost, iPort, pbCertificateThumbprint, cbCertificateThumbprint, &guidAppId, sczCertificateStore && *sczCertificateStore ? sczCertificateStore : L"MY"); - if (S_FALSE == hr && fFailOnExisting) - { - hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - } - - if (S_OK == hr) - { - WcaLog(LOGMSG_STANDARD, "Added SNI SSL certificate '%ls' for hostname: %ls:%d with thumbprint: %ls", sczId, sczHost, iPort, sczCertificateThumbprint); - } - else if (FAILED(hr)) - { - if (fRollback) - { - WcaLogError(hr, "Failed to add SNI SSL certificate to rollback '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); - } - else - { - ExitOnFailure(hr, "Failed to add SNI SSL certificate '%ls' for hostname: %ls:%d", sczId, sczHost, iPort); - } - } - - ReleaseNullMem(pbCertificateThumbprint); - } - } - -LExit: - ReleaseMem(pbCertificateThumbprint); - ReleaseStr(sczCertificateStore); - ReleaseStr(sczAppId); - ReleaseStr(sczCertificateThumbprint); - ReleaseStr(sczHost); - ReleaseStr(sczId); - ReleaseStr(sczCustomActionData); - - if (fHttpInitialized) - { - ::HttpTerminate(HTTP_INITIALIZE_CONFIG, NULL); - } - - return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); -} - -static UINT SchedHttpSniSslCerts( - __in WCA_TODO todoSched -) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - BOOL fHttpInitialized = FALSE; - DWORD cCertificates = 0; - - PMSIHANDLE hView = NULL; - PMSIHANDLE hRec = NULL; - PMSIHANDLE hQueryReq = NULL; - PMSIHANDLE hAceView = NULL; - - LPWSTR sczCustomActionData = NULL; - LPWSTR sczRollbackCustomActionData = NULL; - - LPWSTR sczId = NULL; - LPWSTR sczComponent = NULL; - WCA_TODO todoComponent = WCA_TODO_UNKNOWN; - LPWSTR sczHost = NULL; - int iPort = 0; - LPWSTR sczCertificateThumbprint = NULL; - LPWSTR sczAppId = NULL; - LPWSTR sczCertificateStore = NULL; - int iHandleExisting = 0; - - HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet = NULL; - - // Anything to do? - hr = WcaTableExists(L"Wix4HttpSniSslCert"); - ExitOnFailure(hr, "Failed to check if the Wix4HttpSniSslCert table exists"); - if (S_FALSE == hr) - { - WcaLog(LOGMSG_STANDARD, "Wix4HttpSniSslCert table doesn't exist, so there are no URL reservations to configure"); - ExitFunction(); - } - - // Query and loop through all the SNI SSL certificates. - hr = WcaOpenExecuteView(vcsWixHttpSniSslCertQuery, &hView); - ExitOnFailure(hr, "Failed to open view on the Wix4HttpSniSslCert table"); - - hr = HRESULT_FROM_WIN32(::HttpInitialize(HTTPAPI_VERSION_1, HTTP_INITIALIZE_CONFIG, NULL)); - ExitOnFailure(hr, "Failed to initialize HTTP Server configuration"); - - fHttpInitialized = TRUE; - - while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) - { - hr = WcaGetRecordString(hRec, hurqId, &sczId); - ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Wix4HttpSniSslCert"); - - hr = WcaGetRecordString(hRec, hurqComponent, &sczComponent); - ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Component_"); - - // Figure out what we're doing for this reservation, treating reinstall the same as install. - todoComponent = WcaGetComponentToDo(sczComponent); - if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched) - { - WcaLog(LOGMSG_STANDARD, "Component '%ls' action state (%d) doesn't match request (%d) for Wix4HttpSniSslCert '%ls'", sczComponent, todoComponent, todoSched, sczId); - continue; - } - - hr = WcaGetRecordFormattedString(hRec, hurqHost, &sczHost); - ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Host"); - - hr = WcaGetRecordFormattedInteger(hRec, hurqPort, &iPort); - ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.Port"); - - hr = WcaGetRecordFormattedString(hRec, hurqCertificateThumbprint, &sczCertificateThumbprint); - ExitOnFailure(hr, "Failed to get Wix4HttpSniSslCert.CertificateThumbprint"); - - if (!sczHost || !*sczHost) - { - hr = E_INVALIDARG; - ExitOnFailure(hr, "Require a Host value for Wix4HttpSniSslCert '%ls'", sczId); - } - - if (!iPort) - { - hr = E_INVALIDARG; - ExitOnFailure(hr, "Require a Port value for Wix4HttpSniSslCert '%ls'", sczId); - } - - if (!sczCertificateThumbprint || !*sczCertificateThumbprint) - { - hr = E_INVALIDARG; - ExitOnFailure(hr, "Require a CertificateThumbprint value for Wix4HttpSniSslCert '%ls'", sczId); - } - - hr = WcaGetRecordFormattedString(hRec, hurqAppId, &sczAppId); - ExitOnFailure(hr, "Failed to get AppId for Wix4HttpSniSslCert '%ls'", sczId); - - hr = WcaGetRecordFormattedString(hRec, hurqCertificateStore, &sczCertificateStore); - ExitOnFailure(hr, "Failed to get CertificateStore for Wix4HttpSniSslCert '%ls'", sczId); - - hr = WcaGetRecordInteger(hRec, hurqHandleExisting, &iHandleExisting); - ExitOnFailure(hr, "Failed to get HandleExisting for Wix4HttpSniSslCert '%ls'", sczId); - - hr = GetSniSslCert(sczHost, iPort, &pExistingSniSslSet); - ExitOnFailure(hr, "Failed to get the existing SNI SSL certificate for Wix4HttpSniSslCert '%ls'", sczId); - - hr = EnsureAppId(&sczAppId, pExistingSniSslSet); - ExitOnFailure(hr, "Failed to ensure AppId for Wix4HttpSniSslCert '%ls'", sczId); - - hr = WriteExistingSniSslCert(todoComponent, sczId, sczHost, iPort, iHandleExisting, pExistingSniSslSet, &sczRollbackCustomActionData); - ExitOnFailure(hr, "Failed to write rollback custom action data for Wix4HttpSniSslCert '%ls'", sczId); - - hr = WriteSniSslCert(todoComponent, sczId, sczHost, iPort, iHandleExisting, sczCertificateThumbprint, sczAppId, sczCertificateStore, &sczCustomActionData); - ExitOnFailure(hr, "Failed to write custom action data for Wix4HttpSniSslCert '%ls'", sczId); - ++cCertificates; - - ReleaseNullMem(pExistingSniSslSet); - } - - // Reaching the end of the list is not an error. - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure occurred while processing Wix4HttpSniSslCert table"); - - // Schedule ExecHttpSniSslCerts if there's anything to do. - if (cCertificates) - { - WcaLog(LOGMSG_STANDARD, "Scheduling SNI SSL certificate (%ls)", sczCustomActionData); - WcaLog(LOGMSG_STANDARD, "Scheduling rollback SNI SSL certificate (%ls)", sczRollbackCustomActionData); - - if (WCA_TODO_INSTALL == todoSched) - { - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackHttpSniSslCertsInstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL); - ExitOnFailure(hr, "Failed to schedule install SNI SSL certificate rollback"); - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ExecHttpSniSslCertsInstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL); - ExitOnFailure(hr, "Failed to schedule install SNI SSL certificate execution"); - } - else - { - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackHttpSniSslCertsUninstall"), sczRollbackCustomActionData, cCertificates * COST_HTTP_SNI_SSL); - ExitOnFailure(hr, "Failed to schedule uninstall SNI SSL certificate rollback"); - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ExecHttpSniSslCertsUninstall"), sczCustomActionData, cCertificates * COST_HTTP_SNI_SSL); - ExitOnFailure(hr, "Failed to schedule uninstall SNI SSL certificate execution"); - } - } - else - { - WcaLog(LOGMSG_STANDARD, "No SNI SSL certificates scheduled"); - } - -LExit: - ReleaseMem(pExistingSniSslSet); - ReleaseStr(sczCertificateStore); - ReleaseStr(sczAppId); - ReleaseStr(sczCertificateThumbprint); - ReleaseStr(sczHost); - ReleaseStr(sczComponent); - ReleaseStr(sczId); - ReleaseStr(sczRollbackCustomActionData); - ReleaseStr(sczCustomActionData); - - if (fHttpInitialized) - { - ::HttpTerminate(HTTP_INITIALIZE_CONFIG, NULL); - } - - return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er); -} - -static HRESULT WriteExistingSniSslCert( - __in WCA_TODO action, - __in_z LPCWSTR wzId, - __in_z LPCWSTR wzHost, - __in int iPort, - __in int iHandleExisting, - __in HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSniSslSet, - __inout_z LPWSTR* psczCustomActionData -) -{ - HRESULT hr = S_OK; - LPWSTR sczCertificateThumbprint = NULL; - LPWSTR sczAppId = NULL; - LPCWSTR wzCertificateStore = NULL; - - if (pSniSslSet) - { - hr = StrAllocHexEncode(reinterpret_cast(pSniSslSet->ParamDesc.pSslHash), pSniSslSet->ParamDesc.SslHashLength, &sczCertificateThumbprint); - ExitOnFailure(hr, "Failed to convert existing certificate thumbprint to hex for Wix4HttpSniSslCert '%ls'", wzId); - - hr = StringFromGuid(pSniSslSet->ParamDesc.AppId, &sczAppId); - ExitOnFailure(hr, "Failed to copy existing AppId for Wix4HttpSniSslCert '%ls'", wzId); - - wzCertificateStore = pSniSslSet->ParamDesc.pSslCertStoreName; - } - - hr = WriteSniSslCert(action, wzId, wzHost, iPort, iHandleExisting, sczCertificateThumbprint ? sczCertificateThumbprint : L"", sczAppId ? sczAppId : L"", wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData); - ExitOnFailure(hr, "Failed to write custom action data for Wix4HttpSniSslCert '%ls'", wzId); - -LExit: - ReleaseStr(sczAppId); - ReleaseStr(sczCertificateThumbprint); - - return hr; -} - -static HRESULT WriteSniSslCert( - __in WCA_TODO action, - __in_z LPCWSTR wzId, - __in_z LPCWSTR wzHost, - __in int iPort, - __in int iHandleExisting, - __in_z LPCWSTR wzCertificateThumbprint, - __in_z LPCWSTR wzAppId, - __in_z_opt LPCWSTR wzCertificateStore, - __inout_z LPWSTR* psczCustomActionData -) -{ - HRESULT hr = S_OK; - - hr = WcaWriteIntegerToCaData(action, psczCustomActionData); - ExitOnFailure(hr, "Failed to write action to custom action data"); - - hr = WcaWriteStringToCaData(wzId, psczCustomActionData); - ExitOnFailure(hr, "Failed to write id to custom action data"); - - hr = WcaWriteStringToCaData(wzHost, psczCustomActionData); - ExitOnFailure(hr, "Failed to write Host to custom action data"); - - hr = WcaWriteIntegerToCaData(iPort, psczCustomActionData); - ExitOnFailure(hr, "Failed to write Port to custom action data"); - - hr = WcaWriteIntegerToCaData(iHandleExisting, psczCustomActionData); - ExitOnFailure(hr, "Failed to write HandleExisting to custom action data"); - - hr = WcaWriteStringToCaData(wzCertificateThumbprint, psczCustomActionData); - ExitOnFailure(hr, "Failed to write CertificateThumbprint to custom action data"); - - hr = WcaWriteStringToCaData(wzAppId, psczCustomActionData); - ExitOnFailure(hr, "Failed to write AppId to custom action data"); - - hr = WcaWriteStringToCaData(wzCertificateStore ? wzCertificateStore : L"", psczCustomActionData); - ExitOnFailure(hr, "Failed to write CertificateStore to custom action data"); - -LExit: - return hr; -} - -static HRESULT EnsureAppId( - __inout_z LPWSTR* psczAppId, - __in_opt HTTP_SERVICE_CONFIG_SSL_SNI_SET* pExistingSniSslSet -) -{ - HRESULT hr = S_OK; - RPC_STATUS rs = RPC_S_OK; - GUID guid = { }; - - if (!psczAppId || !*psczAppId || !**psczAppId) - { - if (pExistingSniSslSet) - { - hr = StringFromGuid(pExistingSniSslSet->ParamDesc.AppId, psczAppId); - ExitOnFailure(hr, "Failed to ensure AppId guid"); - } - else - { - rs = ::UuidCreate(&guid); - hr = HRESULT_FROM_RPC(rs); - ExitOnRootFailure(hr, "Failed to create guid for AppId"); - - hr = StringFromGuid(guid, psczAppId); - ExitOnFailure(hr, "Failed to ensure AppId guid"); - } - } - -LExit: - return hr; -} - -static HRESULT StringFromGuid( - __in REFGUID rguid, - __inout_z LPWSTR* psczGuid -) -{ - HRESULT hr = S_OK; - WCHAR wzGuid[39]; - - if (!::StringFromGUID2(rguid, wzGuid, countof(wzGuid))) - { - hr = E_OUTOFMEMORY; - ExitOnRootFailure(hr, "Failed to convert guid into string"); - } - - hr = StrAllocString(psczGuid, wzGuid, 0); - ExitOnFailure(hr, "Failed to copy guid"); - -LExit: - return hr; -} - -static HRESULT AddSniSslCert( - __in_z LPCWSTR /*wzId*/, - __in_z LPWSTR wzHost, - __in int iPort, - __in BYTE rgbCertificateThumbprint[], - __in DWORD cbCertificateThumbprint, - __in GUID* pAppId, - __in_z LPWSTR wzSslCertStore -) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { }; - - SetSniSslCertSetKey(&set.KeyDesc, wzHost, iPort); - set.ParamDesc.SslHashLength = cbCertificateThumbprint; - set.ParamDesc.pSslHash = rgbCertificateThumbprint; - set.ParamDesc.AppId = *pAppId; - set.ParamDesc.pSslCertStoreName = wzSslCertStore; - - er = ::HttpSetServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL); - if (ERROR_ALREADY_EXISTS == er) - { - hr = S_FALSE; - } - else - { - hr = HRESULT_FROM_WIN32(er); - } - - return hr; -} - -static HRESULT GetSniSslCert( - __in_z LPWSTR wzHost, - __in int nPort, - __out HTTP_SERVICE_CONFIG_SSL_SNI_SET** ppSet -) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - HTTP_SERVICE_CONFIG_SSL_SNI_QUERY query = { }; - HTTP_SERVICE_CONFIG_SSL_SNI_SET* pSet = NULL; - ULONG cbSet = 0; - - *ppSet = NULL; - - query.QueryDesc = HttpServiceConfigQueryExact; - SetSniSslCertSetKey(&query.KeyDesc, wzHost, nPort); - - er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL); - if (ERROR_INSUFFICIENT_BUFFER == er) - { - pSet = reinterpret_cast(MemAlloc(cbSet, TRUE)); - ExitOnNull(pSet, hr, E_OUTOFMEMORY, "Failed to allocate query SN SSL certificate buffer"); - - er = ::HttpQueryServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &query, sizeof(query), pSet, cbSet, &cbSet, NULL); - } - - if (ERROR_SUCCESS == er) - { - *ppSet = pSet; - pSet = NULL; - } - else if (ERROR_FILE_NOT_FOUND == er) - { - hr = S_FALSE; - } - else - { - hr = HRESULT_FROM_WIN32(er); - } - -LExit: - ReleaseMem(pSet); - - return hr; -} - -static HRESULT RemoveSniSslCert( - __in_z LPCWSTR /*wzId*/, - __in_z LPWSTR wzHost, - __in int iPort -) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - HTTP_SERVICE_CONFIG_SSL_SNI_SET set = { }; - - SetSniSslCertSetKey(&set.KeyDesc, wzHost, iPort); - - er = ::HttpDeleteServiceConfiguration(NULL, HttpServiceConfigSslSniCertInfo, &set, sizeof(set), NULL); - if (ERROR_FILE_NOT_FOUND == er) - { - hr = S_FALSE; - } - else - { - hr = HRESULT_FROM_WIN32(er); - } - - return hr; -} - -static void SetSniSslCertSetKey( - __in HTTP_SERVICE_CONFIG_SSL_SNI_KEY* pKey, - __in_z LPWSTR wzHost, - __in int iPort -) -{ - pKey->Host = wzHost; - SOCKADDR_IN* pss = reinterpret_cast(&pKey->IpPort); - pss->sin_family = AF_INET; - pss->sin_port = htons(static_cast(iPort)); -} 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 SchedHttpUrlReservationsInstall SchedHttpUrlReservationsUninstall ExecHttpUrlReservations - SchedHttpSniSslCertsInstall - SchedHttpSniSslCertsUninstall - ExecHttpSniSslCerts + SchedHttpCertificatesInstall + SchedHttpCertificatesUninstall + 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 public class HttpExtensionFixture { [Fact] - public void CanBuildUsingSniSssl() + public void CanBuildUsingSsl() { - var folder = TestData.Get("TestData", "SniSsl"); + var folder = TestData.Get("TestData", "Ssl"); var build = new Builder(folder, typeof(HttpExtensionFactory), new[] { folder }); - var results = build.BuildAndQuery(Build, "CustomAction", "Wix4HttpSniSslCert"); + var results = build.BuildAndQuery(Build, "CustomAction", "Wix6HttpCertificate"); WixAssert.CompareLineByLine(new[] { - "CustomAction:Wix4ExecHttpSniSslCertsInstall_X86\t3073\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", - "CustomAction:Wix4ExecHttpSniSslCertsUninstall_X86\t3073\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", - "CustomAction:Wix4RollbackHttpSniSslCertsInstall_X86\t3329\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", - "CustomAction:Wix4RollbackHttpSniSslCertsUninstall_X86\t3329\tWix4HttpCA_X86\tExecHttpSniSslCerts\t", - "CustomAction:Wix4SchedHttpSniSslCertsInstall_X86\t1\tWix4HttpCA_X86\tSchedHttpSniSslCertsInstall\t", - "CustomAction:Wix4SchedHttpSniSslCertsUninstall_X86\t1\tWix4HttpCA_X86\tSchedHttpSniSslCertsUninstall\t", - "Wix4HttpSniSslCert:sslC9YX6_H7UL_WGBx4DoDGI.Sj.D0\texample.com\t8080\t[SOME_THUMBPRINT]\t\t\t2\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo", + "CustomAction:Wix6ExecHttpCertificatesInstall_X86\t3073\tWix6HttpCA_X86\tExecHttpCertificates\t", + "CustomAction:Wix6ExecHttpCertificatesUninstall_X86\t3073\tWix6HttpCA_X86\tExecHttpCertificates\t", + "CustomAction:Wix6RollbackHttpCertificatesInstall_X86\t3329\tWix6HttpCA_X86\tExecHttpCertificates\t", + "CustomAction:Wix6RollbackHttpCertificatesUninstall_X86\t3329\tWix6HttpCA_X86\tExecHttpCertificates\t", + "CustomAction:Wix6SchedHttpCertificatesInstall_X86\t1\tWix6HttpCA_X86\tSchedHttpCertificatesInstall\t", + "CustomAction:Wix6SchedHttpCertificatesUninstall_X86\t1\tWix6HttpCA_X86\tSchedHttpCertificatesUninstall\t", + "Wix6HttpCertificate:ipsFO5EwsJKZPxl2W2V1nI59m1pDQs\t\t[PORTMANTEAU]\t[SOME_OTHER_THUMBPRINT]\t\t\t0\t1\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo", + "Wix6HttpCertificate:sniC9YX6_H7UL_WGBx4DoDGI.Sj.D0\texample.com\t8080\t[SOME_THUMBPRINT]\t\t\t2\t0\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo", }, results); } @@ -37,12 +38,12 @@ namespace WixToolsetTest.Http var results = build.BuildAndQuery(Build, "CustomAction", "Wix4HttpUrlAce", "Wix4HttpUrlReservation"); WixAssert.CompareLineByLine(new[] { - "CustomAction:Wix4ExecHttpUrlReservationsInstall_X86\t3073\tWix4HttpCA_X86\tExecHttpUrlReservations\t", - "CustomAction:Wix4ExecHttpUrlReservationsUninstall_X86\t3073\tWix4HttpCA_X86\tExecHttpUrlReservations\t", - "CustomAction:Wix4RollbackHttpUrlReservationsInstall_X86\t3329\tWix4HttpCA_X86\tExecHttpUrlReservations\t", - "CustomAction:Wix4RollbackHttpUrlReservationsUninstall_X86\t3329\tWix4HttpCA_X86\tExecHttpUrlReservations\t", - "CustomAction:Wix4SchedHttpUrlReservationsInstall_X86\t1\tWix4HttpCA_X86\tSchedHttpUrlReservationsInstall\t", - "CustomAction:Wix4SchedHttpUrlReservationsUninstall_X86\t1\tWix4HttpCA_X86\tSchedHttpUrlReservationsUninstall\t", + "CustomAction:Wix4ExecHttpUrlReservationsInstall_X86\t3073\tWix6HttpCA_X86\tExecHttpUrlReservations\t", + "CustomAction:Wix4ExecHttpUrlReservationsUninstall_X86\t3073\tWix6HttpCA_X86\tExecHttpUrlReservations\t", + "CustomAction:Wix4RollbackHttpUrlReservationsInstall_X86\t3329\tWix6HttpCA_X86\tExecHttpUrlReservations\t", + "CustomAction:Wix4RollbackHttpUrlReservationsUninstall_X86\t3329\tWix6HttpCA_X86\tExecHttpUrlReservations\t", + "CustomAction:Wix4SchedHttpUrlReservationsInstall_X86\t1\tWix6HttpCA_X86\tSchedHttpUrlReservationsInstall\t", + "CustomAction:Wix4SchedHttpUrlReservationsUninstall_X86\t1\tWix6HttpCA_X86\tSchedHttpUrlReservationsUninstall\t", "Wix4HttpUrlAce:aceu5os2gQoblRmzwjt85LQf997uD4\turlO23FkY2xzEY54lY6E6sXFW6glXc\tNT SERVICE\\TestService\t268435456", "Wix4HttpUrlReservation:urlO23FkY2xzEY54lY6E6sXFW6glXc\t0\t\thttp://+:80/vroot/\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo", }, results); @@ -50,8 +51,7 @@ namespace WixToolsetTest.Http private static void Build(string[] args) { - var result = WixRunner.Execute(args) - .AssertSuccess(); + /*var result =*/ WixRunner.Execute(args).AssertSuccess(); } } } diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl deleted file mode 100644 index f1df1234..00000000 --- a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.en-us.wxl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs deleted file mode 100644 index c85e9bba..00000000 --- a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/Package.wxs +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - 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 @@ - - - - - - - - - - - diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt b/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt deleted file mode 100644 index 1b4ffe8a..00000000 --- a/src/ext/Http/test/WixToolsetTest.Http/TestData/SniSsl/example.txt +++ /dev/null @@ -1 +0,0 @@ -This is example.txt. \ No newline at end of file diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.en-us.wxl b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.en-us.wxl new file mode 100644 index 00000000..f1df1234 --- /dev/null +++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.en-us.wxl @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.wxs b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.wxs new file mode 100644 index 00000000..69bdbccb --- /dev/null +++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/Package.wxs @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + diff --git a/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/example.txt b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/example.txt new file mode 100644 index 00000000..1b4ffe8a --- /dev/null +++ b/src/ext/Http/test/WixToolsetTest.Http/TestData/Ssl/example.txt @@ -0,0 +1 @@ +This is example.txt. \ No newline at end of file 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 switch (element.Name.LocalName) { case "SniSslCertificate": - this.ParseSniSslCertificateElement(intermediate, section, element, componentId); + this.ParseCertificateElement(intermediate, section, element, componentId, CertificateType.SniSsl); + break; + + case "SslCertificate": + this.ParseCertificateElement(intermediate, section, element, componentId, CertificateType.IpSsl); break; case "UrlReservation": @@ -71,7 +75,7 @@ namespace WixToolset.Http /// /// The element to parse. /// Identifier of the component that owns this SNI SSL Certificate. - private void ParseSniSslCertificateElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId) + private void ParseCertificateElement(Intermediate intermediate, IntermediateSection section, XElement node, string componentId, CertificateType type) { var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(node); Identifier id = null; @@ -138,13 +142,25 @@ namespace WixToolset.Http // Need the element ID for child element processing, so generate now if not authored. if (null == id) { - id = this.ParseHelper.CreateIdentifier("ssl", componentId, host, port); + var prefix = type == CertificateType.IpSsl ? "ips" : "sni"; + + id = this.ParseHelper.CreateIdentifier(prefix, componentId, host, port); } // Required attributes. if (null == host) { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Host")); + if (type == CertificateType.SniSsl) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Host")); + } + } + else + { + if (type == CertificateType.IpSsl) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeExceptOnElement(sourceLineNumbers, node.Name.LocalName, "Host", "SniSslCertificate")); + } } if (null == port) @@ -162,7 +178,7 @@ namespace WixToolset.Http if (!this.Messaging.EncounteredError) { - section.AddSymbol(new WixHttpSniSslCertSymbol(sourceLineNumbers, id) + section.AddSymbol(new HttpCertificateSymbol(sourceLineNumbers, id) { Host = host, Port = port, @@ -170,11 +186,12 @@ namespace WixToolset.Http AppId = appId, Store = store, HandleExisting = handleExisting, + CertificateType = type, ComponentRef = componentId, }); - this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpSniSslCertsInstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); - this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedHttpSniSslCertsUninstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); + this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix6SchedHttpCertificatesInstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); + this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix6SchedHttpCertificatesUninstall", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); } } 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 public static class HttpTableDefinitions { - public static readonly TableDefinition WixHttpSniSslCert = new TableDefinition( - "Wix4HttpSniSslCert", - HttpSymbolDefinitions.WixHttpSniSslCert, + public static readonly TableDefinition HttpCertificate = new TableDefinition( + "Wix6HttpCertificate", + HttpSymbolDefinitions.HttpCertificate, new[] { - new ColumnDefinition("Wix4HttpSniSslCert", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Host", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Host for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("HttpCertificate", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The non-localized primary key for the table.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Host", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Host for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Port for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), new ColumnDefinition("Thumbprint", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "humbprint of the SNI SSL certificate to find.", modularizeType: ColumnModularizeType.Property), new ColumnDefinition("AppId", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), new ColumnDefinition("Store", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Optional application id for the SNI SSL certificate.", modularizeType: ColumnModularizeType.Property), 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."), + new ColumnDefinition("Type", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Unknown, minValue: 0, maxValue: 1, description: "0: SNI; 1: non-SNI"), 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), }, symbolIdIsPrimaryKey: true @@ -52,7 +53,7 @@ namespace WixToolset.Http public static readonly TableDefinition[] All = new[] { - WixHttpSniSslCert, + HttpCertificate, WixHttpUrlReservation, WixHttpUrlAce, }; 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 @@ +// 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. + +namespace WixToolset.Http.Symbols +{ + /// + /// Must match constants in httpcerts.cpp + /// + public enum CertificateType + { + SniSsl = 0, + IpSsl = 1, + } +} 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 @@ +// 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. + +namespace WixToolset.Http +{ + using WixToolset.Data; + using WixToolset.Http.Symbols; + + public static partial class HttpSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition HttpCertificate = new IntermediateSymbolDefinition( + HttpSymbolDefinitionType.HttpCertificate.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Host), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Port), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Thumbprint), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.AppId), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.Store), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.HandleExisting), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.CertificateType), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(HttpCertificateSymbolFields.ComponentRef), IntermediateFieldType.String), + }, + typeof(HttpCertificateSymbol)); + } +} + +namespace WixToolset.Http.Symbols +{ + using WixToolset.Data; + + public enum HttpCertificateSymbolFields + { + Host, + Port, + Thumbprint, + AppId, + Store, + HandleExisting, + CertificateType, + ComponentRef, + } + + public class HttpCertificateSymbol : IntermediateSymbol + { + public HttpCertificateSymbol() : base(HttpSymbolDefinitions.HttpCertificate, null, null) + { + } + + public HttpCertificateSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(HttpSymbolDefinitions.HttpCertificate, sourceLineNumber, id) + { + } + + public IntermediateField this[HttpCertificateSymbolFields index] => this.Fields[(int)index]; + + public string Host + { + get => this.Fields[(int)HttpCertificateSymbolFields.Host].AsString(); + set => this.Set((int)HttpCertificateSymbolFields.Host, value); + } + + public string Port + { + get => this.Fields[(int)HttpCertificateSymbolFields.Port].AsString(); + set => this.Set((int)HttpCertificateSymbolFields.Port, value); + } + + public string Thumbprint + { + get => this.Fields[(int)HttpCertificateSymbolFields.Thumbprint].AsString(); + set => this.Set((int)HttpCertificateSymbolFields.Thumbprint, value); + } + + public string AppId + { + get => this.Fields[(int)HttpCertificateSymbolFields.AppId].AsString(); + set => this.Set((int)HttpCertificateSymbolFields.AppId, value); + } + + public string Store + { + get => this.Fields[(int)HttpCertificateSymbolFields.Store].AsString(); + set => this.Set((int)HttpCertificateSymbolFields.Store, value); + } + + public HandleExisting HandleExisting + { + get => (HandleExisting)this.Fields[(int)HttpCertificateSymbolFields.HandleExisting].AsNumber(); + set => this.Set((int)HttpCertificateSymbolFields.HandleExisting, (int)value); + } + + public CertificateType CertificateType + { + get => (CertificateType)this.Fields[(int)HttpCertificateSymbolFields.CertificateType].AsNumber(); + set => this.Set((int)HttpCertificateSymbolFields.CertificateType, (int)value); + } + + public string ComponentRef + { + get => this.Fields[(int)HttpCertificateSymbolFields.ComponentRef].AsString(); + set => this.Set((int)HttpCertificateSymbolFields.ComponentRef, value); + } + } +} 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 public enum HttpSymbolDefinitionType { - WixHttpSniSslCert, + HttpCertificate, WixHttpUrlAce, WixHttpUrlReservation, } @@ -28,8 +28,8 @@ namespace WixToolset.Http { switch (type) { - case HttpSymbolDefinitionType.WixHttpSniSslCert: - return HttpSymbolDefinitions.WixHttpSniSslCert; + case HttpSymbolDefinitionType.HttpCertificate: + return HttpSymbolDefinitions.HttpCertificate; case HttpSymbolDefinitionType.WixHttpUrlAce: 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 @@ -// 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. - -namespace WixToolset.Http -{ - using WixToolset.Data; - using WixToolset.Http.Symbols; - - public static partial class HttpSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition WixHttpSniSslCert = new IntermediateSymbolDefinition( - HttpSymbolDefinitionType.WixHttpSniSslCert.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Host), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Port), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Thumbprint), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.AppId), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.Store), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.HandleExisting), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(WixHttpSniSslCertSymbolFields.ComponentRef), IntermediateFieldType.String), - }, - typeof(WixHttpSniSslCertSymbol)); - } -} - -namespace WixToolset.Http.Symbols -{ - using WixToolset.Data; - - public enum WixHttpSniSslCertSymbolFields - { - Host, - Port, - Thumbprint, - AppId, - Store, - HandleExisting, - ComponentRef, - } - - public class WixHttpSniSslCertSymbol : IntermediateSymbol - { - public WixHttpSniSslCertSymbol() : base(HttpSymbolDefinitions.WixHttpSniSslCert, null, null) - { - } - - public WixHttpSniSslCertSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(HttpSymbolDefinitions.WixHttpSniSslCert, sourceLineNumber, id) - { - } - - public IntermediateField this[WixHttpSniSslCertSymbolFields index] => this.Fields[(int)index]; - - public string Host - { - get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Host].AsString(); - set => this.Set((int)WixHttpSniSslCertSymbolFields.Host, value); - } - - public string Port - { - get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Port].AsString(); - set => this.Set((int)WixHttpSniSslCertSymbolFields.Port, value); - } - - public string Thumbprint - { - get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Thumbprint].AsString(); - set => this.Set((int)WixHttpSniSslCertSymbolFields.Thumbprint, value); - } - - public string AppId - { - get => this.Fields[(int)WixHttpSniSslCertSymbolFields.AppId].AsString(); - set => this.Set((int)WixHttpSniSslCertSymbolFields.AppId, value); - } - - public string Store - { - get => this.Fields[(int)WixHttpSniSslCertSymbolFields.Store].AsString(); - set => this.Set((int)WixHttpSniSslCertSymbolFields.Store, value); - } - - public HandleExisting HandleExisting - { - get => (HandleExisting)this.Fields[(int)WixHttpSniSslCertSymbolFields.HandleExisting].AsNumber(); - set => this.Set((int)WixHttpSniSslCertSymbolFields.HandleExisting, (int)value); - } - - public string ComponentRef - { - get => this.Fields[(int)WixHttpSniSslCertSymbolFields.ComponentRef].AsString(); - set => this.Set((int)WixHttpSniSslCertSymbolFields.ComponentRef, value); - } - } -} 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 @@ - - - - - - + + + + + + - - - + + - - - - - - + + + + + + - - - - - - + + + + + + - - - + + - + 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 @@ - - - - - - + + + + + + -- cgit v1.2.3-55-g6feb