aboutsummaryrefslogtreecommitdiff
path: root/src/ext/Firewall/wixext
diff options
context:
space:
mode:
authorchris_bednarski <Chris.Bednarski@minfos.com.au>2023-09-21 16:03:28 +1000
committerBob Arnson <github@bobs.org>2023-11-19 12:17:13 -0500
commitdfb7512b85536b7726080648f2228cf8d0153724 (patch)
treed053018ee47afe7e349dda6739a6580c771a1a3d /src/ext/Firewall/wixext
parent80e604761b4f43b9b79a4878fcae360b071a7c35 (diff)
downloadwix-dfb7512b85536b7726080648f2228cf8d0153724.tar.gz
wix-dfb7512b85536b7726080648f2228cf8d0153724.tar.bz2
wix-dfb7512b85536b7726080648f2228cf8d0153724.zip
add firewall extension decompiler, make msi modifications work, add all attributes
Diffstat (limited to 'src/ext/Firewall/wixext')
-rw-r--r--src/ext/Firewall/wixext/FirewallCompiler.cs623
-rw-r--r--src/ext/Firewall/wixext/FirewallConstants.cs17
-rw-r--r--src/ext/Firewall/wixext/FirewallDecompiler.cs317
-rw-r--r--src/ext/Firewall/wixext/FirewallErrors.cs29
-rw-r--r--src/ext/Firewall/wixext/FirewallTableDefinitions.cs28
-rw-r--r--src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs142
-rw-r--r--src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj4
7 files changed, 1063 insertions, 97 deletions
diff --git a/src/ext/Firewall/wixext/FirewallCompiler.cs b/src/ext/Firewall/wixext/FirewallCompiler.cs
index ed49ba9c..c4a5318c 100644
--- a/src/ext/Firewall/wixext/FirewallCompiler.cs
+++ b/src/ext/Firewall/wixext/FirewallCompiler.cs
@@ -35,7 +35,7 @@ namespace WixToolset.Firewall
35 switch (element.Name.LocalName) 35 switch (element.Name.LocalName)
36 { 36 {
37 case "FirewallException": 37 case "FirewallException":
38 this.ParseFirewallExceptionElement(intermediate, section, element, fileComponentId, fileId); 38 this.ParseFirewallExceptionElement(intermediate, section, parentElement, element, fileComponentId, fileId, null);
39 break; 39 break;
40 default: 40 default:
41 this.ParseHelper.UnexpectedElement(parentElement, element); 41 this.ParseHelper.UnexpectedElement(parentElement, element);
@@ -48,7 +48,35 @@ namespace WixToolset.Firewall
48 switch (element.Name.LocalName) 48 switch (element.Name.LocalName)
49 { 49 {
50 case "FirewallException": 50 case "FirewallException":
51 this.ParseFirewallExceptionElement(intermediate, section, element, componentId, null); 51 this.ParseFirewallExceptionElement(intermediate, section, parentElement, element, componentId, null, null);
52 break;
53 default:
54 this.ParseHelper.UnexpectedElement(parentElement, element);
55 break;
56 }
57 break;
58 case "ServiceConfig":
59 var serviceConfigName = context["ServiceConfigServiceName"];
60 var serviceConfigComponentId = context["ServiceConfigComponentId"];
61
62 switch (element.Name.LocalName)
63 {
64 case "FirewallException":
65 this.ParseFirewallExceptionElement(intermediate, section, parentElement, element, serviceConfigComponentId, null, serviceConfigName);
66 break;
67 default:
68 this.ParseHelper.UnexpectedElement(parentElement, element);
69 break;
70 }
71 break;
72 case "ServiceInstall":
73 var serviceInstallName = context["ServiceInstallName"];
74 var serviceInstallComponentId = context["ServiceInstallComponentId"];
75
76 switch (element.Name.LocalName)
77 {
78 case "FirewallException":
79 this.ParseFirewallExceptionElement(intermediate, section, parentElement, element, serviceInstallComponentId, null, serviceInstallName);
52 break; 80 break;
53 default: 81 default:
54 this.ParseHelper.UnexpectedElement(parentElement, element); 82 this.ParseHelper.UnexpectedElement(parentElement, element);
@@ -64,10 +92,12 @@ namespace WixToolset.Firewall
64 /// <summary> 92 /// <summary>
65 /// Parses a FirewallException element. 93 /// Parses a FirewallException element.
66 /// </summary> 94 /// </summary>
95 /// <param name="parentElement">The parent element of the one being parsed.</param>
67 /// <param name="element">The element to parse.</param> 96 /// <param name="element">The element to parse.</param>
68 /// <param name="componentId">Identifier of the component that owns this firewall exception.</param> 97 /// <param name="componentId">Identifier of the component that owns this firewall exception.</param>
69 /// <param name="fileId">The file identifier of the parent element (null if nested under Component).</param> 98 /// <param name="fileId">The file identifier of the parent element (null if nested under Component).</param>
70 private void ParseFirewallExceptionElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string fileId) 99 /// <param name="serviceName">The service name of the parent element (null if not nested under ServiceConfig or ServiceInstall).</param>
100 private void ParseFirewallExceptionElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, string componentId, string fileId, string serviceName)
71 { 101 {
72 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); 102 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
73 Identifier id = null; 103 Identifier id = null;
@@ -76,12 +106,32 @@ namespace WixToolset.Firewall
76 string file = null; 106 string file = null;
77 string program = null; 107 string program = null;
78 string port = null; 108 string port = null;
79 int? protocol = null; 109 string protocol = null;
80 int? profile = null; 110 string profile = null;
81 string scope = null; 111 string scope = null;
82 string remoteAddresses = null; 112 string remoteAddresses = null;
83 string description = null; 113 string description = null;
84 int? direction = null; 114 int? direction = null;
115 string protocolValue = null;
116 string action = null;
117 string edgeTraversal = null;
118 string enabled = null;
119 string grouping = null;
120 string icmpTypesAndCodes = null;
121 string interfaces = null;
122 string interfaceValue = null;
123 string interfaceTypes = null;
124 string interfaceTypeValue = null;
125 string localScope = null;
126 string localAddresses = null;
127 string remotePort = null;
128 string service = null;
129 string localAppPackageId = null;
130 string localUserAuthorizedList = null;
131 string localUserOwner = null;
132 string remoteMachineAuthorizedList = null;
133 string remoteUserAuthorizedList = null;
134 string secureFlags = null;
85 135
86 foreach (var attrib in element.Attributes()) 136 foreach (var attrib in element.Attributes())
87 { 137 {
@@ -96,9 +146,9 @@ namespace WixToolset.Firewall
96 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); 146 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
97 break; 147 break;
98 case "File": 148 case "File":
99 if (null != fileId) 149 if (fileId != null)
100 { 150 {
101 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "File", "File")); 151 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "File", parentElement.Name.LocalName));
102 } 152 }
103 else 153 else
104 { 154 {
@@ -106,15 +156,31 @@ namespace WixToolset.Firewall
106 } 156 }
107 break; 157 break;
108 case "IgnoreFailure": 158 case "IgnoreFailure":
109 if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) 159 if (this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.Yes)
110 { 160 {
111 attributes |= 0x1; // feaIgnoreFailures 161 attributes |= 0x1; // feaIgnoreFailures
112 } 162 }
113 break; 163 break;
164 case "OnUpdate":
165 var onupdate = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
166 switch (onupdate)
167 {
168 case "DoNothing":
169 attributes |= 0x2; // feaIgnoreUpdates
170 break;
171 case "EnableOnly":
172 attributes |= 0x4; // feaEnableOnUpdate
173 break;
174
175 default:
176 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "OnUpdate", onupdate, "EnableOnly", "DoNothing"));
177 break;
178 }
179 break;
114 case "Program": 180 case "Program":
115 if (null != fileId) 181 if (fileId != null)
116 { 182 {
117 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "Program", "File")); 183 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "Program", parentElement.Name.LocalName));
118 } 184 }
119 else 185 else
120 { 186 {
@@ -125,22 +191,28 @@ namespace WixToolset.Firewall
125 port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); 191 port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
126 break; 192 break;
127 case "Protocol": 193 case "Protocol":
128 var protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); 194 protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
129 switch (protocolValue) 195 switch (protocolValue)
130 { 196 {
197 case FirewallConstants.IntegerNotSetString:
198 break;
199
131 case "tcp": 200 case "tcp":
132 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP; 201 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP.ToString();
133 break; 202 break;
134 case "udp": 203 case "udp":
135 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_UDP; 204 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_UDP.ToString();
136 break; 205 break;
206
137 default: 207 default:
138 int parsedProtocol; 208 protocol = protocolValue;
139 if (!Int32.TryParse(protocolValue, out parsedProtocol) || parsedProtocol > 255 || parsedProtocol < 0) 209 if (!this.ParseHelper.ContainsProperty(protocolValue))
140 { 210 {
141 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Protocol", protocolValue, "tcp", "udp", "0-255")); 211 if (!Int32.TryParse(protocolValue, out var parsedProtocol) || parsedProtocol > 255 || parsedProtocol < 0)
212 {
213 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Protocol", protocolValue, "tcp", "udp", "0-255"));
214 }
142 } 215 }
143 protocol = parsedProtocol;
144 break; 216 break;
145 } 217 }
146 break; 218 break;
@@ -167,7 +239,11 @@ namespace WixToolset.Firewall
167 remoteAddresses = "DefaultGateway"; 239 remoteAddresses = "DefaultGateway";
168 break; 240 break;
169 default: 241 default:
170 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Scope", scope, "any", "localSubnet", "DNS", "DHCP", "WINS", "defaultGateway")); 242 remoteAddresses = scope;
243 if (!this.ParseHelper.ContainsProperty(scope))
244 {
245 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Scope", scope, "any", "localSubnet", "DNS", "DHCP", "WINS", "defaultGateway"));
246 }
171 break; 247 break;
172 } 248 }
173 break; 249 break;
@@ -176,19 +252,23 @@ namespace WixToolset.Firewall
176 switch (profileValue) 252 switch (profileValue)
177 { 253 {
178 case "domain": 254 case "domain":
179 profile = FirewallConstants.NET_FW_PROFILE2_DOMAIN; 255 profile = FirewallConstants.NET_FW_PROFILE2_DOMAIN.ToString();
180 break; 256 break;
181 case "private": 257 case "private":
182 profile = FirewallConstants.NET_FW_PROFILE2_PRIVATE; 258 profile = FirewallConstants.NET_FW_PROFILE2_PRIVATE.ToString();
183 break; 259 break;
184 case "public": 260 case "public":
185 profile = FirewallConstants.NET_FW_PROFILE2_PUBLIC; 261 profile = FirewallConstants.NET_FW_PROFILE2_PUBLIC.ToString();
186 break; 262 break;
187 case "all": 263 case "all":
188 profile = FirewallConstants.NET_FW_PROFILE2_ALL; 264 profile = FirewallConstants.NET_FW_PROFILE2_ALL.ToString();
189 break; 265 break;
190 default: 266 default:
191 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Profile", profileValue, "domain", "private", "public", "all")); 267 profile = profileValue;
268 if (!this.ParseHelper.ContainsProperty(profileValue))
269 {
270 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Profile", profileValue, "domain", "private", "public", "all"));
271 }
192 break; 272 break;
193 } 273 }
194 break; 274 break;
@@ -200,6 +280,196 @@ namespace WixToolset.Firewall
200 ? FirewallConstants.NET_FW_RULE_DIR_OUT 280 ? FirewallConstants.NET_FW_RULE_DIR_OUT
201 : FirewallConstants.NET_FW_RULE_DIR_IN; 281 : FirewallConstants.NET_FW_RULE_DIR_IN;
202 break; 282 break;
283 case "Action":
284 action = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
285 switch (action)
286 {
287 case "Block":
288 action = "0";
289 break;
290 case "Allow":
291 action = "1";
292 break;
293
294 default:
295 if (!this.ParseHelper.ContainsProperty(action))
296 {
297 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Action", action, "Allow", "Block"));
298 }
299 break;
300 }
301 break;
302 case "EdgeTraversal":
303 edgeTraversal = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
304 switch (edgeTraversal)
305 {
306 case "Deny":
307 edgeTraversal = FirewallConstants.NET_FW_EDGE_TRAVERSAL_TYPE_DENY.ToString();
308 break;
309 case "Allow":
310 edgeTraversal = FirewallConstants.NET_FW_EDGE_TRAVERSAL_TYPE_ALLOW.ToString();
311 break;
312 case "DeferToApp":
313 attributes |= 0x8; // feaAddINetFwRule2
314 edgeTraversal = FirewallConstants.NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_APP.ToString();
315 break;
316 case "DeferToUser":
317 attributes |= 0x8; // feaAddINetFwRule2
318 edgeTraversal = FirewallConstants.NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_USER.ToString();
319 break;
320
321 default:
322 if (!this.ParseHelper.ContainsProperty(edgeTraversal))
323 {
324 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "EdgeTraversal", edgeTraversal, "Allow", "DeferToApp", "DeferToUser", "Deny"));
325 }
326 break;
327 }
328 break;
329 case "Enabled":
330 enabled = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
331 if (!this.ParseHelper.ContainsProperty(enabled))
332 {
333 switch (this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib))
334 {
335 case YesNoType.Yes:
336 enabled = "1";
337 break;
338 case YesNoType.No:
339 enabled = "0";
340 break;
341
342 default:
343 this.Messaging.Write(ErrorMessages.IllegalYesNoValue(sourceLineNumbers, element.Name.LocalName, "Enabled", enabled));
344 break;
345 }
346 }
347 break;
348 case "Grouping":
349 grouping = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
350 break;
351 case "IcmpTypesAndCodes":
352 icmpTypesAndCodes = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
353 break;
354 case "Interface":
355 interfaceValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
356 interfaces = interfaceValue;
357 break;
358 case "InterfaceType":
359 interfaceTypeValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
360 switch (interfaceTypeValue)
361 {
362 case "RemoteAccess":
363 case "Wireless":
364 case "Lan":
365 case "All":
366 break;
367
368 default:
369 if (!this.ParseHelper.ContainsProperty(interfaceTypeValue))
370 {
371 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "InterfaceType", interfaceTypeValue, "RemoteAccess", "Wireless", "Lan", "All"));
372 }
373 break;
374 }
375 interfaceTypes = interfaceTypeValue;
376 break;
377 case "LocalScope":
378 localScope = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
379 switch (localScope)
380 {
381 case "any":
382 localAddresses = "*";
383 break;
384 case "localSubnet":
385 localAddresses = "LocalSubnet";
386 break;
387 case "DNS":
388 localAddresses = "dns";
389 break;
390 case "DHCP":
391 localAddresses = "dhcp";
392 break;
393 case "WINS":
394 localAddresses = "wins";
395 break;
396 case "defaultGateway":
397 localAddresses = "DefaultGateway";
398 break;
399
400 default:
401 if (!this.ParseHelper.ContainsProperty(localScope))
402 {
403 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "LocalScope", localScope, "any", "localSubnet", "DNS", "DHCP", "WINS", "defaultGateway"));
404 }
405 else
406 {
407 localAddresses = localScope;
408 }
409 break;
410 }
411 break;
412 case "RemotePort":
413 remotePort = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
414 break;
415 case "Service":
416 if (serviceName != null)
417 {
418 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "Service", parentElement.Name.LocalName));
419 }
420 else
421 {
422 service = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
423 }
424 break;
425 case "LocalAppPackageId":
426 localAppPackageId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
427 attributes |= 0x10; // feaAddINetFwRule3
428 break;
429 case "LocalUserAuthorizedList":
430 localUserAuthorizedList = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
431 attributes |= 0x10; // feaAddINetFwRule3
432 break;
433 case "LocalUserOwner":
434 localUserOwner = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
435 attributes |= 0x10; // feaAddINetFwRule3
436 break;
437 case "RemoteMachineAuthorizedList":
438 remoteMachineAuthorizedList = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
439 attributes |= 0x10; // feaAddINetFwRule3
440 break;
441 case "RemoteUserAuthorizedList":
442 remoteUserAuthorizedList = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
443 attributes |= 0x10; // feaAddINetFwRule3
444 break;
445 case "IPSecSecureFlags":
446 secureFlags = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
447 attributes |= 0x10; // feaAddINetFwRule3
448 if (!this.ParseHelper.ContainsProperty(secureFlags))
449 {
450 switch (secureFlags)
451 {
452 case "None":
453 secureFlags = "0";
454 break;
455 case "NoEncapsulation":
456 secureFlags = "1";
457 break;
458 case "WithIntegrity":
459 secureFlags = "2";
460 break;
461 case "NegotiateEncryption":
462 secureFlags = "3";
463 break;
464 case "Encrypt":
465 secureFlags = "4";
466 break;
467 default:
468 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "IPSecSecureFlags", secureFlags, "None", "NoEncapsulation", "WithIntegrity", "NegotiateEncryption", "Encrypt"));
469 break;
470 }
471 }
472 break;
203 default: 473 default:
204 this.ParseHelper.UnexpectedAttribute(element, attrib); 474 this.ParseHelper.UnexpectedAttribute(element, attrib);
205 break; 475 break;
@@ -211,7 +481,7 @@ namespace WixToolset.Firewall
211 } 481 }
212 } 482 }
213 483
214 // parse RemoteAddress children 484 // parse children
215 foreach (var child in element.Elements()) 485 foreach (var child in element.Elements())
216 { 486 {
217 if (this.Namespace == child.Name.Namespace) 487 if (this.Namespace == child.Name.Namespace)
@@ -219,7 +489,7 @@ namespace WixToolset.Firewall
219 switch (child.Name.LocalName) 489 switch (child.Name.LocalName)
220 { 490 {
221 case "RemoteAddress": 491 case "RemoteAddress":
222 if (null != scope) 492 if (scope != null)
223 { 493 {
224 this.Messaging.Write(FirewallErrors.IllegalRemoteAddressWithScopeAttribute(sourceLineNumbers)); 494 this.Messaging.Write(FirewallErrors.IllegalRemoteAddressWithScopeAttribute(sourceLineNumbers));
225 } 495 }
@@ -228,6 +498,37 @@ namespace WixToolset.Firewall
228 this.ParseRemoteAddressElement(intermediate, section, child, ref remoteAddresses); 498 this.ParseRemoteAddressElement(intermediate, section, child, ref remoteAddresses);
229 } 499 }
230 break; 500 break;
501 case "Interface":
502 if (interfaceValue != null)
503 {
504 this.Messaging.Write(FirewallErrors.IllegalInterfaceWithInterfaceAttribute(sourceLineNumbers));
505 }
506 else
507 {
508 this.ParseInterfaceElement(intermediate, section, child, ref interfaces);
509 }
510 break;
511 case "InterfaceType":
512 if (interfaceTypeValue != null)
513 {
514 this.Messaging.Write(FirewallErrors.IllegalInterfaceTypeWithInterfaceTypeAttribute(sourceLineNumbers));
515 }
516 else
517 {
518 this.ParseInterfaceTypeElement(intermediate, section, child, ref interfaceTypes);
519 }
520 break;
521 case "LocalAddress":
522 if (localScope != null)
523 {
524 this.Messaging.Write(FirewallErrors.IllegalLocalAddressWithLocalScopeAttribute(sourceLineNumbers));
525 }
526 else
527 {
528 this.ParseLocalAddressElement(intermediate, section, child, ref localAddresses);
529 }
530 break;
531
231 default: 532 default:
232 this.ParseHelper.UnexpectedElement(element, child); 533 this.ParseHelper.UnexpectedElement(element, child);
233 break; 534 break;
@@ -239,54 +540,84 @@ namespace WixToolset.Firewall
239 } 540 }
240 } 541 }
241 542
242 if (null == id) 543 if (id == null)
243 { 544 {
244 id = this.ParseHelper.CreateIdentifier("fex", name, remoteAddresses, componentId); 545 // firewall rule names are meant to be unique
546 id = this.ParseHelper.CreateIdentifier("fex", name, componentId);
245 } 547 }
246 548
247 // Name is required 549 // Name is required
248 if (null == name) 550 if (name == null)
249 { 551 {
250 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); 552 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
251 } 553 }
252 554
253 // Scope or child RemoteAddress(es) are required 555 if (service == null)
254 if (null == remoteAddresses)
255 { 556 {
256 this.Messaging.Write(ErrorMessages.ExpectedAttributeOrElement(sourceLineNumbers, element.Name.LocalName, "Scope", "RemoteAddress")); 557 service = serviceName;
257 } 558 }
258 559
259 // can't have both Program and File 560 // can't have both Program and File
260 if (null != program && null != file) 561 if (program != null && file != null)
261 { 562 {
262 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "File", "Program")); 563 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "File", "Program"));
263 } 564 }
264 565
265 // must be nested under File, have File or Program attributes, or have Port attribute 566 // Defer to user edge traversal setting can only be used in a firewall rule where program path and TCP/UDP protocol are specified with no additional conditions.
266 if (String.IsNullOrEmpty(fileId) && String.IsNullOrEmpty(file) && String.IsNullOrEmpty(program) && String.IsNullOrEmpty(port)) 567 if (edgeTraversal == FirewallConstants.NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_USER.ToString())
267 { 568 {
268 this.Messaging.Write(FirewallErrors.NoExceptionSpecified(sourceLineNumbers)); 569 if (protocol != null && !(protocol == FirewallConstants.NET_FW_IP_PROTOCOL_TCP.ToString() || protocol == FirewallConstants.NET_FW_IP_PROTOCOL_UDP.ToString()))
269 } 570 {
571 this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithLegalList(sourceLineNumbers, element.Name.LocalName, "Protocol", protocolValue, "tcp,udp"));
572 }
270 573
271 // Ports can only be specified if the protocol is TCP or UDP. 574 if (String.IsNullOrEmpty(fileId) && String.IsNullOrEmpty(file) && String.IsNullOrEmpty(program))
272 if (!String.IsNullOrEmpty(port) && protocol.HasValue)
273 {
274 switch(protocol.Value)
275 { 575 {
276 case FirewallConstants.NET_FW_IP_PROTOCOL_TCP: 576 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Program", "EdgeTraversal", "DeferToUser"));
277 case FirewallConstants.NET_FW_IP_PROTOCOL_UDP: 577 }
278 break;
279 578
280 default: 579 if (port != null)
281 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Port", "Protocol", protocol.Value.ToString())); 580 {
282 break; 581 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Port", "EdgeTraversal", "DeferToUser"));
582 }
583
584 if (remotePort != null)
585 {
586 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "RemotePort", "EdgeTraversal", "DeferToUser"));
587 }
588
589 if (localScope != null)
590 {
591 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "LocalScope", "EdgeTraversal", "DeferToUser"));
592 }
593
594 if (scope != null)
595 {
596 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Scope", "EdgeTraversal", "DeferToUser"));
597 }
598
599 if (profile != null)
600 {
601 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Profile", "EdgeTraversal", "DeferToUser"));
602 }
603
604 if (service != null)
605 {
606 if (serviceName != null)
607 {
608 this.Messaging.Write(ErrorMessages.IllegalAttributeValueWhenNested(sourceLineNumbers, element.Name.LocalName, "EdgeTraversal", "DeferToUser", parentElement.Name.LocalName));
609 }
610 else
611 {
612 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Service", "EdgeTraversal", "DeferToUser"));
613 }
283 } 614 }
284 } 615 }
285 616
286 if (!this.Messaging.EncounteredError) 617 if (!this.Messaging.EncounteredError)
287 { 618 {
288 // at this point, File attribute and File parent element are treated the same 619 // at this point, File attribute and File parent element are treated the same
289 if (null != file) 620 if (file != null)
290 { 621 {
291 fileId = file; 622 fileId = file;
292 } 623 }
@@ -295,28 +626,38 @@ namespace WixToolset.Firewall
295 { 626 {
296 Name = name, 627 Name = name,
297 RemoteAddresses = remoteAddresses, 628 RemoteAddresses = remoteAddresses,
298 Profile = profile ?? FirewallConstants.NET_FW_PROFILE2_ALL,
299 ComponentRef = componentId, 629 ComponentRef = componentId,
300 Description = description, 630 Description = description,
301 Direction = direction ?? FirewallConstants.NET_FW_RULE_DIR_IN, 631 Direction = direction ?? FirewallConstants.NET_FW_RULE_DIR_IN,
632 Action = action ?? FirewallConstants.IntegerNotSetString,
633 EdgeTraversal = edgeTraversal ?? FirewallConstants.IntegerNotSetString,
634 Enabled = enabled ?? FirewallConstants.IntegerNotSetString,
635 Grouping = grouping,
636 IcmpTypesAndCodes = icmpTypesAndCodes,
637 Interfaces = interfaces,
638 InterfaceTypes = interfaceTypes,
639 LocalAddresses = localAddresses,
640 Port = port,
641 Profile = profile ?? FirewallConstants.IntegerNotSetString,
642 Protocol = protocol ?? FirewallConstants.IntegerNotSetString,
643 RemotePort = remotePort,
644 ServiceName = service,
645 LocalAppPackageId = localAppPackageId,
646 LocalUserAuthorizedList = localUserAuthorizedList,
647 LocalUserOwner = localUserOwner,
648 RemoteMachineAuthorizedList = remoteMachineAuthorizedList,
649 RemoteUserAuthorizedList = remoteUserAuthorizedList,
650 SecureFlags = secureFlags ?? FirewallConstants.IntegerNotSetString,
302 }); 651 });
303 652
304 if (!String.IsNullOrEmpty(port)) 653 if (String.IsNullOrEmpty(protocol))
305 { 654 {
306 symbol.Port = port; 655 if (!String.IsNullOrEmpty(port) || !String.IsNullOrEmpty(remotePort))
307
308 if (!protocol.HasValue)
309 { 656 {
310 // default protocol is "TCP" 657 symbol.Protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP.ToString();
311 protocol = FirewallConstants.NET_FW_IP_PROTOCOL_TCP;
312 } 658 }
313 } 659 }
314 660
315 if (protocol.HasValue)
316 {
317 symbol.Protocol = protocol.Value;
318 }
319
320 if (!String.IsNullOrEmpty(fileId)) 661 if (!String.IsNullOrEmpty(fileId))
321 { 662 {
322 symbol.Program = $"[#{fileId}]"; 663 symbol.Program = $"[#{fileId}]";
@@ -327,7 +668,7 @@ namespace WixToolset.Firewall
327 symbol.Program = program; 668 symbol.Program = program;
328 } 669 }
329 670
330 if (CompilerConstants.IntegerNotSet != attributes) 671 if (attributes != CompilerConstants.IntegerNotSet)
331 { 672 {
332 symbol.Attributes = attributes; 673 symbol.Attributes = attributes;
333 } 674 }
@@ -382,5 +723,167 @@ namespace WixToolset.Firewall
382 } 723 }
383 } 724 }
384 } 725 }
726
727 /// <summary>
728 /// Parses an Interface element
729 /// </summary>
730 /// <param name="element">The element to parse.</param>
731 private void ParseInterfaceElement(Intermediate intermediate, IntermediateSection section, XElement element, ref string interfaces)
732 {
733 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
734 string name = null;
735
736 // no attributes
737 foreach (var attrib in element.Attributes())
738 {
739 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
740 {
741 switch (attrib.Name.LocalName)
742 {
743 case "Name":
744 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
745 break;
746 }
747 }
748 else
749 {
750 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
751 }
752 }
753
754 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
755
756 if (String.IsNullOrEmpty(name))
757 {
758 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
759 }
760 else
761 {
762 if (String.IsNullOrEmpty(interfaces))
763 {
764 interfaces = name;
765 }
766 else
767 {
768 interfaces = String.Concat(interfaces, FirewallConstants.FORBIDDEN_FIREWALL_CHAR, name);
769 }
770 }
771 }
772
773 /// <summary>
774 /// Parses an InterfaceType element
775 /// </summary>
776 /// <param name="element">The element to parse.</param>
777 private void ParseInterfaceTypeElement(Intermediate intermediate, IntermediateSection section, XElement element, ref string interfaceTypes)
778 {
779 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
780 string value = null;
781
782 // no attributes
783 foreach (var attrib in element.Attributes())
784 {
785 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
786 {
787 switch (attrib.Name.LocalName)
788 {
789 case "Value":
790 value = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
791 break;
792 }
793 }
794 else
795 {
796 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
797 }
798 }
799
800 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
801
802 if (String.IsNullOrEmpty(value))
803 {
804 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Value"));
805 }
806 else
807 {
808 switch (value)
809 {
810 case "RemoteAccess":
811 case "Wireless":
812 case "Lan":
813 case "All":
814 break;
815
816 default:
817 if (!this.ParseHelper.ContainsProperty(value))
818 {
819 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Value", value, "RemoteAccess", "Wireless", "Lan", "All"));
820 value = null;
821 }
822 break;
823 }
824
825 if (String.IsNullOrEmpty(interfaceTypes))
826 {
827 interfaceTypes = value;
828 }
829 else if (interfaceTypes.Contains("All"))
830 {
831 if (value != "All")
832 {
833 this.Messaging.Write(FirewallErrors.IllegalInterfaceTypeWithInterfaceTypeAll(sourceLineNumbers));
834 }
835 }
836 else if(!String.IsNullOrEmpty(value))
837 {
838 interfaceTypes = String.Concat(interfaceTypes, ",", value);
839 }
840 }
841 }
842
843 /// <summary>
844 /// Parses a RemoteAddress element
845 /// </summary>
846 /// <param name="element">The element to parse.</param>
847 private void ParseLocalAddressElement(Intermediate intermediate, IntermediateSection section, XElement element, ref string localAddresses)
848 {
849 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
850 string address = null;
851
852 // no attributes
853 foreach (var attrib in element.Attributes())
854 {
855 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
856 {
857 switch (attrib.Name.LocalName)
858 {
859 case "Value":
860 address = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
861 break;
862 }
863 }
864 else
865 {
866 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
867 }
868 }
869
870 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
871
872 if (String.IsNullOrEmpty(address))
873 {
874 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Value"));
875 }
876 else
877 {
878 if (String.IsNullOrEmpty(localAddresses))
879 {
880 localAddresses = address;
881 }
882 else
883 {
884 localAddresses = String.Concat(localAddresses, ",", address);
885 }
886 }
887 }
385 } 888 }
386} 889}
diff --git a/src/ext/Firewall/wixext/FirewallConstants.cs b/src/ext/Firewall/wixext/FirewallConstants.cs
index 5ecfe032..b7ed8728 100644
--- a/src/ext/Firewall/wixext/FirewallConstants.cs
+++ b/src/ext/Firewall/wixext/FirewallConstants.cs
@@ -9,6 +9,11 @@ namespace WixToolset.Firewall
9 internal static readonly XNamespace Namespace = "http://wixtoolset.org/schemas/v4/wxs/firewall"; 9 internal static readonly XNamespace Namespace = "http://wixtoolset.org/schemas/v4/wxs/firewall";
10 internal static readonly XName FirewallExceptionName = Namespace + "FirewallException"; 10 internal static readonly XName FirewallExceptionName = Namespace + "FirewallException";
11 internal static readonly XName RemoteAddressName = Namespace + "RemoteAddress"; 11 internal static readonly XName RemoteAddressName = Namespace + "RemoteAddress";
12 internal static readonly XName InterfaceName = Namespace + "Interface";
13 internal static readonly XName InterfaceTypeName = Namespace + "InterfaceType";
14 internal static readonly XName LocalAddressName = Namespace + "LocalAddress";
15
16 internal const string IntegerNotSetString = "-2147483648";
12 17
13 // from icftypes.h 18 // from icftypes.h
14 public const int NET_FW_RULE_DIR_IN = 1; 19 public const int NET_FW_RULE_DIR_IN = 1;
@@ -21,5 +26,17 @@ namespace WixToolset.Firewall
21 public const int NET_FW_PROFILE2_PRIVATE = 0x0002; 26 public const int NET_FW_PROFILE2_PRIVATE = 0x0002;
22 public const int NET_FW_PROFILE2_PUBLIC = 0x0004; 27 public const int NET_FW_PROFILE2_PUBLIC = 0x0004;
23 public const int NET_FW_PROFILE2_ALL = 0x7FFFFFFF; 28 public const int NET_FW_PROFILE2_ALL = 0x7FFFFFFF;
29
30 // from icftypes.h
31 public const int NET_FW_EDGE_TRAVERSAL_TYPE_DENY = 0;
32 public const int NET_FW_EDGE_TRAVERSAL_TYPE_ALLOW = 1;
33 public const int NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_APP = 2;
34 public const int NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_USER = 3;
35
36 /// <summary>
37 /// Firewall rules are stored in the registry.<br/>
38 /// The pipe character is used to split firewall rule attributes, so is not permitted in any of them.
39 /// </summary>
40 public const char FORBIDDEN_FIREWALL_CHAR = '|';
24 } 41 }
25} 42}
diff --git a/src/ext/Firewall/wixext/FirewallDecompiler.cs b/src/ext/Firewall/wixext/FirewallDecompiler.cs
index 9ddd8a9a..7fafab17 100644
--- a/src/ext/Firewall/wixext/FirewallDecompiler.cs
+++ b/src/ext/Firewall/wixext/FirewallDecompiler.cs
@@ -8,6 +8,8 @@ namespace WixToolset.Firewall
8 using WixToolset.Data; 8 using WixToolset.Data;
9 using WixToolset.Data.WindowsInstaller; 9 using WixToolset.Data.WindowsInstaller;
10 using WixToolset.Extensibility; 10 using WixToolset.Extensibility;
11 using WixToolset.Extensibility.Data;
12 using WixToolset.Extensibility.Services;
11 13
12 /// <summary> 14 /// <summary>
13 /// The decompiler for the WiX Toolset Firewall Extension. 15 /// The decompiler for the WiX Toolset Firewall Extension.
@@ -16,6 +18,14 @@ namespace WixToolset.Firewall
16 { 18 {
17 public override IReadOnlyCollection<TableDefinition> TableDefinitions => FirewallTableDefinitions.All; 19 public override IReadOnlyCollection<TableDefinition> TableDefinitions => FirewallTableDefinitions.All;
18 20
21 private IParseHelper ParseHelper { get; set; }
22
23 public override void PreDecompile(IWindowsInstallerDecompileContext context, IWindowsInstallerDecompilerHelper helper)
24 {
25 base.PreDecompile(context, helper);
26 this.ParseHelper = context.ServiceProvider.GetService<IParseHelper>();
27 }
28
19 /// <summary> 29 /// <summary>
20 /// Called at the beginning of the decompilation of a database. 30 /// Called at the beginning of the decompilation of a database.
21 /// </summary> 31 /// </summary>
@@ -32,6 +42,8 @@ namespace WixToolset.Firewall
32 { 42 {
33 switch (table.Name) 43 switch (table.Name)
34 { 44 {
45 case "WixFirewallException":
46 case "Wix4FirewallException":
35 case "Wix5FirewallException": 47 case "Wix5FirewallException":
36 this.DecompileWixFirewallExceptionTable(table); 48 this.DecompileWixFirewallExceptionTable(table);
37 break; 49 break;
@@ -57,7 +69,7 @@ namespace WixToolset.Firewall
57 /// <param name="table">The table to decompile.</param> 69 /// <param name="table">The table to decompile.</param>
58 private void DecompileWixFirewallExceptionTable(Table table) 70 private void DecompileWixFirewallExceptionTable(Table table)
59 { 71 {
60 foreach (Row row in table.Rows) 72 foreach (var row in table.Rows)
61 { 73 {
62 var firewallException = new XElement(FirewallConstants.FirewallExceptionName, 74 var firewallException = new XElement(FirewallConstants.FirewallExceptionName,
63 new XAttribute("Id", row.FieldAsString(0)), 75 new XAttribute("Id", row.FieldAsString(0)),
@@ -90,13 +102,20 @@ namespace WixToolset.Firewall
90 firewallException.Add(new XAttribute("Scope", "defaultGateway")); 102 firewallException.Add(new XAttribute("Scope", "defaultGateway"));
91 break; 103 break;
92 default: 104 default:
93 FirewallDecompiler.AddRemoteAddress(firewallException, addresses[0]); 105 if (this.ParseHelper.ContainsProperty(addresses[0]))
106 {
107 firewallException.Add(new XAttribute("Scope", addresses[0]));
108 }
109 else
110 {
111 FirewallDecompiler.AddRemoteAddress(firewallException, addresses[0]);
112 }
94 break; 113 break;
95 } 114 }
96 } 115 }
97 else 116 else
98 { 117 {
99 foreach (string address in addresses) 118 foreach (var address in addresses)
100 { 119 {
101 FirewallDecompiler.AddRemoteAddress(firewallException, address); 120 FirewallDecompiler.AddRemoteAddress(firewallException, address);
102 } 121 }
@@ -110,16 +129,19 @@ namespace WixToolset.Firewall
110 129
111 if (!row.IsColumnEmpty(4)) 130 if (!row.IsColumnEmpty(4))
112 { 131 {
113 switch (Convert.ToInt32(row[4])) 132 switch (row.FieldAsString(4))
114 { 133 {
115 case FirewallConstants.NET_FW_IP_PROTOCOL_TCP: 134 case FirewallConstants.IntegerNotSetString:
135 break;
136 case "6":
116 firewallException.Add(new XAttribute("Protocol", "tcp")); 137 firewallException.Add(new XAttribute("Protocol", "tcp"));
117 break; 138 break;
118 case FirewallConstants.NET_FW_IP_PROTOCOL_UDP: 139 case "17":
119 firewallException.Add(new XAttribute("Protocol", "udp")); 140 firewallException.Add(new XAttribute("Protocol", "udp"));
120 break; 141 break;
142
121 default: 143 default:
122 firewallException.Add(new XAttribute("Protocol", row[4])); 144 firewallException.Add(new XAttribute("Protocol", row.FieldAsString(4)));
123 break; 145 break;
124 } 146 }
125 } 147 }
@@ -131,26 +153,44 @@ namespace WixToolset.Firewall
131 153
132 if (!row.IsColumnEmpty(6)) 154 if (!row.IsColumnEmpty(6))
133 { 155 {
134 var attr = Convert.ToInt32(row[6]); 156 var attr = row.FieldAsInteger(6);
135 AttributeIfNotNull("IgnoreFailure", (attr & 0x1) == 0x1); 157 if ((attr & 0x1) == 0x1)
158 {
159 AttributeIfNotNull("IgnoreFailure", true);
160 }
161
162 if ((attr & 0x2) == 0x2)
163 {
164 firewallException.Add(new XAttribute("OnUpdate", "DoNothing"));
165 }
166 else if ((attr & 0x4) == 0x4)
167 {
168 firewallException.Add(new XAttribute("OnUpdate", "EnableOnly"));
169 }
136 } 170 }
137 171
138 if (!row.IsColumnEmpty(7)) 172 if (!row.IsColumnEmpty(7))
139 { 173 {
140 switch (Convert.ToInt32(row[7])) 174 switch (row.FieldAsString(7))
141 { 175 {
142 case FirewallConstants.NET_FW_PROFILE2_DOMAIN: 176 case FirewallConstants.IntegerNotSetString:
177 break;
178 case "1":
143 firewallException.Add(new XAttribute("Profile", "domain")); 179 firewallException.Add(new XAttribute("Profile", "domain"));
144 break; 180 break;
145 case FirewallConstants.NET_FW_PROFILE2_PRIVATE: 181 case "2":
146 firewallException.Add(new XAttribute("Profile", "private")); 182 firewallException.Add(new XAttribute("Profile", "private"));
147 break; 183 break;
148 case FirewallConstants.NET_FW_PROFILE2_PUBLIC: 184 case "4":
149 firewallException.Add(new XAttribute("Profile", "public")); 185 firewallException.Add(new XAttribute("Profile", "public"));
150 break; 186 break;
151 case FirewallConstants.NET_FW_PROFILE2_ALL: 187 case "2147483647":
152 firewallException.Add(new XAttribute("Profile", "all")); 188 firewallException.Add(new XAttribute("Profile", "all"));
153 break; 189 break;
190
191 default:
192 firewallException.Add(new XAttribute("Profile", row.FieldAsString(7)));
193 break;
154 } 194 }
155 } 195 }
156 196
@@ -164,8 +204,6 @@ namespace WixToolset.Firewall
164 switch (Convert.ToInt32(row[10])) 204 switch (Convert.ToInt32(row[10]))
165 { 205 {
166 case FirewallConstants.NET_FW_RULE_DIR_IN: 206 case FirewallConstants.NET_FW_RULE_DIR_IN:
167
168 firewallException.Add(AttributeIfNotNull("Outbound", false));
169 break; 207 break;
170 case FirewallConstants.NET_FW_RULE_DIR_OUT: 208 case FirewallConstants.NET_FW_RULE_DIR_OUT:
171 firewallException.Add(AttributeIfNotNull("Outbound", true)); 209 firewallException.Add(AttributeIfNotNull("Outbound", true));
@@ -173,6 +211,224 @@ namespace WixToolset.Firewall
173 } 211 }
174 } 212 }
175 213
214 // Introduced in 5.0.0
215 if (row.Fields.Length > 11)
216 {
217 if (!row.IsColumnEmpty(11))
218 {
219 var action = row.FieldAsString(11);
220 switch (action)
221 {
222 case FirewallConstants.IntegerNotSetString:
223 break;
224 case "1":
225 firewallException.Add(new XAttribute("Action", "Allow"));
226 break;
227 case "0":
228 firewallException.Add(new XAttribute("Action", "Block"));
229 break;
230 default:
231 firewallException.Add(new XAttribute("Action", action));
232 break;
233 }
234 }
235
236 if (!row.IsColumnEmpty(12))
237 {
238 var edgeTraversal = row.FieldAsString(12);
239 switch (edgeTraversal)
240 {
241 case FirewallConstants.IntegerNotSetString:
242 break;
243 case "0":
244 firewallException.Add(new XAttribute("EdgeTraversal", "Deny"));
245 break;
246 case "1":
247 firewallException.Add(new XAttribute("EdgeTraversal", "Allow"));
248 break;
249 case "2":
250 firewallException.Add(new XAttribute("EdgeTraversal", "DeferToApp"));
251 break;
252 case "3":
253 firewallException.Add(new XAttribute("EdgeTraversal", "DeferToUser"));
254 break;
255 default:
256 firewallException.Add(new XAttribute("EdgeTraversal", edgeTraversal));
257 break;
258 }
259 }
260
261 if (!row.IsColumnEmpty(13))
262 {
263 var enabled = row.FieldAsString(13);
264 switch (enabled)
265 {
266 case FirewallConstants.IntegerNotSetString:
267 break;
268 case "1":
269 firewallException.Add(new XAttribute("Enabled", "yes"));
270 break;
271 case "0":
272 firewallException.Add(new XAttribute("Enabled", "no"));
273 break;
274 default:
275 firewallException.Add(new XAttribute("Enabled", enabled));
276 break;
277 }
278 }
279
280 if (!row.IsColumnEmpty(14))
281 {
282 firewallException.Add(new XAttribute("Grouping", row.FieldAsString(14)));
283 }
284
285 if (!row.IsColumnEmpty(15))
286 {
287 firewallException.Add(new XAttribute("IcmpTypesAndCodes", row.FieldAsString(15)));
288 }
289
290 if (!row.IsColumnEmpty(16))
291 {
292 string[] interfaces = row.FieldAsString(16).Split(new[] { FirewallConstants.FORBIDDEN_FIREWALL_CHAR }, StringSplitOptions.RemoveEmptyEntries);
293 if (interfaces.Length == 1)
294 {
295 firewallException.Add(new XAttribute("Interface", interfaces[0]));
296 }
297 else
298 {
299 foreach (var interfaceItem in interfaces)
300 {
301 FirewallDecompiler.AddInterface(firewallException, interfaceItem);
302 }
303 }
304 }
305
306 if (!row.IsColumnEmpty(17))
307 {
308 string[] interfaceTypes = row.FieldAsString(17).Split(',');
309 if (interfaceTypes.Length == 1)
310 {
311 firewallException.Add(new XAttribute("InterfaceType", interfaceTypes[0]));
312 }
313 else
314 {
315 foreach (var interfaceType in interfaceTypes)
316 {
317 FirewallDecompiler.AddInterfaceType(firewallException, interfaceType);
318 }
319 }
320 }
321
322 if (!row.IsColumnEmpty(18))
323 {
324 string[] addresses = row.FieldAsString(18).Split(',');
325 if (addresses.Length == 1)
326 {
327 switch (addresses[0])
328 {
329 case "*":
330 firewallException.Add(new XAttribute("LocalScope", "any"));
331 break;
332 case "LocalSubnet":
333 firewallException.Add(new XAttribute("LocalScope", "localSubnet"));
334 break;
335 case "dns":
336 firewallException.Add(new XAttribute("LocalScope", "DNS"));
337 break;
338 case "dhcp":
339 firewallException.Add(new XAttribute("LocalScope", "DHCP"));
340 break;
341 case "wins":
342 firewallException.Add(new XAttribute("LocalScope", "WINS"));
343 break;
344 case "DefaultGateway":
345 firewallException.Add(new XAttribute("LocalScope", "defaultGateway"));
346 break;
347 default:
348 if (this.ParseHelper.ContainsProperty(addresses[0]))
349 {
350 firewallException.Add(new XAttribute("LocalScope", addresses[0]));
351 }
352 else
353 {
354 FirewallDecompiler.AddLocalAddress(firewallException, addresses[0]);
355 }
356 break;
357 }
358 }
359 else
360 {
361 foreach (var address in addresses)
362 {
363 FirewallDecompiler.AddLocalAddress(firewallException, address);
364 }
365 }
366 }
367
368 if (!row.IsColumnEmpty(19))
369 {
370 firewallException.Add(new XAttribute("RemotePort", row.FieldAsString(19)));
371 }
372
373 if (!row.IsColumnEmpty(20))
374 {
375 firewallException.Add(new XAttribute("Service", row.FieldAsString(20)));
376 }
377
378 if (!row.IsColumnEmpty(21))
379 {
380 firewallException.Add(new XAttribute("LocalAppPackageId", row.FieldAsString(21)));
381 }
382
383 if (!row.IsColumnEmpty(22))
384 {
385 firewallException.Add(new XAttribute("LocalUserAuthorizedList", row.FieldAsString(22)));
386 }
387
388 if (!row.IsColumnEmpty(23))
389 {
390 firewallException.Add(new XAttribute("LocalUserOwner", row.FieldAsString(23)));
391 }
392
393 if (!row.IsColumnEmpty(24))
394 {
395 firewallException.Add(new XAttribute("RemoteMachineAuthorizedList", row.FieldAsString(24)));
396 }
397
398 if (!row.IsColumnEmpty(25))
399 {
400 firewallException.Add(new XAttribute("RemoteUserAuthorizedList", row.FieldAsString(25)));
401 }
402
403 if (!row.IsColumnEmpty(26))
404 {
405 var secureFlags = row.FieldAsString(26);
406 switch (secureFlags)
407 {
408 case FirewallConstants.IntegerNotSetString:
409 break;
410 case "0":
411 firewallException.Add(new XAttribute("IPSecSecureFlags", "None"));
412 break;
413 case "1":
414 firewallException.Add(new XAttribute("IPSecSecureFlags", "NoEncapsulation"));
415 break;
416 case "2":
417 firewallException.Add(new XAttribute("IPSecSecureFlags", "WithIntegrity"));
418 break;
419 case "3":
420 firewallException.Add(new XAttribute("IPSecSecureFlags", "NegotiateEncryption"));
421 break;
422 case "4":
423 firewallException.Add(new XAttribute("IPSecSecureFlags", "Encrypt"));
424 break;
425 default:
426 firewallException.Add(new XAttribute("IPSecSecureFlags", secureFlags));
427 break;
428 }
429 }
430 }
431
176 this.DecompilerHelper.IndexElement(row, firewallException); 432 this.DecompilerHelper.IndexElement(row, firewallException);
177 } 433 }
178 } 434 }
@@ -183,7 +439,34 @@ namespace WixToolset.Firewall
183 new XAttribute("Value", address) 439 new XAttribute("Value", address)
184 ); 440 );
185 441
186 firewallException.AddAfterSelf(remoteAddress); 442 firewallException.Add(remoteAddress);
443 }
444
445 private static void AddInterfaceType(XElement firewallException, string type)
446 {
447 var interfaceType = new XElement(FirewallConstants.InterfaceTypeName,
448 new XAttribute("Value", type)
449 );
450
451 firewallException.Add(interfaceType);
452 }
453
454 private static void AddLocalAddress(XElement firewallException, string address)
455 {
456 var localAddress = new XElement(FirewallConstants.LocalAddressName,
457 new XAttribute("Value", address)
458 );
459
460 firewallException.Add(localAddress);
461 }
462
463 private static void AddInterface(XElement firewallException, string value)
464 {
465 var interfaceName = new XElement(FirewallConstants.InterfaceName,
466 new XAttribute("Name", value)
467 );
468
469 firewallException.Add(interfaceName);
187 } 470 }
188 471
189 private static XAttribute AttributeIfNotNull(string name, bool value) 472 private static XAttribute AttributeIfNotNull(string name, bool value)
diff --git a/src/ext/Firewall/wixext/FirewallErrors.cs b/src/ext/Firewall/wixext/FirewallErrors.cs
index b2dac782..523398e5 100644
--- a/src/ext/Firewall/wixext/FirewallErrors.cs
+++ b/src/ext/Firewall/wixext/FirewallErrors.cs
@@ -12,11 +12,6 @@ namespace WixToolset.Firewall
12 return Message(sourceLineNumbers, Ids.IllegalRemoteAddressWithScopeAttribute, "The RemoteAddress element cannot be specified because its parent FirewallException already specified the Scope attribute. To use RemoteAddress elements, omit the Scope attribute."); 12 return Message(sourceLineNumbers, Ids.IllegalRemoteAddressWithScopeAttribute, "The RemoteAddress element cannot be specified because its parent FirewallException already specified the Scope attribute. To use RemoteAddress elements, omit the Scope attribute.");
13 } 13 }
14 14
15 public static Message NoExceptionSpecified(SourceLineNumber sourceLineNumbers)
16 {
17 return Message(sourceLineNumbers, Ids.NoExceptionSpecified, "The FirewallException element doesn't identify the target of the firewall exception. To create an application exception, nest the FirewallException element under a File element or provide a value for the File or Program attributes. To create a port exception, provide a value for the Port attribute.");
18 }
19
20 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) 15 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
21 { 16 {
22 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args); 17 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
@@ -27,10 +22,32 @@ namespace WixToolset.Firewall
27 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args); 22 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args);
28 } 23 }
29 24
25 public static Message IllegalInterfaceWithInterfaceAttribute(SourceLineNumber sourceLineNumbers)
26 {
27 return Message(sourceLineNumbers, Ids.IllegalInterfaceWithInterfaceAttribute, "The Interface element cannot be specified because its parent FirewallException already specified the Interface attribute. To use Interface elements, omit the Interface attribute.");
28 }
29
30 public static Message IllegalInterfaceTypeWithInterfaceTypeAttribute(SourceLineNumber sourceLineNumbers)
31 {
32 return Message(sourceLineNumbers, Ids.IllegalInterfaceTypeWithInterfaceTypeAttribute, "The InterfaceType element cannot be specified because its parent FirewallException already specified the InterfaceType attribute. To use InterfaceType elements, omit the InterfaceType attribute.");
33 }
34
35 public static Message IllegalInterfaceTypeWithInterfaceTypeAll(SourceLineNumber sourceLineNumbers)
36 {
37 return Message(sourceLineNumbers, Ids.IllegalInterfaceTypeWithInterfaceTypeAll, "The InterfaceType element cannot be specified because its parent FirewallException contains another InterfaceType element with value 'All'.");
38 }
39 public static Message IllegalLocalAddressWithLocalScopeAttribute(SourceLineNumber sourceLineNumbers)
40 {
41 return Message(sourceLineNumbers, Ids.IllegalLocalAddressWithLocalScopeAttribute, "The LocalAddress element cannot be specified because its parent FirewallException already specified the LocalScope attribute. To use LocalAddress elements, omit the LocalScope attribute.");
42 }
43
30 public enum Ids 44 public enum Ids
31 { 45 {
32 IllegalRemoteAddressWithScopeAttribute = 6401, 46 IllegalRemoteAddressWithScopeAttribute = 6401,
33 NoExceptionSpecified = 6403, 47 IllegalInterfaceWithInterfaceAttribute = 6402,
48 IllegalInterfaceTypeWithInterfaceTypeAttribute = 6404,
49 IllegalInterfaceTypeWithInterfaceTypeAll = 6405,
50 IllegalLocalAddressWithLocalScopeAttribute = 6406,
34 } 51 }
35 } 52 }
36} 53}
diff --git a/src/ext/Firewall/wixext/FirewallTableDefinitions.cs b/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
index 26dedbf1..7a35bb59 100644
--- a/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
+++ b/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
@@ -13,15 +13,31 @@ namespace WixToolset.Firewall
13 { 13 {
14 new ColumnDefinition("Wix5FirewallException", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The primary key, a non-localized token.", modularizeType: ColumnModularizeType.Column), 14 new ColumnDefinition("Wix5FirewallException", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The primary key, a non-localized token.", modularizeType: ColumnModularizeType.Column),
15 new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Localizable display name.", modularizeType: ColumnModularizeType.Property), 15 new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Localizable display name.", modularizeType: ColumnModularizeType.Property),
16 new ColumnDefinition("RemoteAddresses", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Remote address to accept incoming connections from.", modularizeType: ColumnModularizeType.Property), 16 new ColumnDefinition("RemoteAddresses", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Remote address to accept incoming connections from.", modularizeType: ColumnModularizeType.Property),
17 new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 1, description: "Port number.", modularizeType: ColumnModularizeType.Property), 17 new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 1, maxValue: 65535, description: "Local Port number.", modularizeType: ColumnModularizeType.Property),
18 new ColumnDefinition("Protocol", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 0, maxValue: 255, description: "Protocol (6=TCP; 17=UDP). https://www.iana.org/assignments/protocol-numbers"), 18 new ColumnDefinition("Protocol", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 0, maxValue: 255, description: "Protocol (6=TCP; 17=UDP). https://www.iana.org/assignments/protocol-numbers", modularizeType: ColumnModularizeType.Property),
19 new ColumnDefinition("Program", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Exception for a program (formatted path name).", modularizeType: ColumnModularizeType.Property), 19 new ColumnDefinition("Program", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Exception for a program (formatted path name).", modularizeType: ColumnModularizeType.Property),
20 new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Vital=1"), 20 new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Vital=1; IgnoreUpdates=2; EnableOnChange=4; INetFwRule2=8; INetFwRule3=16"),
21 new ColumnDefinition("Profile", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Integer, minValue: 1, maxValue: 2147483647, description: "Profile (1=domain; 2=private; 4=public; 2147483647=all)."), 21 new ColumnDefinition("Profile", ColumnType.String, 4, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 1, maxValue: 2147483647, description: "Profile (1=domain; 2=private; 4=public; 2147483647=all).", modularizeType: ColumnModularizeType.Property),
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 component that controls the firewall configuration.", 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 component that controls the firewall configuration.", modularizeType: ColumnModularizeType.Column),
23 new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in Windows Firewall manager for this firewall rule."), 23 new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in Windows Firewall manager for this firewall rule."),
24 new ColumnDefinition("Direction", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 1, maxValue: 2, description: "Direction (1=in; 2=out)"), 24 new ColumnDefinition("Direction", ColumnType.Number, 1, primaryKey: false, nullable: false, ColumnCategory.Integer, minValue: 1, maxValue: 2, description: "Direction (1=in; 2=out)"),
25 new ColumnDefinition("Action", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 0, maxValue: 1, description: "Action (0=Block; 1=Allow).", modularizeType: ColumnModularizeType.Property),
26 new ColumnDefinition("EdgeTraversal", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 0, maxValue: 3, description: "Edge traversal (0=Deny; 1=Allow; 2=DeferToApp; 3=DeferToUser).", modularizeType: ColumnModularizeType.Property),
27 new ColumnDefinition("Enabled", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 0, maxValue: 1, description: "Enabled (0=Disabled; 1=Enabled).", modularizeType: ColumnModularizeType.Property),
28 new ColumnDefinition("Grouping", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "The group to which the rule belongs.", modularizeType: ColumnModularizeType.Property),
29 new ColumnDefinition("IcmpTypesAndCodes", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Comma separated list of ICMP types and codes separated by colons.", modularizeType: ColumnModularizeType.Property),
30 new ColumnDefinition("Interfaces", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "A list of network interfaces separated by a pipe character.", modularizeType: ColumnModularizeType.Property),
31 new ColumnDefinition("InterfaceTypes", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Comma separated list of interface types (combination of Wireless,Lan,RemoteAccess or All).", modularizeType: ColumnModularizeType.Property),
32 new ColumnDefinition("LocalAddresses", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Local address to accept incoming connections on.", modularizeType: ColumnModularizeType.Property),
33 new ColumnDefinition("RemotePort", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 1, maxValue: 65535, description: "Remote Port number.", modularizeType: ColumnModularizeType.Property),
34 new ColumnDefinition("ServiceName", ColumnType.String, 256, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Windows Service short name.", modularizeType: ColumnModularizeType.Property),
35 new ColumnDefinition("LocalAppPackageId", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Package identifier or the app container identifier of a process.", modularizeType: ColumnModularizeType.Property),
36 new ColumnDefinition("LocalUserAuthorizedList", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "List of authorized local users for an app container.", modularizeType: ColumnModularizeType.Property),
37 new ColumnDefinition("LocalUserOwner", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "SID of the user who is the owner of the rule.", modularizeType: ColumnModularizeType.Property),
38 new ColumnDefinition("RemoteMachineAuthorizedList", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "List of remote computers which are authorized to access an app container.", modularizeType: ColumnModularizeType.Property),
39 new ColumnDefinition("RemoteUserAuthorizedList", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "List of remote users who are authorized to access an app container.", modularizeType: ColumnModularizeType.Property),
40 new ColumnDefinition("SecureFlags", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 0, maxValue: 1, description: "NET_FW_AUTHENTICATE_TYPE IPsec verification level.", modularizeType: ColumnModularizeType.Property),
25 }, 41 },
26 symbolIdIsPrimaryKey: true 42 symbolIdIsPrimaryKey: true
27 ); 43 );
diff --git a/src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs b/src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs
index 620de969..d6a54255 100644
--- a/src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs
+++ b/src/ext/Firewall/wixext/Symbols/WixFirewallExceptionSymbol.cs
@@ -14,13 +14,29 @@ namespace WixToolset.Firewall
14 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Name), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Name), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.RemoteAddresses), IntermediateFieldType.String), 15 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.RemoteAddresses), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Port), IntermediateFieldType.String), 16 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Port), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Protocol), IntermediateFieldType.Number), 17 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Protocol), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Program), IntermediateFieldType.String), 18 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Program), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Attributes), IntermediateFieldType.Number), 19 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Attributes), IntermediateFieldType.Number),
20 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Profile), IntermediateFieldType.Number), 20 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Profile), IntermediateFieldType.String),
21 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.ComponentRef), IntermediateFieldType.String), 21 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.ComponentRef), IntermediateFieldType.String),
22 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Description), IntermediateFieldType.String), 22 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Description), IntermediateFieldType.String),
23 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Direction), IntermediateFieldType.Number), 23 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Direction), IntermediateFieldType.Number),
24 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Action), IntermediateFieldType.String),
25 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.EdgeTraversal), IntermediateFieldType.String),
26 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Enabled), IntermediateFieldType.String),
27 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Grouping), IntermediateFieldType.String),
28 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.IcmpTypesAndCodes), IntermediateFieldType.String),
29 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.Interfaces), IntermediateFieldType.String),
30 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.InterfaceTypes), IntermediateFieldType.String),
31 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.LocalAddresses), IntermediateFieldType.String),
32 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.RemotePort), IntermediateFieldType.String),
33 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.ServiceName), IntermediateFieldType.String),
34 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.LocalAppPackageId), IntermediateFieldType.String),
35 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.LocalUserAuthorizedList), IntermediateFieldType.String),
36 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.LocalUserOwner), IntermediateFieldType.String),
37 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.RemoteMachineAuthorizedList), IntermediateFieldType.String),
38 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.RemoteUserAuthorizedList), IntermediateFieldType.String),
39 new IntermediateFieldDefinition(nameof(WixFirewallExceptionSymbolFields.SecureFlags), IntermediateFieldType.String),
24 }, 40 },
25 typeof(WixFirewallExceptionSymbol)); 41 typeof(WixFirewallExceptionSymbol));
26 } 42 }
@@ -42,6 +58,22 @@ namespace WixToolset.Firewall.Symbols
42 ComponentRef, 58 ComponentRef,
43 Description, 59 Description,
44 Direction, 60 Direction,
61 Action,
62 EdgeTraversal,
63 Enabled,
64 Grouping,
65 IcmpTypesAndCodes,
66 Interfaces,
67 InterfaceTypes,
68 LocalAddresses,
69 RemotePort,
70 ServiceName,
71 LocalAppPackageId,
72 LocalUserAuthorizedList,
73 LocalUserOwner,
74 RemoteMachineAuthorizedList,
75 RemoteUserAuthorizedList,
76 SecureFlags,
45 } 77 }
46 78
47 public class WixFirewallExceptionSymbol : IntermediateSymbol 79 public class WixFirewallExceptionSymbol : IntermediateSymbol
@@ -74,9 +106,9 @@ namespace WixToolset.Firewall.Symbols
74 set => this.Set((int)WixFirewallExceptionSymbolFields.Port, value); 106 set => this.Set((int)WixFirewallExceptionSymbolFields.Port, value);
75 } 107 }
76 108
77 public int? Protocol 109 public string Protocol
78 { 110 {
79 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Protocol].AsNullableNumber(); 111 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Protocol].AsString();
80 set => this.Set((int)WixFirewallExceptionSymbolFields.Protocol, value); 112 set => this.Set((int)WixFirewallExceptionSymbolFields.Protocol, value);
81 } 113 }
82 114
@@ -92,9 +124,9 @@ namespace WixToolset.Firewall.Symbols
92 set => this.Set((int)WixFirewallExceptionSymbolFields.Attributes, value); 124 set => this.Set((int)WixFirewallExceptionSymbolFields.Attributes, value);
93 } 125 }
94 126
95 public int Profile 127 public string Profile
96 { 128 {
97 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Profile].AsNumber(); 129 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Profile].AsString();
98 set => this.Set((int)WixFirewallExceptionSymbolFields.Profile, value); 130 set => this.Set((int)WixFirewallExceptionSymbolFields.Profile, value);
99 } 131 }
100 132
@@ -115,5 +147,101 @@ namespace WixToolset.Firewall.Symbols
115 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Direction].AsNumber(); 147 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Direction].AsNumber();
116 set => this.Set((int)WixFirewallExceptionSymbolFields.Direction, value); 148 set => this.Set((int)WixFirewallExceptionSymbolFields.Direction, value);
117 } 149 }
150
151 public string Action
152 {
153 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Action].AsString();
154 set => this.Set((int)WixFirewallExceptionSymbolFields.Action, value);
155 }
156
157 public string EdgeTraversal
158 {
159 get => this.Fields[(int)WixFirewallExceptionSymbolFields.EdgeTraversal].AsString();
160 set => this.Set((int)WixFirewallExceptionSymbolFields.EdgeTraversal, value);
161 }
162
163 public string Enabled
164 {
165 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Enabled].AsString();
166 set => this.Set((int)WixFirewallExceptionSymbolFields.Enabled, value);
167 }
168
169 public string Grouping
170 {
171 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Grouping].AsString();
172 set => this.Set((int)WixFirewallExceptionSymbolFields.Grouping, value);
173 }
174
175 public string IcmpTypesAndCodes
176 {
177 get => this.Fields[(int)WixFirewallExceptionSymbolFields.IcmpTypesAndCodes].AsString();
178 set => this.Set((int)WixFirewallExceptionSymbolFields.IcmpTypesAndCodes, value);
179 }
180
181 public string Interfaces
182 {
183 get => this.Fields[(int)WixFirewallExceptionSymbolFields.Interfaces].AsString();
184 set => this.Set((int)WixFirewallExceptionSymbolFields.Interfaces, value);
185 }
186
187 public string InterfaceTypes
188 {
189 get => this.Fields[(int)WixFirewallExceptionSymbolFields.InterfaceTypes].AsString();
190 set => this.Set((int)WixFirewallExceptionSymbolFields.InterfaceTypes, value);
191 }
192
193 public string LocalAddresses
194 {
195 get => this.Fields[(int)WixFirewallExceptionSymbolFields.LocalAddresses].AsString();
196 set => this.Set((int)WixFirewallExceptionSymbolFields.LocalAddresses, value);
197 }
198
199 public string RemotePort
200 {
201 get => this.Fields[(int)WixFirewallExceptionSymbolFields.RemotePort].AsString();
202 set => this.Set((int)WixFirewallExceptionSymbolFields.RemotePort, value);
203 }
204
205 public string ServiceName
206 {
207 get => this.Fields[(int)WixFirewallExceptionSymbolFields.ServiceName].AsString();
208 set => this.Set((int)WixFirewallExceptionSymbolFields.ServiceName, value);
209 }
210
211 public string LocalAppPackageId
212 {
213 get => this.Fields[(int)WixFirewallExceptionSymbolFields.LocalAppPackageId].AsString();
214 set => this.Set((int)WixFirewallExceptionSymbolFields.LocalAppPackageId, value);
215 }
216
217 public string LocalUserAuthorizedList
218 {
219 get => this.Fields[(int)WixFirewallExceptionSymbolFields.LocalUserAuthorizedList].AsString();
220 set => this.Set((int)WixFirewallExceptionSymbolFields.LocalUserAuthorizedList, value);
221 }
222
223 public string LocalUserOwner
224 {
225 get => this.Fields[(int)WixFirewallExceptionSymbolFields.LocalUserOwner].AsString();
226 set => this.Set((int)WixFirewallExceptionSymbolFields.LocalUserOwner, value);
227 }
228
229 public string RemoteMachineAuthorizedList
230 {
231 get => this.Fields[(int)WixFirewallExceptionSymbolFields.RemoteMachineAuthorizedList].AsString();
232 set => this.Set((int)WixFirewallExceptionSymbolFields.RemoteMachineAuthorizedList, value);
233 }
234
235 public string RemoteUserAuthorizedList
236 {
237 get => this.Fields[(int)WixFirewallExceptionSymbolFields.RemoteUserAuthorizedList].AsString();
238 set => this.Set((int)WixFirewallExceptionSymbolFields.RemoteUserAuthorizedList, value);
239 }
240
241 public string SecureFlags
242 {
243 get => this.Fields[(int)WixFirewallExceptionSymbolFields.SecureFlags].AsString();
244 set => this.Set((int)WixFirewallExceptionSymbolFields.SecureFlags, value);
245 }
118 } 246 }
119} \ No newline at end of file 247}
diff --git a/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj b/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj
index 8d1dc77e..098b121c 100644
--- a/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj
+++ b/src/ext/Firewall/wixext/WixToolset.Firewall.wixext.csproj
@@ -5,9 +5,11 @@
5 <PropertyGroup> 5 <PropertyGroup>
6 <TargetFramework>netstandard2.0</TargetFramework> 6 <TargetFramework>netstandard2.0</TargetFramework>
7 <RootNamespace>WixToolset.Firewall</RootNamespace> 7 <RootNamespace>WixToolset.Firewall</RootNamespace>
8 <Description>WiX Toolset Firewallity Extension</Description> 8 <Description>WiX Toolset Firewall Extension</Description>
9 <Title>WiX Toolset Firewall Extension</Title> 9 <Title>WiX Toolset Firewall Extension</Title>
10 <DebugType>embedded</DebugType> 10 <DebugType>embedded</DebugType>
11 <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
12 <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
11 </PropertyGroup> 13 </PropertyGroup>
12 14
13 <Import Project="..\..\WixExt.props" /> 15 <Import Project="..\..\WixExt.props" />