aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Http/wixext
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 /src/ext/Http/wixext
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
Diffstat (limited to 'src/ext/Http/wixext')
-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
6 files changed, 150 insertions, 111 deletions
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}