use WcaGetRecordFormattedString to get firewall rule description
chris_bednarski committed
Aug 20, 2023 at 19:49 UTC
537e79d3c8b99e1576db48b19c8071c0922342f2
7 files changed
+153
-4
src/ext/Firewall/ca/firewall.cpp
+1
-1
@@ -79,7 +79,7 @@ static UINT SchedFirewallExceptions(
79
hr = WcaGetRecordString(hRec, feqComponent, &pwzComponent);
80
ExitOnFailure(hr, "Failed to get firewall exception component.");
81
82
- hr = WcaGetRecordString(hRec, feqDescription, &pwzDescription);
82
+ hr = WcaGetRecordFormattedString(hRec, feqDescription, &pwzDescription);
83
ExitOnFailure(hr, "Failed to get firewall exception description.");
84
85
hr = WcaGetRecordInteger(hRec, feqDirection, &iDirection);
src/test/burn/WixTestTools/Firewall/RuleDetails.cs
+2
-2
@@ -164,7 +164,7 @@ namespace WixTestTools.Firewall
164
public bool? Enabled { get; set; }
165
166
/// <summary>
167
- /// This property is optional. It specifies the group to which an individual rule belongs and groups multiple rules into a single line in the Windows Firewall control panel<br/>
167
+ /// This property is optional. It specifies the group to which an individual rule belongs and groups multiple rules into a single line in the Windows Firewall control panel.<br/>
168
/// This allows the users to enable or disable multiple rules with a single click.<br/>
169
/// The Grouping property can also be specified using indirect strings.<br/>
170
/// Example: "Simple Group Name"<br/>
@@ -193,7 +193,7 @@ namespace WixTestTools.Firewall
193
194
/// <summary>
195
/// This property is optional. The NET_FW_ACTION enumerated type specifies the action for this rule.<br/>
196
- /// NET_FW_ACTION_ALLOW is the default value. Profiles can be combined from the following values:<br/>
196
+ /// NET_FW_ACTION_ALLOW is the default value. The Action must be specified from the following list of values:<br/>
197
/// <b>o</b> NET_FW_ACTION_BLOCK = 0x0<br/>
198
/// <b>o</b> NET_FW_ACTION_ALLOW = 0x1<br/>
199
/// </summary>
src/test/burn/WixTestTools/Firewall/UniqueCheck.cs
+8
-1
@@ -6,7 +6,7 @@ namespace WixTestTools.Firewall
6
7
/// <summary>
8
/// A lot of firewall rules don't follow the Microsoft recommendation of using unique names.<br/>
9
- /// This class helps to disambiguate the rules based on Name, Direction, Profile, Protocol, ApplicationName and the LocalUserOwner.
9
+ /// This class helps to disambiguate the rules based on Name, Direction, Profile, Protocol, ApplicationName, LocalUserOwner and RemoteAddresses.
10
/// </summary>
11
public class UniqueCheck
12
{
@@ -22,6 +22,7 @@ namespace WixTestTools.Firewall
22
this.Protocol = details.Protocol;
23
this.ApplicationName = details.ApplicationName;
24
this.LocalUserOwner = details.LocalUserOwner;
25
+ this.RemoteAddresses = details.RemoteAddresses;
26
}
27
28
@@ -37,6 +38,7 @@ namespace WixTestTools.Firewall
38
39
public string LocalUserOwner { get; set; }
40
41
+ public string RemoteAddresses { get; set; }
42
43
public bool FirewallRuleIsUnique(INetFwRule3 rule)
44
{
@@ -70,6 +72,11 @@ namespace WixTestTools.Firewall
72
return false;
73
}
74
75
+ if (this.RemoteAddresses != null && rule.RemoteAddresses != this.RemoteAddresses)
76
+ {
77
+ return false;
78
+ }
79
+
80
return true;
81
}
82
}
src/test/burn/WixTestTools/Firewall/Verifier.cs
+2
@@ -281,7 +281,9 @@ namespace WixTestTools.Firewall
281
Assert.True(expected.ServiceName == actual.ServiceName, FormatErrorMessage(name, "ServiceNames", expected.ServiceName, actual.ServiceName, unique));
282
Assert.True(expected.Protocol == actual.Protocol, FormatErrorMessage(name, "Protocols", expected.Protocol, actual.Protocol, unique));
283
Assert.True(expected.LocalPorts == actual.LocalPorts, FormatErrorMessage(name, "LocalPorts", expected.LocalPorts, actual.LocalPorts, unique));
284
+ Assert.True(expected.LocalAddresses == actual.LocalAddresses, FormatErrorMessage(name, "LocalAddresses", expected.LocalAddresses, actual.LocalAddresses, unique));
285
Assert.True(expected.RemotePorts == actual.RemotePorts, FormatErrorMessage(name, "RemotePorts", expected.RemotePorts, actual.RemotePorts, unique));
286
+ Assert.True(expected.RemoteAddresses == actual.RemoteAddresses, FormatErrorMessage(name, "RemoteAddresses", expected.RemoteAddresses, actual.RemoteAddresses, unique));
287
Assert.True(expected.IcmpTypesAndCodes == actual.IcmpTypesAndCodes, FormatErrorMessage(name, "IcmpTypesAndCodes", expected.IcmpTypesAndCodes, actual.Description, unique));
288
Assert.True(expected.Direction == actual.Direction, FormatErrorMessage(name, "Directions", expected.Direction, actual.Direction, unique));
289
Assert.Equal<object>(expected.Interfaces, actual.Interfaces);
src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/DynamicFirewallRules.wixproj
new
+13
@@ -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
+<Project Sdk="WixToolset.Sdk">
3
+ <PropertyGroup>
4
+ <UpgradeCode>{C587F355-26FF-4D17-801F-50505C348D99}</UpgradeCode>
5
+ <ProductComponentsRef>true</ProductComponentsRef>
6
+ </PropertyGroup>
7
+ <ItemGroup>
8
+ <Compile Include="..\..\Templates\Product.wxs" Link="Product.wxs" />
9
+ </ItemGroup>
10
+ <ItemGroup>
11
+ <PackageReference Include="WixToolset.Firewall.wixext" />
12
+ </ItemGroup>
13
+</Project>
\ No newline at end of file
src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/product.wxs
new
+50
@@ -0,0 +1,50 @@
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
+
3
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall">
4
+ <Fragment>
5
+ <ComponentGroup Id="ProductComponents">
6
+ <ComponentRef Id="FirewallComponent2"/>
7
+ </ComponentGroup>
8
+
9
+ <Property Id="PORTNUMBER" Secure="yes">
10
+ <RegistrySearch Id="FindPortNumber" Root="HKLM" Key="SOFTWARE\WiX\Tests\$(var.TestGroupName)" Name="PortNumber" Type="raw" />
11
+ </Property>
12
+
13
+ <CustomAction Id="SavePortNumberCmdLineValue" Property="CMDLINE_PORTNUMBER" Value="[PORTNUMBER]" Execute="firstSequence" />
14
+ <CustomAction Id="SetPortNumberFromCmdLineValue" Property="PORTNUMBER" Value="[CMDLINE_PORTNUMBER]" Execute="firstSequence" />
15
+ <CustomAction Id="SetPortNumberDefaultValue" Property="PORTNUMBER" Value="9999" Execute="firstSequence" />
16
+
17
+ <InstallExecuteSequence>
18
+ <Custom Action="SavePortNumberCmdLineValue" Before="AppSearch" />
19
+ <Custom Action="SetPortNumberFromCmdLineValue" After="AppSearch" Condition="CMDLINE_PORTNUMBER" />
20
+ <Custom Action="SetPortNumberDefaultValue" After="SetPortNumberFromCmdLineValue" Condition="NOT PORTNUMBER" />
21
+ </InstallExecuteSequence>
22
+ </Fragment>
23
+
24
+ <Fragment>
25
+ <Component Id="FirewallComponent2" Guid="528C212C-09C6-47FC-A466-A3799DD04D25" Directory="INSTALLFOLDER" >
26
+ <RegistryValue Root="HKLM" Key="SOFTWARE\WiX\Tests\$(var.TestGroupName)" Name="PortNumber" Value="[PORTNUMBER]" Type="string" />
27
+
28
+ <File Source="$(sys.SOURCEFILEPATH)" KeyPath="yes" >
29
+ <fw:FirewallException Id="FirewallException1"
30
+ Port="[PORTNUMBER]"
31
+ Description="WiX Toolset firewall exception rule integration test - dynamic app description [PORTNUMBER]"
32
+ Name="WiXToolset401 Test - 0003" Scope="localSubnet" />
33
+ </File>
34
+
35
+ <fw:FirewallException Id="FirewallException2"
36
+ Description="WiX Toolset firewall exception rule integration test - dynamic port description [PORTNUMBER]"
37
+ Name="WiXToolset401 Test - 0004" Scope="any" Port="[PORTNUMBER]" />
38
+
39
+ <fw:FirewallException Id="FirewallException3"
40
+ Description="WiX Toolset firewall exception rule integration test - dynamic Name [PORTNUMBER]"
41
+ Program="%windir%\system32\[PORTNUMBER].exe"
42
+ Port="[PORTNUMBER]"
43
+ Protocol="udp" Profile="private"
44
+ Name="WiXToolset401 Test - 0005 - [PORTNUMBER]" >
45
+ <fw:RemoteAddress Value="127.0.0.1" />
46
+ <fw:RemoteAddress Value="192.168.1.1" />
47
+ </fw:FirewallException>
48
+ </Component>
49
+ </Fragment>
50
+</Wix>
src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs
+77
@@ -200,5 +200,82 @@ namespace WixToolsetTest.MsiE2E
200
201
Verifier.VerifyFirewallRule("WiXToolset401 Test - 0001", expected);
202
}
203
+
204
+ [RuntimeFact]
205
+ public void FirewallRulesUseFormattedStringProperties()
206
+ {
207
+ var product = this.CreatePackageInstaller("DynamicFirewallRules");
208
+ product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
209
+
210
+ var expected1 = new RuleDetails("WiXToolset401 Test - 0003")
211
+ {
212
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
213
+ ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("DynamicFirewallRules", "product.wxs")),
214
+ Description = "WiX Toolset firewall exception rule integration test - dynamic app description 9999",
215
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
216
+ EdgeTraversal = true,
217
+ EdgeTraversalOptions = 1,
218
+ Enabled = true,
219
+ InterfaceTypes = "All",
220
+ LocalAddresses = "*",
221
+ Profiles = Int32.MaxValue,
222
+ Protocol = 6,
223
+ RemoteAddresses = "LocalSubnet",
224
+ SecureFlags = 0,
225
+ LocalPorts = "9999",
226
+ RemotePorts = "*",
227
+ };
228
+
229
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0003", expected1);
230
+
231
+ var expected2 = new RuleDetails("WiXToolset401 Test - 0004")
232
+ {
233
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
234
+ Description = "WiX Toolset firewall exception rule integration test - dynamic port description 9999",
235
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
236
+ EdgeTraversal = false,
237
+ EdgeTraversalOptions = 0,
238
+ Enabled = true,
239
+ InterfaceTypes = "All",
240
+ LocalAddresses = "*",
241
+ Profiles = Int32.MaxValue,
242
+ Protocol = 6,
243
+ RemoteAddresses = "*",
244
+ SecureFlags = 0,
245
+ LocalPorts = "9999",
246
+ RemotePorts = "*",
247
+ };
248
+
249
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0004", expected2);
250
+
251
+
252
+ var expected3 = new RuleDetails("WiXToolset401 Test - 0005 - 9999")
253
+ {
254
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
255
+ ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("windir"), "system32", "9999.exe"),
256
+ Description = "WiX Toolset firewall exception rule integration test - dynamic Name 9999",
257
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
258
+ EdgeTraversal = true,
259
+ EdgeTraversalOptions = 1,
260
+ Enabled = true,
261
+ InterfaceTypes = "All",
262
+ LocalAddresses = "*",
263
+ Profiles = 2,
264
+ Protocol = 17,
265
+ RemoteAddresses = "127.0.0.1/255.255.255.255,192.168.1.1/255.255.255.255",
266
+ SecureFlags = 0,
267
+ LocalPorts = "9999",
268
+ RemotePorts = "*",
269
+ };
270
+
271
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0005 - 9999", expected3);
272
+
273
+ product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
274
+
275
+ // verify the firewall exceptions have been removed.
276
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0003"));
277
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0004"));
278
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0005 - 9999"));
279
+ }
280
}
281
}