diff options
| author | chris_bednarski <Chris.Bednarski@minfos.com.au> | 2023-09-21 16:03:28 +1000 |
|---|---|---|
| committer | Bob Arnson <github@bobs.org> | 2023-11-19 12:17:13 -0500 |
| commit | dfb7512b85536b7726080648f2228cf8d0153724 (patch) | |
| tree | d053018ee47afe7e349dda6739a6580c771a1a3d /src | |
| parent | 80e604761b4f43b9b79a4878fcae360b071a7c35 (diff) | |
| download | wix-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')
35 files changed, 3356 insertions, 347 deletions
diff --git a/src/ext/Firewall/ca/firewall.cpp b/src/ext/Firewall/ca/firewall.cpp index eed6f9df..f50ae409 100644 --- a/src/ext/Firewall/ca/firewall.cpp +++ b/src/ext/Firewall/ca/firewall.cpp | |||
| @@ -3,34 +3,54 @@ | |||
| 3 | #include "precomp.h" | 3 | #include "precomp.h" |
| 4 | 4 | ||
| 5 | LPCWSTR vcsFirewallExceptionQuery = | 5 | LPCWSTR vcsFirewallExceptionQuery = |
| 6 | L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description`, `Direction` FROM `Wix5FirewallException`"; | 6 | L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description`, `Direction`, `Action`, `EdgeTraversal`, `Enabled`, `Grouping`, `IcmpTypesAndCodes`, `Interfaces`, `InterfaceTypes`, `LocalAddresses`, `RemotePort`, `ServiceName`, `LocalAppPackageId`, `LocalUserAuthorizedList`, `LocalUserOwner`, `RemoteMachineAuthorizedList`, `RemoteUserAuthorizedList`, `SecureFlags` FROM `Wix5FirewallException`"; |
| 7 | enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription, feqDirection }; | 7 | enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription, feqDirection, feqAction, feqEdgeTraversal, feqEnabled, feqGrouping, feqIcmpTypesAndCodes, feqInterfaces, feqInterfaceTypes, feqLocalAddresses, feqRemotePort, feqServiceName, feqLocalAppPackageId, feqLocalUserAuthorizedList, feqLocalUserOwner, feqRemoteMachineAuthorizedList, feqRemoteUserAuthorizedList, feqSecureFlags }; |
| 8 | enum eFirewallExceptionTarget { fetPort = 1, fetApplication, fetUnknown }; | 8 | enum eFirewallExceptionAttributes { feaIgnoreFailures = 1, feaIgnoreUpdates = 2, feaEnableOnUpdate = 4, feaAddINetFwRule2 = 8, feaAddINetFwRule3 = 16 }; |
| 9 | enum eFirewallExceptionAttributes { feaIgnoreFailures = 1 }; | ||
| 10 | 9 | ||
| 11 | struct FIREWALL_EXCEPTION_ATTRIBUTES | 10 | struct FIREWALL_EXCEPTION_ATTRIBUTES |
| 12 | { | 11 | { |
| 13 | LPWSTR pwzName; | 12 | LPWSTR pwzName; |
| 14 | |||
| 15 | LPWSTR pwzRemoteAddresses; | ||
| 16 | LPWSTR pwzPort; | ||
| 17 | int iProtocol; | ||
| 18 | LPWSTR pwzProgram; | ||
| 19 | int iAttributes; | 13 | int iAttributes; |
| 20 | int iProfile; | 14 | |
| 15 | // INetFwRule | ||
| 16 | int iAction; | ||
| 17 | LPWSTR pwzApplicationName; | ||
| 21 | LPWSTR pwzDescription; | 18 | LPWSTR pwzDescription; |
| 22 | int iDirection; | 19 | int iDirection; |
| 20 | int iEnabled; | ||
| 21 | LPWSTR pwzGrouping; | ||
| 22 | LPWSTR pwzIcmpTypesAndCodes; | ||
| 23 | LPWSTR pwzInterfaces; | ||
| 24 | LPWSTR pwzInterfaceTypes; | ||
| 25 | LPWSTR pwzLocalAddresses; | ||
| 26 | LPWSTR pwzLocalPorts; | ||
| 27 | int iProfile; | ||
| 28 | int iProtocol; | ||
| 29 | LPWSTR pwzRemoteAddresses; | ||
| 30 | LPWSTR pwzRemotePorts; | ||
| 31 | LPWSTR pwzServiceName; | ||
| 32 | |||
| 33 | // INetFwRule2 | ||
| 34 | int iEdgeTraversal; | ||
| 35 | |||
| 36 | // INetFwRule3 | ||
| 37 | LPWSTR pwzLocalAppPackageId; | ||
| 38 | LPWSTR pwzLocalUserAuthorizedList; | ||
| 39 | LPWSTR pwzLocalUserOwner; | ||
| 40 | LPWSTR pwzRemoteMachineAuthorizedList; | ||
| 41 | LPWSTR pwzRemoteUserAuthorizedList; | ||
| 42 | int iSecureFlags; | ||
| 23 | }; | 43 | }; |
| 24 | 44 | ||
| 25 | /****************************************************************** | 45 | /****************************************************************** |
| 26 | SchedFirewallExceptions - immediate custom action worker to | 46 | SchedFirewallExceptions - immediate custom action worker to |
| 27 | register and remove firewall exceptions. | 47 | register and remove firewall exceptions. |
| 28 | 48 | ||
| 29 | ********************************************************************/ | 49 | ********************************************************************/ |
| 30 | static UINT SchedFirewallExceptions( | 50 | static UINT SchedFirewallExceptions( |
| 31 | __in MSIHANDLE hInstall, | 51 | __in MSIHANDLE hInstall, |
| 32 | WCA_TODO todoSched | 52 | __in WCA_TODO todoSched |
| 33 | ) | 53 | ) |
| 34 | { | 54 | { |
| 35 | HRESULT hr = S_OK; | 55 | HRESULT hr = S_OK; |
| 36 | UINT er = ERROR_SUCCESS; | 56 | UINT er = ERROR_SUCCESS; |
| @@ -67,19 +87,19 @@ static UINT SchedFirewallExceptions( | |||
| 67 | hr = WcaGetRecordFormattedString(hRec, feqRemoteAddresses, &attrs.pwzRemoteAddresses); | 87 | hr = WcaGetRecordFormattedString(hRec, feqRemoteAddresses, &attrs.pwzRemoteAddresses); |
| 68 | ExitOnFailure(hr, "Failed to get firewall exception remote addresses."); | 88 | ExitOnFailure(hr, "Failed to get firewall exception remote addresses."); |
| 69 | 89 | ||
| 70 | hr = WcaGetRecordFormattedString(hRec, feqPort, &attrs.pwzPort); | 90 | hr = WcaGetRecordFormattedString(hRec, feqPort, &attrs.pwzLocalPorts); |
| 71 | ExitOnFailure(hr, "Failed to get firewall exception port."); | 91 | ExitOnFailure(hr, "Failed to get firewall exception port."); |
| 72 | 92 | ||
| 73 | hr = WcaGetRecordInteger(hRec, feqProtocol, &attrs.iProtocol); | 93 | hr = WcaGetRecordFormattedInteger(hRec, feqProtocol, &attrs.iProtocol); |
| 74 | ExitOnFailure(hr, "Failed to get firewall exception protocol."); | 94 | ExitOnFailure(hr, "Failed to get firewall exception protocol."); |
| 75 | 95 | ||
| 76 | hr = WcaGetRecordFormattedString(hRec, feqProgram, &attrs.pwzProgram); | 96 | hr = WcaGetRecordFormattedString(hRec, feqProgram, &attrs.pwzApplicationName); |
| 77 | ExitOnFailure(hr, "Failed to get firewall exception program."); | 97 | ExitOnFailure(hr, "Failed to get firewall exception program."); |
| 78 | 98 | ||
| 79 | hr = WcaGetRecordInteger(hRec, feqAttributes, &attrs.iAttributes); | 99 | hr = WcaGetRecordInteger(hRec, feqAttributes, &attrs.iAttributes); |
| 80 | ExitOnFailure(hr, "Failed to get firewall exception attributes."); | 100 | ExitOnFailure(hr, "Failed to get firewall exception attributes."); |
| 81 | 101 | ||
| 82 | hr = WcaGetRecordInteger(hRec, feqProfile, &attrs.iProfile); | 102 | hr = WcaGetRecordFormattedInteger(hRec, feqProfile, &attrs.iProfile); |
| 83 | ExitOnFailure(hr, "Failed to get firewall exception profile."); | 103 | ExitOnFailure(hr, "Failed to get firewall exception profile."); |
| 84 | 104 | ||
| 85 | hr = WcaGetRecordString(hRec, feqComponent, &pwzComponent); | 105 | hr = WcaGetRecordString(hRec, feqComponent, &pwzComponent); |
| @@ -91,6 +111,54 @@ static UINT SchedFirewallExceptions( | |||
| 91 | hr = WcaGetRecordInteger(hRec, feqDirection, &attrs.iDirection); | 111 | hr = WcaGetRecordInteger(hRec, feqDirection, &attrs.iDirection); |
| 92 | ExitOnFailure(hr, "Failed to get firewall exception direction."); | 112 | ExitOnFailure(hr, "Failed to get firewall exception direction."); |
| 93 | 113 | ||
| 114 | hr = WcaGetRecordFormattedInteger(hRec, feqAction, &attrs.iAction); | ||
| 115 | ExitOnFailure(hr, "Failed to get firewall exception action."); | ||
| 116 | |||
| 117 | hr = WcaGetRecordFormattedInteger(hRec, feqEdgeTraversal, &attrs.iEdgeTraversal); | ||
| 118 | ExitOnFailure(hr, "Failed to get firewall exception edge traversal."); | ||
| 119 | |||
| 120 | hr = WcaGetRecordFormattedInteger(hRec, feqEnabled, &attrs.iEnabled); | ||
| 121 | ExitOnFailure(hr, "Failed to get firewall exception enabled flag."); | ||
| 122 | |||
| 123 | hr = WcaGetRecordFormattedString(hRec, feqGrouping, &attrs.pwzGrouping); | ||
| 124 | ExitOnFailure(hr, "Failed to get firewall exception grouping."); | ||
| 125 | |||
| 126 | hr = WcaGetRecordFormattedString(hRec, feqIcmpTypesAndCodes, &attrs.pwzIcmpTypesAndCodes); | ||
| 127 | ExitOnFailure(hr, "Failed to get firewall exception ICMP types and codes."); | ||
| 128 | |||
| 129 | hr = WcaGetRecordFormattedString(hRec, feqInterfaces, &attrs.pwzInterfaces); | ||
| 130 | ExitOnFailure(hr, "Failed to get firewall exception interfaces."); | ||
| 131 | |||
| 132 | hr = WcaGetRecordFormattedString(hRec, feqInterfaceTypes, &attrs.pwzInterfaceTypes); | ||
| 133 | ExitOnFailure(hr, "Failed to get firewall exception interface types."); | ||
| 134 | |||
| 135 | hr = WcaGetRecordFormattedString(hRec, feqLocalAddresses, &attrs.pwzLocalAddresses); | ||
| 136 | ExitOnFailure(hr, "Failed to get firewall exception local addresses."); | ||
| 137 | |||
| 138 | hr = WcaGetRecordFormattedString(hRec, feqRemotePort, &attrs.pwzRemotePorts); | ||
| 139 | ExitOnFailure(hr, "Failed to get firewall exception remote port."); | ||
| 140 | |||
| 141 | hr = WcaGetRecordFormattedString(hRec, feqServiceName, &attrs.pwzServiceName); | ||
| 142 | ExitOnFailure(hr, "Failed to get firewall exception service name."); | ||
| 143 | |||
| 144 | hr = WcaGetRecordFormattedString(hRec, feqLocalAppPackageId, &attrs.pwzLocalAppPackageId); | ||
| 145 | ExitOnFailure(hr, "Failed to get firewall exception local app package id."); | ||
| 146 | |||
| 147 | hr = WcaGetRecordFormattedString(hRec, feqLocalUserAuthorizedList, &attrs.pwzLocalUserAuthorizedList); | ||
| 148 | ExitOnFailure(hr, "Failed to get firewall exception local user authorized list."); | ||
| 149 | |||
| 150 | hr = WcaGetRecordFormattedString(hRec, feqLocalUserOwner, &attrs.pwzLocalUserOwner); | ||
| 151 | ExitOnFailure(hr, "Failed to get firewall exception local user owner."); | ||
| 152 | |||
| 153 | hr = WcaGetRecordFormattedString(hRec, feqRemoteMachineAuthorizedList, &attrs.pwzRemoteMachineAuthorizedList); | ||
| 154 | ExitOnFailure(hr, "Failed to get firewall exception remote machine authorized list."); | ||
| 155 | |||
| 156 | hr = WcaGetRecordFormattedString(hRec, feqRemoteUserAuthorizedList, &attrs.pwzRemoteUserAuthorizedList); | ||
| 157 | ExitOnFailure(hr, "Failed to get firewall exception remote user authorized list."); | ||
| 158 | |||
| 159 | hr = WcaGetRecordFormattedInteger(hRec, feqSecureFlags, &attrs.iSecureFlags); | ||
| 160 | ExitOnFailure(hr, "Failed to get firewall exception secure flag."); | ||
| 161 | |||
| 94 | // figure out what we're doing for this exception, treating reinstall the same as install | 162 | // figure out what we're doing for this exception, treating reinstall the same as install |
| 95 | WCA_TODO todoComponent = WcaGetComponentToDo(pwzComponent); | 163 | WCA_TODO todoComponent = WcaGetComponentToDo(pwzComponent); |
| 96 | if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched) | 164 | if ((WCA_TODO_REINSTALL == todoComponent ? WCA_TODO_INSTALL : todoComponent) != todoSched) |
| @@ -99,7 +167,6 @@ static UINT SchedFirewallExceptions( | |||
| 99 | continue; | 167 | continue; |
| 100 | } | 168 | } |
| 101 | 169 | ||
| 102 | // action :: name :: profile :: remoteaddresses :: attributes :: target :: {port::protocol | path} | ||
| 103 | ++cFirewallExceptions; | 170 | ++cFirewallExceptions; |
| 104 | hr = WcaWriteIntegerToCaData(todoComponent, &pwzCustomActionData); | 171 | hr = WcaWriteIntegerToCaData(todoComponent, &pwzCustomActionData); |
| 105 | ExitOnFailure(hr, "failed to write exception action to custom action data"); | 172 | ExitOnFailure(hr, "failed to write exception action to custom action data"); |
| @@ -116,40 +183,75 @@ static UINT SchedFirewallExceptions( | |||
| 116 | hr = WcaWriteIntegerToCaData(attrs.iAttributes, &pwzCustomActionData); | 183 | hr = WcaWriteIntegerToCaData(attrs.iAttributes, &pwzCustomActionData); |
| 117 | ExitOnFailure(hr, "failed to write exception attributes to custom action data"); | 184 | ExitOnFailure(hr, "failed to write exception attributes to custom action data"); |
| 118 | 185 | ||
| 119 | if (*attrs.pwzProgram) | 186 | hr = WcaWriteStringToCaData(attrs.pwzApplicationName, &pwzCustomActionData); |
| 120 | { | ||
| 121 | // If program is defined, we have an application exception. | ||
| 122 | hr = WcaWriteIntegerToCaData(fetApplication, &pwzCustomActionData); | ||
| 123 | ExitOnFailure(hr, "failed to write exception target (application) to custom action data"); | ||
| 124 | |||
| 125 | hr = WcaWriteStringToCaData(attrs.pwzProgram, &pwzCustomActionData); | ||
| 126 | ExitOnFailure(hr, "failed to write application path to custom action data"); | ||
| 127 | } | ||
| 128 | else | ||
| 129 | { | ||
| 130 | // we have a port-only exception | ||
| 131 | hr = WcaWriteIntegerToCaData(fetPort, &pwzCustomActionData); | ||
| 132 | ExitOnFailure(hr, "failed to write exception target (port) to custom action data"); | ||
| 133 | } | ||
| 134 | |||
| 135 | hr = WcaWriteStringToCaData(attrs.pwzPort, &pwzCustomActionData); | ||
| 136 | ExitOnFailure(hr, "failed to write application path to custom action data"); | 187 | ExitOnFailure(hr, "failed to write application path to custom action data"); |
| 137 | 188 | ||
| 189 | hr = WcaWriteStringToCaData(attrs.pwzLocalPorts, &pwzCustomActionData); | ||
| 190 | ExitOnFailure(hr, "failed to write local ports to custom action data"); | ||
| 191 | |||
| 138 | hr = WcaWriteIntegerToCaData(attrs.iProtocol, &pwzCustomActionData); | 192 | hr = WcaWriteIntegerToCaData(attrs.iProtocol, &pwzCustomActionData); |
| 139 | ExitOnFailure(hr, "failed to write exception protocol to custom action data"); | 193 | ExitOnFailure(hr, "failed to write exception protocol to custom action data"); |
| 140 | 194 | ||
| 141 | hr = WcaWriteStringToCaData(attrs.pwzDescription, &pwzCustomActionData); | 195 | hr = WcaWriteStringToCaData(attrs.pwzDescription, &pwzCustomActionData); |
| 142 | ExitOnFailure(hr, "failed to write firewall rule description to custom action data"); | 196 | ExitOnFailure(hr, "failed to write firewall exception description to custom action data"); |
| 143 | 197 | ||
| 144 | hr = WcaWriteIntegerToCaData(attrs.iDirection, &pwzCustomActionData); | 198 | hr = WcaWriteIntegerToCaData(attrs.iDirection, &pwzCustomActionData); |
| 145 | ExitOnFailure(hr, "failed to write firewall rule direction to custom action data"); | 199 | ExitOnFailure(hr, "failed to write firewall exception direction to custom action data"); |
| 200 | |||
| 201 | hr = WcaWriteIntegerToCaData(attrs.iAction, &pwzCustomActionData); | ||
| 202 | ExitOnFailure(hr, "failed to write exception action to custom action data"); | ||
| 203 | |||
| 204 | hr = WcaWriteIntegerToCaData(attrs.iEdgeTraversal, &pwzCustomActionData); | ||
| 205 | ExitOnFailure(hr, "failed to write exception edge traversal to custom action data"); | ||
| 206 | |||
| 207 | hr = WcaWriteIntegerToCaData(attrs.iEnabled, &pwzCustomActionData); | ||
| 208 | ExitOnFailure(hr, "failed to write exception enabled flag to custom action data"); | ||
| 209 | |||
| 210 | hr = WcaWriteStringToCaData(attrs.pwzGrouping, &pwzCustomActionData); | ||
| 211 | ExitOnFailure(hr, "failed to write grouping to custom action data"); | ||
| 212 | |||
| 213 | hr = WcaWriteStringToCaData(attrs.pwzIcmpTypesAndCodes, &pwzCustomActionData); | ||
| 214 | ExitOnFailure(hr, "failed to write icmp types and codes to custom action data"); | ||
| 215 | |||
| 216 | hr = WcaWriteStringToCaData(attrs.pwzInterfaces, &pwzCustomActionData); | ||
| 217 | ExitOnFailure(hr, "failed to write interfaces to custom action data"); | ||
| 218 | |||
| 219 | hr = WcaWriteStringToCaData(attrs.pwzInterfaceTypes, &pwzCustomActionData); | ||
| 220 | ExitOnFailure(hr, "failed to write interface types to custom action data"); | ||
| 221 | |||
| 222 | hr = WcaWriteStringToCaData(attrs.pwzLocalAddresses, &pwzCustomActionData); | ||
| 223 | ExitOnFailure(hr, "failed to write local addresses to custom action data"); | ||
| 224 | |||
| 225 | hr = WcaWriteStringToCaData(attrs.pwzRemotePorts, &pwzCustomActionData); | ||
| 226 | ExitOnFailure(hr, "failed to write remote ports to custom action data"); | ||
| 227 | |||
| 228 | hr = WcaWriteStringToCaData(attrs.pwzServiceName, &pwzCustomActionData); | ||
| 229 | ExitOnFailure(hr, "failed to write service name to custom action data"); | ||
| 230 | |||
| 231 | hr = WcaWriteStringToCaData(attrs.pwzLocalAppPackageId, &pwzCustomActionData); | ||
| 232 | ExitOnFailure(hr, "failed to write local app package id to custom action data"); | ||
| 233 | |||
| 234 | hr = WcaWriteStringToCaData(attrs.pwzLocalUserAuthorizedList, &pwzCustomActionData); | ||
| 235 | ExitOnFailure(hr, "failed to write local user authorized list to custom action data"); | ||
| 236 | |||
| 237 | hr = WcaWriteStringToCaData(attrs.pwzLocalUserOwner, &pwzCustomActionData); | ||
| 238 | ExitOnFailure(hr, "failed to write local user owner to custom action data"); | ||
| 239 | |||
| 240 | hr = WcaWriteStringToCaData(attrs.pwzRemoteMachineAuthorizedList, &pwzCustomActionData); | ||
| 241 | ExitOnFailure(hr, "failed to write remote machine authorized list to custom action data"); | ||
| 242 | |||
| 243 | hr = WcaWriteStringToCaData(attrs.pwzRemoteUserAuthorizedList, &pwzCustomActionData); | ||
| 244 | ExitOnFailure(hr, "failed to write remote user authorized list to custom action data"); | ||
| 245 | |||
| 246 | hr = WcaWriteIntegerToCaData(attrs.iSecureFlags, &pwzCustomActionData); | ||
| 247 | ExitOnFailure(hr, "failed to write exception secure flags to custom action data"); | ||
| 146 | } | 248 | } |
| 147 | 249 | ||
| 148 | // reaching the end of the list is actually a good thing, not an error | 250 | // reaching the end of the list is actually a good thing, not an error |
| 149 | if (E_NOMOREITEMS == hr) | 251 | if (E_NOMOREITEMS == hr) |
| 150 | { | 252 | { |
| 151 | hr = S_OK; | 253 | hr = S_OK; |
| 152 | } | 254 | } |
| 153 | ExitOnFailure(hr, "failure occured while processing Wix5FirewallException table"); | 255 | ExitOnFailure(hr, "failure occured while processing Wix5FirewallException table"); |
| 154 | 256 | ||
| 155 | // schedule ExecFirewallExceptions if there's anything to do | 257 | // schedule ExecFirewallExceptions if there's anything to do |
| @@ -160,14 +262,14 @@ static UINT SchedFirewallExceptions( | |||
| 160 | if (WCA_TODO_INSTALL == todoSched) | 262 | if (WCA_TODO_INSTALL == todoSched) |
| 161 | { | 263 | { |
| 162 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); | 264 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); |
| 163 | ExitOnFailure(hr, "failed to schedule firewall install exceptions rollback"); | 265 | ExitOnFailure(hr, "failed to schedule firewall install exceptions rollback"); |
| 164 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); | 266 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); |
| 165 | ExitOnFailure(hr, "failed to schedule firewall install exceptions execution"); | 267 | ExitOnFailure(hr, "failed to schedule firewall install exceptions execution"); |
| 166 | } | 268 | } |
| 167 | else | 269 | else |
| 168 | { | 270 | { |
| 169 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); | 271 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); |
| 170 | ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions rollback"); | 272 | ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions rollback"); |
| 171 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); | 273 | hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION); |
| 172 | ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions execution"); | 274 | ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions execution"); |
| 173 | } | 275 | } |
| @@ -180,53 +282,68 @@ static UINT SchedFirewallExceptions( | |||
| 180 | LExit: | 282 | LExit: |
| 181 | ReleaseStr(attrs.pwzName); | 283 | ReleaseStr(attrs.pwzName); |
| 182 | ReleaseStr(attrs.pwzRemoteAddresses); | 284 | ReleaseStr(attrs.pwzRemoteAddresses); |
| 183 | ReleaseStr(attrs.pwzPort); | 285 | ReleaseStr(attrs.pwzLocalPorts); |
| 184 | ReleaseStr(attrs.pwzProgram); | 286 | ReleaseStr(attrs.pwzApplicationName); |
| 185 | ReleaseStr(attrs.pwzDescription); | 287 | ReleaseStr(attrs.pwzDescription); |
| 288 | ReleaseStr(attrs.pwzGrouping); | ||
| 289 | ReleaseStr(attrs.pwzIcmpTypesAndCodes); | ||
| 290 | ReleaseStr(attrs.pwzInterfaces); | ||
| 291 | ReleaseStr(attrs.pwzInterfaceTypes); | ||
| 292 | ReleaseStr(attrs.pwzLocalAddresses); | ||
| 293 | ReleaseStr(attrs.pwzRemotePorts); | ||
| 294 | ReleaseStr(attrs.pwzServiceName); | ||
| 295 | ReleaseStr(attrs.pwzLocalAppPackageId); | ||
| 296 | ReleaseStr(attrs.pwzLocalUserAuthorizedList); | ||
| 297 | ReleaseStr(attrs.pwzLocalUserOwner); | ||
| 298 | ReleaseStr(attrs.pwzRemoteMachineAuthorizedList); | ||
| 299 | ReleaseStr(attrs.pwzRemoteUserAuthorizedList); | ||
| 186 | ReleaseStr(pwzComponent); | 300 | ReleaseStr(pwzComponent); |
| 187 | ReleaseStr(pwzCustomActionData); | 301 | ReleaseStr(pwzCustomActionData); |
| 188 | 302 | ||
| 189 | return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er); | 303 | return WcaFinalize(er = FAILED(hr) ? ERROR_INSTALL_FAILURE : er); |
| 190 | } | 304 | } |
| 191 | 305 | ||
| 192 | /****************************************************************** | 306 | |
| 307 | /******************************************************************* | ||
| 193 | SchedFirewallExceptionsInstall - immediate custom action entry | 308 | SchedFirewallExceptionsInstall - immediate custom action entry |
| 194 | point to register firewall exceptions. | 309 | point to register firewall exceptions. |
| 195 | 310 | ||
| 196 | ********************************************************************/ | 311 | ********************************************************************/ |
| 197 | extern "C" UINT __stdcall SchedFirewallExceptionsInstall( | 312 | extern "C" UINT __stdcall SchedFirewallExceptionsInstall( |
| 198 | __in MSIHANDLE hInstall | 313 | __in MSIHANDLE hInstall |
| 199 | ) | 314 | ) |
| 200 | { | 315 | { |
| 201 | return SchedFirewallExceptions(hInstall, WCA_TODO_INSTALL); | 316 | return SchedFirewallExceptions(hInstall, WCA_TODO_INSTALL); |
| 202 | } | 317 | } |
| 203 | 318 | ||
| 204 | /****************************************************************** | 319 | |
| 320 | /******************************************************************* | ||
| 205 | SchedFirewallExceptionsUninstall - immediate custom action entry | 321 | SchedFirewallExceptionsUninstall - immediate custom action entry |
| 206 | point to remove firewall exceptions. | 322 | point to remove firewall exceptions. |
| 207 | 323 | ||
| 208 | ********************************************************************/ | 324 | ********************************************************************/ |
| 209 | extern "C" UINT __stdcall SchedFirewallExceptionsUninstall( | 325 | extern "C" UINT __stdcall SchedFirewallExceptionsUninstall( |
| 210 | __in MSIHANDLE hInstall | 326 | __in MSIHANDLE hInstall |
| 211 | ) | 327 | ) |
| 212 | { | 328 | { |
| 213 | return SchedFirewallExceptions(hInstall, WCA_TODO_UNINSTALL); | 329 | return SchedFirewallExceptions(hInstall, WCA_TODO_UNINSTALL); |
| 214 | } | 330 | } |
| 215 | 331 | ||
| 216 | /****************************************************************** | 332 | |
| 333 | /******************************************************************* | ||
| 217 | GetFirewallRules - Get the collection of firewall rules. | 334 | GetFirewallRules - Get the collection of firewall rules. |
| 218 | 335 | ||
| 219 | ********************************************************************/ | 336 | ********************************************************************/ |
| 220 | static HRESULT GetFirewallRules( | 337 | static HRESULT GetFirewallRules( |
| 221 | __in BOOL fIgnoreFailures, | 338 | __in BOOL fIgnoreFailures, |
| 222 | __out INetFwRules** ppNetFwRules | 339 | __out INetFwRules** ppNetFwRules |
| 223 | ) | 340 | ) |
| 224 | { | 341 | { |
| 225 | HRESULT hr = S_OK; | 342 | HRESULT hr = S_OK; |
| 226 | INetFwPolicy2* pNetFwPolicy2 = NULL; | 343 | INetFwPolicy2* pNetFwPolicy2 = NULL; |
| 227 | INetFwRules* pNetFwRules = NULL; | 344 | INetFwRules* pNetFwRules = NULL; |
| 228 | *ppNetFwRules = NULL; | 345 | *ppNetFwRules = NULL; |
| 229 | 346 | ||
| 230 | do | 347 | do |
| 231 | { | 348 | { |
| 232 | ReleaseNullObject(pNetFwPolicy2); | 349 | ReleaseNullObject(pNetFwPolicy2); |
| @@ -262,7 +379,7 @@ static HRESULT GetFirewallRules( | |||
| 262 | 379 | ||
| 263 | *ppNetFwRules = pNetFwRules; | 380 | *ppNetFwRules = pNetFwRules; |
| 264 | pNetFwRules = NULL; | 381 | pNetFwRules = NULL; |
| 265 | 382 | ||
| 266 | LExit: | 383 | LExit: |
| 267 | ReleaseObject(pNetFwPolicy2); | 384 | ReleaseObject(pNetFwPolicy2); |
| 268 | ReleaseObject(pNetFwRules); | 385 | ReleaseObject(pNetFwRules); |
| @@ -270,51 +387,380 @@ LExit: | |||
| 270 | return hr; | 387 | return hr; |
| 271 | } | 388 | } |
| 272 | 389 | ||
| 273 | /****************************************************************** | 390 | |
| 274 | CreateFwRuleObject - CoCreate a firewall rule, and set the common set of properties which are shared | 391 | /******************************************************************* |
| 275 | between port and application firewall rules | 392 | CreateFwRuleObject - CoCreate a firewall rule, and set the name |
| 276 | 393 | ||
| 277 | ********************************************************************/ | 394 | ********************************************************************/ |
| 278 | static HRESULT CreateFwRuleObject( | 395 | static HRESULT CreateFwRuleObject( |
| 279 | __in BSTR bstrName, | 396 | __in BSTR bstrName, |
| 280 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs, | ||
| 281 | __out INetFwRule** ppNetFwRule | 397 | __out INetFwRule** ppNetFwRule |
| 282 | ) | 398 | ) |
| 399 | { | ||
| 400 | HRESULT hr = S_OK; | ||
| 401 | INetFwRule* pNetFwRule = NULL; | ||
| 402 | *ppNetFwRule = NULL; | ||
| 403 | |||
| 404 | hr = ::CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_ALL, __uuidof(INetFwRule), (LPVOID*)&pNetFwRule); | ||
| 405 | ExitOnFailure(hr, "failed to create NetFwRule object"); | ||
| 406 | |||
| 407 | hr = pNetFwRule->put_Name(bstrName); | ||
| 408 | ExitOnFailure(hr, "failed to set firewall exception name"); | ||
| 409 | |||
| 410 | *ppNetFwRule = pNetFwRule; | ||
| 411 | |||
| 412 | LExit: | ||
| 413 | return hr; | ||
| 414 | } | ||
| 415 | |||
| 416 | |||
| 417 | /********************************************************************* | ||
| 418 | GetFwRuleInterfaces - pack firewall rule interfaces into a VARIANT. | ||
| 419 | The populated VARIANT needs to be cleaned up by the calling function. | ||
| 420 | |||
| 421 | **********************************************************************/ | ||
| 422 | static HRESULT GetFwRuleInterfaces( | ||
| 423 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs, | ||
| 424 | __out VARIANT& vInterfaces | ||
| 425 | ) | ||
| 426 | { | ||
| 427 | HRESULT hr = S_OK; | ||
| 428 | BSTR bstrInterfaces = NULL; | ||
| 429 | const WCHAR FORBIDDEN_FIREWALL_CHAR = L'|'; | ||
| 430 | LONG iInterfacesCount = 0; | ||
| 431 | UINT iLength = 0; | ||
| 432 | LONG iIndex = 0; | ||
| 433 | |||
| 434 | ::VariantInit(&vInterfaces); | ||
| 435 | ExitOnNull(attrs.pwzInterfaces, hr, S_OK, "No interfaces to pack"); | ||
| 436 | |||
| 437 | bstrInterfaces = ::SysAllocString(attrs.pwzInterfaces); | ||
| 438 | ExitOnNull(bstrInterfaces, hr, E_OUTOFMEMORY, "failed SysAllocString for interfaces"); | ||
| 439 | |||
| 440 | iLength = ::SysStringLen(bstrInterfaces); | ||
| 441 | |||
| 442 | LPWSTR pwzT = bstrInterfaces; | ||
| 443 | while (*pwzT) | ||
| 444 | { | ||
| 445 | if (FORBIDDEN_FIREWALL_CHAR == *pwzT) | ||
| 446 | { | ||
| 447 | *pwzT = L'\0'; | ||
| 448 | pwzT++; | ||
| 449 | |||
| 450 | // skip empty values inside the interfaces eg. ||| | ||
| 451 | if (*pwzT && FORBIDDEN_FIREWALL_CHAR != *pwzT) | ||
| 452 | { | ||
| 453 | iInterfacesCount++; | ||
| 454 | } | ||
| 455 | } | ||
| 456 | else | ||
| 457 | { | ||
| 458 | if (pwzT == bstrInterfaces) | ||
| 459 | { | ||
| 460 | iInterfacesCount++; | ||
| 461 | } | ||
| 462 | |||
| 463 | pwzT++; | ||
| 464 | } | ||
| 465 | } | ||
| 466 | |||
| 467 | ExitOnNull(iInterfacesCount, hr, S_OK, "All interfaces are empty values"); | ||
| 468 | |||
| 469 | vInterfaces.vt = VT_ARRAY | VT_VARIANT; | ||
| 470 | // this will be cleaned up by ReleaseVariant call of the calling function | ||
| 471 | vInterfaces.parray = SafeArrayCreateVector(VT_VARIANT, 0, iInterfacesCount); | ||
| 472 | |||
| 473 | for (LPCWSTR pwzElement = bstrInterfaces; pwzElement < (bstrInterfaces + iLength); ++pwzElement) | ||
| 474 | { | ||
| 475 | if (*pwzElement) | ||
| 476 | { | ||
| 477 | VARIANT vElement; | ||
| 478 | ::VariantInit(&vElement); | ||
| 479 | |||
| 480 | vElement.vt = VT_BSTR; | ||
| 481 | // this will be cleaned up by ReleaseVariant call of the calling function | ||
| 482 | vElement.bstrVal = ::SysAllocString(pwzElement); | ||
| 483 | ExitOnNull(vElement.bstrVal, hr, E_OUTOFMEMORY, "failed SysAllocString for interface element"); | ||
| 484 | |||
| 485 | hr = SafeArrayPutElement(vInterfaces.parray, &iIndex, &vElement); | ||
| 486 | ExitOnFailure(hr, "failed to put interface '%ls' into safe array", pwzElement); | ||
| 487 | |||
| 488 | pwzElement += ::SysStringLen(vElement.bstrVal); | ||
| 489 | iIndex++; | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | LExit: | ||
| 494 | ReleaseBSTR(bstrInterfaces); | ||
| 495 | |||
| 496 | return hr; | ||
| 497 | } | ||
| 498 | |||
| 499 | /****************************************************************************** | ||
| 500 | UpdateFwRule2Object - update properties for a firewall INetFwRule2 interface. | ||
| 501 | Requires Windows 7 / 2008 R2 | ||
| 502 | |||
| 503 | ******************************************************************************/ | ||
| 504 | static HRESULT UpdateFwRule2Object( | ||
| 505 | __in INetFwRule* pNetFwRule, | ||
| 506 | __in BOOL fUpdateRule, | ||
| 507 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs | ||
| 508 | ) | ||
| 283 | { | 509 | { |
| 284 | HRESULT hr = S_OK; | 510 | HRESULT hr = S_OK; |
| 511 | INetFwRule2* pNetFwRule2 = NULL; | ||
| 512 | |||
| 513 | hr = pNetFwRule->QueryInterface(__uuidof(INetFwRule2), (LPVOID*)&pNetFwRule2); | ||
| 514 | ExitOnFailure(hr, "failed to query INetFwRule2 interface"); | ||
| 515 | |||
| 516 | if (MSI_NULL_INTEGER != attrs.iEdgeTraversal) | ||
| 517 | { | ||
| 518 | hr = pNetFwRule2->put_EdgeTraversalOptions(attrs.iEdgeTraversal); | ||
| 519 | ExitOnFailure(hr, "failed to set exception edge traversal option"); | ||
| 520 | } | ||
| 521 | else if (fUpdateRule) | ||
| 522 | { | ||
| 523 | hr = pNetFwRule2->put_EdgeTraversalOptions(NET_FW_EDGE_TRAVERSAL_TYPE_DENY); | ||
| 524 | ExitOnFailure(hr, "failed to remove exception edge traversal option"); | ||
| 525 | } | ||
| 526 | |||
| 527 | LExit: | ||
| 528 | ReleaseObject(pNetFwRule2); | ||
| 529 | |||
| 530 | return hr; | ||
| 531 | } | ||
| 532 | |||
| 533 | |||
| 534 | /****************************************************************************** | ||
| 535 | UpdateFwRule3Object - update properties for a firewall INetFwRule3 interface. | ||
| 536 | Requires Windows 8 / 2012 | ||
| 537 | |||
| 538 | ******************************************************************************/ | ||
| 539 | static HRESULT UpdateFwRule3Object( | ||
| 540 | __in INetFwRule* pNetFwRule, | ||
| 541 | __in BOOL fUpdateRule, | ||
| 542 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs | ||
| 543 | ) | ||
| 544 | { | ||
| 545 | HRESULT hr = S_OK; | ||
| 546 | |||
| 547 | BSTR bstrLocalAppPackageId = NULL; | ||
| 548 | BSTR bstrLocalUserAuthorizedList = NULL; | ||
| 549 | BSTR bstrLocalUserOwner = NULL; | ||
| 550 | BSTR bstrRemoteMachineAuthorizedList = NULL; | ||
| 551 | BSTR bstrRemoteUserAuthorizedList = NULL; | ||
| 552 | INetFwRule3* pNetFwRule3 = NULL; | ||
| 553 | |||
| 554 | bstrLocalAppPackageId = ::SysAllocString(attrs.pwzLocalAppPackageId); | ||
| 555 | ExitOnNull(bstrLocalAppPackageId, hr, E_OUTOFMEMORY, "failed SysAllocString for local app package id"); | ||
| 556 | bstrLocalUserAuthorizedList = ::SysAllocString(attrs.pwzLocalUserAuthorizedList); | ||
| 557 | ExitOnNull(bstrLocalUserAuthorizedList, hr, E_OUTOFMEMORY, "failed SysAllocString for local user authorized list"); | ||
| 558 | bstrLocalUserOwner = ::SysAllocString(attrs.pwzLocalUserOwner); | ||
| 559 | ExitOnNull(bstrLocalUserOwner, hr, E_OUTOFMEMORY, "failed SysAllocString for local user owner"); | ||
| 560 | bstrRemoteMachineAuthorizedList = ::SysAllocString(attrs.pwzRemoteMachineAuthorizedList); | ||
| 561 | ExitOnNull(bstrRemoteMachineAuthorizedList, hr, E_OUTOFMEMORY, "failed SysAllocString for remote machine authorized list"); | ||
| 562 | bstrRemoteUserAuthorizedList = ::SysAllocString(attrs.pwzRemoteUserAuthorizedList); | ||
| 563 | ExitOnNull(bstrRemoteUserAuthorizedList, hr, E_OUTOFMEMORY, "failed SysAllocString for remote user authorized list"); | ||
| 564 | |||
| 565 | hr = pNetFwRule->QueryInterface(__uuidof(INetFwRule3), (LPVOID*)&pNetFwRule3); | ||
| 566 | ExitOnFailure(hr, "failed to query INetFwRule3 interface"); | ||
| 567 | |||
| 568 | if (bstrLocalAppPackageId && *bstrLocalAppPackageId) | ||
| 569 | { | ||
| 570 | hr = pNetFwRule3->put_LocalAppPackageId(bstrLocalAppPackageId); | ||
| 571 | ExitOnFailure(hr, "failed to set exception local app package id"); | ||
| 572 | } | ||
| 573 | else if (fUpdateRule) | ||
| 574 | { | ||
| 575 | hr = pNetFwRule3->put_LocalAppPackageId(NULL); | ||
| 576 | ExitOnFailure(hr, "failed to remove exception local app package id"); | ||
| 577 | } | ||
| 578 | |||
| 579 | if (bstrLocalUserAuthorizedList && *bstrLocalUserAuthorizedList) | ||
| 580 | { | ||
| 581 | hr = pNetFwRule3->put_LocalUserAuthorizedList(bstrLocalUserAuthorizedList); | ||
| 582 | ExitOnFailure(hr, "failed to set exception local user authorized list"); | ||
| 583 | } | ||
| 584 | else if (fUpdateRule) | ||
| 585 | { | ||
| 586 | hr = pNetFwRule3->put_LocalUserAuthorizedList(NULL); | ||
| 587 | ExitOnFailure(hr, "failed to remove exception local user authorized list"); | ||
| 588 | } | ||
| 589 | |||
| 590 | if (bstrLocalUserOwner && *bstrLocalUserOwner) | ||
| 591 | { | ||
| 592 | hr = pNetFwRule3->put_LocalUserOwner(bstrLocalUserOwner); | ||
| 593 | ExitOnFailure(hr, "failed to set exception local user owner"); | ||
| 594 | } | ||
| 595 | else if (fUpdateRule) | ||
| 596 | { | ||
| 597 | hr = pNetFwRule3->put_LocalUserOwner(NULL); | ||
| 598 | ExitOnFailure(hr, "failed to remove exception local user owner"); | ||
| 599 | } | ||
| 600 | |||
| 601 | if (bstrRemoteMachineAuthorizedList && *bstrRemoteMachineAuthorizedList) | ||
| 602 | { | ||
| 603 | hr = pNetFwRule3->put_RemoteMachineAuthorizedList(bstrRemoteMachineAuthorizedList); | ||
| 604 | ExitOnFailure(hr, "failed to set exception remote machine authorized list"); | ||
| 605 | } | ||
| 606 | else if (fUpdateRule) | ||
| 607 | { | ||
| 608 | hr = pNetFwRule3->put_RemoteMachineAuthorizedList(NULL); | ||
| 609 | ExitOnFailure(hr, "failed to remove exception remote machine authorized list"); | ||
| 610 | } | ||
| 611 | |||
| 612 | if (bstrRemoteUserAuthorizedList && *bstrRemoteUserAuthorizedList) | ||
| 613 | { | ||
| 614 | hr = pNetFwRule3->put_RemoteUserAuthorizedList(bstrRemoteUserAuthorizedList); | ||
| 615 | ExitOnFailure(hr, "failed to set exception remote user authorized list"); | ||
| 616 | } | ||
| 617 | else if (fUpdateRule) | ||
| 618 | { | ||
| 619 | hr = pNetFwRule3->put_RemoteUserAuthorizedList(NULL); | ||
| 620 | ExitOnFailure(hr, "failed to remove exception remote user authorized list"); | ||
| 621 | } | ||
| 622 | |||
| 623 | if (MSI_NULL_INTEGER != attrs.iSecureFlags) | ||
| 624 | { | ||
| 625 | hr = pNetFwRule3->put_SecureFlags(attrs.iSecureFlags); | ||
| 626 | ExitOnFailure(hr, "failed to set exception IPsec secure flags"); | ||
| 627 | } | ||
| 628 | else if (fUpdateRule) | ||
| 629 | { | ||
| 630 | hr = pNetFwRule3->put_SecureFlags(NET_FW_AUTHENTICATE_NONE); | ||
| 631 | ExitOnFailure(hr, "failed to reset exception IPsec secure flags"); | ||
| 632 | } | ||
| 633 | |||
| 634 | LExit: | ||
| 635 | ReleaseBSTR(bstrLocalAppPackageId); | ||
| 636 | ReleaseBSTR(bstrLocalUserAuthorizedList); | ||
| 637 | ReleaseBSTR(bstrLocalUserOwner); | ||
| 638 | ReleaseBSTR(bstrRemoteMachineAuthorizedList); | ||
| 639 | ReleaseBSTR(bstrRemoteUserAuthorizedList); | ||
| 640 | ReleaseObject(pNetFwRule3); | ||
| 641 | |||
| 642 | return hr; | ||
| 643 | } | ||
| 644 | |||
| 645 | |||
| 646 | /********************************************************************** | ||
| 647 | UpdateFwRuleObject - update all properties for a basic firewall rule. | ||
| 648 | Requires Windows Vista / 2008 | ||
| 649 | |||
| 650 | **********************************************************************/ | ||
| 651 | static HRESULT UpdateFwRuleObject( | ||
| 652 | __in INetFwRule* pNetFwRule, | ||
| 653 | __in BOOL fUpdateRule, | ||
| 654 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs | ||
| 655 | ) | ||
| 656 | { | ||
| 657 | HRESULT hr = S_OK; | ||
| 658 | BSTR bstrEmpty = NULL; | ||
| 285 | BSTR bstrRemoteAddresses = NULL; | 659 | BSTR bstrRemoteAddresses = NULL; |
| 660 | BSTR bstrFile = NULL; | ||
| 286 | BSTR bstrPort = NULL; | 661 | BSTR bstrPort = NULL; |
| 287 | BSTR bstrDescription = NULL; | 662 | BSTR bstrDescription = NULL; |
| 288 | INetFwRule* pNetFwRule = NULL; | 663 | BSTR bstrGrouping = NULL; |
| 289 | *ppNetFwRule = NULL; | 664 | BSTR bstrIcmpTypesAndCodes = NULL; |
| 665 | BSTR bstrInterfaceTypes = NULL; | ||
| 666 | BSTR bstrLocalAddresses = NULL; | ||
| 667 | BSTR bstrRemotePort = NULL; | ||
| 668 | BSTR bstrServiceName = NULL; | ||
| 669 | VARIANT vInterfaces; | ||
| 670 | ::VariantInit(&vInterfaces); | ||
| 671 | LONG iProtocol = 0; | ||
| 672 | |||
| 673 | INetFwRule2* pNetFwRule2 = NULL; | ||
| 290 | 674 | ||
| 291 | // convert to BSTRs to make COM happy | 675 | // convert to BSTRs to make COM happy |
| 676 | bstrEmpty = ::SysAllocString(L""); | ||
| 677 | ExitOnNull(bstrEmpty, hr, E_OUTOFMEMORY, "failed SysAllocString for empty placeholder"); | ||
| 678 | |||
| 292 | bstrRemoteAddresses = ::SysAllocString(attrs.pwzRemoteAddresses); | 679 | bstrRemoteAddresses = ::SysAllocString(attrs.pwzRemoteAddresses); |
| 293 | ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses"); | 680 | ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses"); |
| 294 | bstrPort = ::SysAllocString(attrs.pwzPort); | 681 | bstrFile = ::SysAllocString(attrs.pwzApplicationName); |
| 682 | ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for application name"); | ||
| 683 | bstrPort = ::SysAllocString(attrs.pwzLocalPorts); | ||
| 295 | ExitOnNull(bstrPort, hr, E_OUTOFMEMORY, "failed SysAllocString for port"); | 684 | ExitOnNull(bstrPort, hr, E_OUTOFMEMORY, "failed SysAllocString for port"); |
| 296 | bstrDescription = ::SysAllocString(attrs.pwzDescription); | 685 | bstrDescription = ::SysAllocString(attrs.pwzDescription); |
| 297 | ExitOnNull(bstrDescription, hr, E_OUTOFMEMORY, "failed SysAllocString for description"); | 686 | ExitOnNull(bstrDescription, hr, E_OUTOFMEMORY, "failed SysAllocString for description"); |
| 687 | bstrGrouping = ::SysAllocString(attrs.pwzGrouping); | ||
| 688 | ExitOnNull(bstrGrouping, hr, E_OUTOFMEMORY, "failed SysAllocString for grouping"); | ||
| 689 | bstrIcmpTypesAndCodes = ::SysAllocString(attrs.pwzIcmpTypesAndCodes); | ||
| 690 | ExitOnNull(bstrIcmpTypesAndCodes, hr, E_OUTOFMEMORY, "failed SysAllocString for icmp types and codes"); | ||
| 691 | bstrInterfaceTypes = ::SysAllocString(attrs.pwzInterfaceTypes); | ||
| 692 | ExitOnNull(bstrInterfaceTypes, hr, E_OUTOFMEMORY, "failed SysAllocString for interface types"); | ||
| 693 | bstrLocalAddresses = ::SysAllocString(attrs.pwzLocalAddresses); | ||
| 694 | ExitOnNull(bstrLocalAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for local addresses"); | ||
| 695 | bstrRemotePort = ::SysAllocString(attrs.pwzRemotePorts); | ||
| 696 | ExitOnNull(bstrRemotePort, hr, E_OUTOFMEMORY, "failed SysAllocString for remote port"); | ||
| 697 | bstrServiceName = ::SysAllocString(attrs.pwzServiceName); | ||
| 698 | ExitOnNull(bstrServiceName, hr, E_OUTOFMEMORY, "failed SysAllocString for service name"); | ||
| 699 | |||
| 700 | if (fUpdateRule) | ||
| 701 | { | ||
| 702 | hr = pNetFwRule->get_Protocol(&iProtocol); | ||
| 703 | ExitOnFailure(hr, "failed to get exception protocol"); | ||
| 298 | 704 | ||
| 299 | hr = ::CoCreateInstance(__uuidof(NetFwRule), NULL, CLSCTX_ALL, __uuidof(INetFwRule), (void**)&pNetFwRule); | 705 | // If you are editing a TCP port rule and converting it into an ICMP rule, |
| 300 | ExitOnFailure(hr, "failed to create NetFwRule object"); | 706 | // first delete the ports, change protocol from TCP to ICMP, and then add the ports. |
| 301 | 707 | ||
| 302 | hr = pNetFwRule->put_Name(bstrName); | 708 | switch (iProtocol) |
| 303 | ExitOnFailure(hr, "failed to set exception name"); | 709 | { |
| 710 | case NET_FW_IP_PROTOCOL_ANY: | ||
| 711 | break; | ||
| 304 | 712 | ||
| 305 | hr = pNetFwRule->put_Profiles(static_cast<NET_FW_PROFILE_TYPE2>(attrs.iProfile)); | 713 | case 1: // ICMP |
| 306 | ExitOnFailure(hr, "failed to set exception profile"); | 714 | hr = pNetFwRule->put_IcmpTypesAndCodes(NULL); |
| 715 | ExitOnFailure(hr, "failed to remove exception icmp types and codes"); | ||
| 716 | // fall through and reset ports too | ||
| 307 | 717 | ||
| 718 | default: | ||
| 719 | hr = pNetFwRule->put_LocalPorts(NULL); | ||
| 720 | ExitOnFailure(hr, "failed to update exception local ports to NULL"); | ||
| 721 | |||
| 722 | hr = pNetFwRule->put_RemotePorts(NULL); | ||
| 723 | ExitOnFailure(hr, "failed to update exception remote ports to NULL"); | ||
| 724 | break; | ||
| 725 | } | ||
| 726 | } | ||
| 727 | |||
| 728 | if (MSI_NULL_INTEGER != attrs.iProfile) | ||
| 729 | { | ||
| 730 | hr = pNetFwRule->put_Profiles(static_cast<NET_FW_PROFILE_TYPE2> (attrs.iProfile)); | ||
| 731 | ExitOnFailure(hr, "failed to set exception profile"); | ||
| 732 | } | ||
| 733 | else if (fUpdateRule) | ||
| 734 | { | ||
| 735 | hr = pNetFwRule->put_Profiles(NET_FW_PROFILE2_ALL); | ||
| 736 | ExitOnFailure(hr, "failed to reset exception profile to all"); | ||
| 737 | } | ||
| 738 | |||
| 739 | // The Protocol property must be set before the LocalPorts/RemotePorts properties or an error will be returned. | ||
| 308 | if (MSI_NULL_INTEGER != attrs.iProtocol) | 740 | if (MSI_NULL_INTEGER != attrs.iProtocol) |
| 309 | { | 741 | { |
| 310 | hr = pNetFwRule->put_Protocol(static_cast<NET_FW_IP_PROTOCOL>(attrs.iProtocol)); | 742 | hr = pNetFwRule->put_Protocol(static_cast<NET_FW_IP_PROTOCOL> (attrs.iProtocol)); |
| 311 | ExitOnFailure(hr, "failed to set exception protocol"); | 743 | ExitOnFailure(hr, "failed to set exception protocol"); |
| 312 | } | 744 | } |
| 745 | else if (fUpdateRule) | ||
| 746 | { | ||
| 747 | if ((bstrPort && *bstrPort) || (bstrRemotePort && *bstrRemotePort)) | ||
| 748 | { | ||
| 749 | // default protocol is "TCP" in the WiX firewall compiler if a port is specified | ||
| 750 | hr = pNetFwRule->put_Protocol(NET_FW_IP_PROTOCOL_TCP); | ||
| 751 | ExitOnFailure(hr, "failed to reset exception protocol to TCP"); | ||
| 752 | } | ||
| 753 | else | ||
| 754 | { | ||
| 755 | hr = pNetFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY); | ||
| 756 | ExitOnFailure(hr, "failed to reset exception protocol to ANY"); | ||
| 757 | } | ||
| 758 | } | ||
| 313 | 759 | ||
| 314 | if (bstrPort && *bstrPort) | 760 | if (bstrPort && *bstrPort) |
| 315 | { | 761 | { |
| 316 | hr = pNetFwRule->put_LocalPorts(bstrPort); | 762 | hr = pNetFwRule->put_LocalPorts(bstrPort); |
| 317 | ExitOnFailure(hr, "failed to set exception port"); | 763 | ExitOnFailure(hr, "failed to set exception local ports '%ls'", bstrPort); |
| 318 | } | 764 | } |
| 319 | 765 | ||
| 320 | if (bstrRemoteAddresses && *bstrRemoteAddresses) | 766 | if (bstrRemoteAddresses && *bstrRemoteAddresses) |
| @@ -322,122 +768,195 @@ static HRESULT CreateFwRuleObject( | |||
| 322 | hr = pNetFwRule->put_RemoteAddresses(bstrRemoteAddresses); | 768 | hr = pNetFwRule->put_RemoteAddresses(bstrRemoteAddresses); |
| 323 | ExitOnFailure(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses); | 769 | ExitOnFailure(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses); |
| 324 | } | 770 | } |
| 771 | else if (fUpdateRule) | ||
| 772 | { | ||
| 773 | hr = pNetFwRule->put_RemoteAddresses(bstrEmpty); | ||
| 774 | ExitOnFailure(hr, "failed to remove exception remote addresses"); | ||
| 775 | } | ||
| 325 | 776 | ||
| 326 | if (bstrDescription && *bstrDescription) | 777 | if (bstrDescription && *bstrDescription) |
| 327 | { | 778 | { |
| 328 | hr = pNetFwRule->put_Description(bstrDescription); | 779 | hr = pNetFwRule->put_Description(bstrDescription); |
| 329 | ExitOnFailure(hr, "failed to set exception description '%ls'", bstrDescription); | 780 | ExitOnFailure(hr, "failed to set exception description '%ls'", bstrDescription); |
| 330 | } | 781 | } |
| 782 | else if (fUpdateRule) | ||
| 783 | { | ||
| 784 | hr = pNetFwRule->put_Description(bstrEmpty); | ||
| 785 | ExitOnFailure(hr, "failed to remove exception description"); | ||
| 786 | } | ||
| 331 | 787 | ||
| 332 | if (MSI_NULL_INTEGER != attrs.iDirection) | 788 | if (MSI_NULL_INTEGER != attrs.iDirection) |
| 333 | { | 789 | { |
| 334 | hr = pNetFwRule->put_Direction(static_cast<NET_FW_RULE_DIRECTION> (attrs.iDirection)); | 790 | hr = pNetFwRule->put_Direction(static_cast<NET_FW_RULE_DIRECTION> (attrs.iDirection)); |
| 335 | ExitOnFailure(hr, "failed to set exception direction"); | 791 | ExitOnFailure(hr, "failed to set exception direction"); |
| 336 | } | 792 | } |
| 793 | else if (fUpdateRule) | ||
| 794 | { | ||
| 795 | hr = pNetFwRule->put_Direction(NET_FW_RULE_DIR_IN); | ||
| 796 | ExitOnFailure(hr, "failed to reset exception direction to in"); | ||
| 797 | } | ||
| 337 | 798 | ||
| 338 | *ppNetFwRule = pNetFwRule; | 799 | if (MSI_NULL_INTEGER != attrs.iAction) |
| 339 | pNetFwRule = NULL; | 800 | { |
| 801 | hr = pNetFwRule->put_Action(static_cast<NET_FW_ACTION> (attrs.iAction)); | ||
| 802 | ExitOnFailure(hr, "failed to set exception action"); | ||
| 803 | } | ||
| 804 | else if (fUpdateRule) | ||
| 805 | { | ||
| 806 | hr = pNetFwRule->put_Action(NET_FW_ACTION_ALLOW); | ||
| 807 | ExitOnFailure(hr, "failed to reset exception action to allow"); | ||
| 808 | } | ||
| 340 | 809 | ||
| 341 | LExit: | 810 | if (bstrFile && *bstrFile) |
| 342 | ReleaseBSTR(bstrRemoteAddresses); | 811 | { |
| 343 | ReleaseBSTR(bstrPort); | 812 | hr = pNetFwRule->put_ApplicationName(bstrFile); |
| 344 | ReleaseBSTR(bstrDescription); | 813 | ExitOnFailure(hr, "failed to set exception application name"); |
| 345 | ReleaseObject(pNetFwRule); | 814 | } |
| 815 | else if (fUpdateRule) | ||
| 816 | { | ||
| 817 | hr = pNetFwRule->put_ApplicationName(NULL); | ||
| 818 | ExitOnFailure(hr, "failed to remove exception application name"); | ||
| 819 | } | ||
| 346 | 820 | ||
| 347 | return hr; | 821 | if (MSI_NULL_INTEGER != attrs.iEdgeTraversal) |
| 348 | } | 822 | { |
| 823 | switch (attrs.iEdgeTraversal) | ||
| 824 | { | ||
| 825 | default: | ||
| 826 | hr = pNetFwRule->put_EdgeTraversal(NET_FW_EDGE_TRAVERSAL_TYPE_DENY != attrs.iEdgeTraversal ? VARIANT_TRUE : VARIANT_FALSE); | ||
| 827 | ExitOnFailure(hr, "failed to set exception edge traversal"); | ||
| 828 | break; | ||
| 349 | 829 | ||
| 350 | /****************************************************************** | 830 | // handled by put_EdgeTraversalOptions |
| 351 | AddApplicationException | 831 | case NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_APP: |
| 832 | case NET_FW_EDGE_TRAVERSAL_TYPE_DEFER_TO_USER: | ||
| 833 | break; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | else if (fUpdateRule) | ||
| 837 | { | ||
| 838 | hr = pNetFwRule->put_EdgeTraversal(VARIANT_FALSE); | ||
| 839 | ExitOnFailure(hr, "failed to remove exception edge traversal"); | ||
| 840 | } | ||
| 352 | 841 | ||
| 353 | ********************************************************************/ | 842 | // enable even when iEnabled == MSI_NULL_INTEGER |
| 354 | static HRESULT AddApplicationException( | 843 | hr = pNetFwRule->put_Enabled(attrs.iEnabled ? VARIANT_TRUE : VARIANT_FALSE); |
| 355 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs, | 844 | ExitOnFailure(hr, "failed to set exception enabled flag"); |
| 356 | __in BOOL fIgnoreFailures | ||
| 357 | ) | ||
| 358 | { | ||
| 359 | HRESULT hr = S_OK; | ||
| 360 | BSTR bstrFile = NULL; | ||
| 361 | BSTR bstrName = NULL; | ||
| 362 | INetFwRules* pNetFwRules = NULL; | ||
| 363 | INetFwRule* pNetFwRule = NULL; | ||
| 364 | 845 | ||
| 365 | // convert to BSTRs to make COM happy | 846 | if (bstrGrouping && *bstrGrouping) |
| 366 | bstrFile = ::SysAllocString(attrs.pwzProgram); | 847 | { |
| 367 | ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for path"); | 848 | hr = pNetFwRule->put_Grouping(bstrGrouping); |
| 368 | bstrName = ::SysAllocString(attrs.pwzName); | 849 | ExitOnFailure(hr, "failed to set exception grouping '%ls'", bstrGrouping); |
| 369 | ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name"); | 850 | } |
| 851 | else if (fUpdateRule) | ||
| 852 | { | ||
| 853 | hr = pNetFwRule->put_Grouping(bstrEmpty); | ||
| 854 | ExitOnFailure(hr, "failed to remove exception grouping"); | ||
| 855 | } | ||
| 370 | 856 | ||
| 371 | // get the collection of firewall rules | 857 | if (bstrIcmpTypesAndCodes && *bstrIcmpTypesAndCodes) |
| 372 | hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules); | ||
| 373 | ExitOnFailure(hr, "failed to get firewall rules object"); | ||
| 374 | if (S_FALSE == hr) // user or package author chose to ignore missing firewall | ||
| 375 | { | 858 | { |
| 376 | ExitFunction(); | 859 | hr = pNetFwRule->put_IcmpTypesAndCodes(bstrIcmpTypesAndCodes); |
| 860 | ExitOnFailure(hr, "failed to set exception icmp types and codes '%ls'", bstrIcmpTypesAndCodes); | ||
| 377 | } | 861 | } |
| 378 | 862 | ||
| 379 | // try to find it (i.e., support reinstall) | 863 | hr = GetFwRuleInterfaces(attrs, vInterfaces); |
| 380 | hr = pNetFwRules->Item(bstrName, &pNetFwRule); | 864 | ExitOnFailure(hr, "failed to prepare exception interfaces '%ls'", attrs.pwzInterfaces); |
| 381 | if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) | 865 | |
| 866 | if (attrs.pwzInterfaces && *attrs.pwzInterfaces) | ||
| 382 | { | 867 | { |
| 383 | hr = CreateFwRuleObject(bstrName, attrs, &pNetFwRule); | 868 | hr = pNetFwRule->put_Interfaces(vInterfaces); |
| 384 | ExitOnFailure(hr, "failed to create FwRule object"); | 869 | ExitOnFailure(hr, "failed to set exception interfaces '%ls'", attrs.pwzInterfaces); |
| 870 | } | ||
| 871 | else if (fUpdateRule) | ||
| 872 | { | ||
| 873 | hr = pNetFwRule->put_Interfaces(vInterfaces); | ||
| 874 | ExitOnFailure(hr, "failed to remove exception interfaces"); | ||
| 875 | } | ||
| 385 | 876 | ||
| 386 | // set edge traversal to true | 877 | if (bstrInterfaceTypes && *bstrInterfaceTypes) |
| 387 | hr = pNetFwRule->put_EdgeTraversal(VARIANT_TRUE); | 878 | { |
| 388 | ExitOnFailure(hr, "failed to set application exception edgetraversal property"); | 879 | hr = pNetFwRule->put_InterfaceTypes(bstrInterfaceTypes); |
| 389 | 880 | ExitOnFailure(hr, "failed to set exception interface types '%ls'", bstrInterfaceTypes); | |
| 390 | // set path | ||
| 391 | hr = pNetFwRule->put_ApplicationName(bstrFile); | ||
| 392 | ExitOnFailure(hr, "failed to set application name"); | ||
| 393 | |||
| 394 | // enable it | ||
| 395 | hr = pNetFwRule->put_Enabled(VARIANT_TRUE); | ||
| 396 | ExitOnFailure(hr, "failed to to enable application exception"); | ||
| 397 | |||
| 398 | // add it to the list of authorized apps | ||
| 399 | hr = pNetFwRules->Add(pNetFwRule); | ||
| 400 | ExitOnFailure(hr, "failed to add app to the authorized apps list"); | ||
| 401 | } | 881 | } |
| 402 | else | 882 | else if (fUpdateRule) |
| 403 | { | 883 | { |
| 404 | // we found an existing app exception (if we succeeded, that is) | 884 | hr = pNetFwRule->put_InterfaceTypes(bstrEmpty); |
| 405 | ExitOnFailure(hr, "failed trying to find existing app"); | 885 | ExitOnFailure(hr, "failed to remove exception interface types"); |
| 406 | 886 | } | |
| 407 | // enable it (just in case it was disabled) | 887 | |
| 408 | pNetFwRule->put_Enabled(VARIANT_TRUE); | 888 | if (bstrLocalAddresses && *bstrLocalAddresses) |
| 889 | { | ||
| 890 | hr = pNetFwRule->put_LocalAddresses(bstrLocalAddresses); | ||
| 891 | ExitOnFailure(hr, "failed to set exception local addresses '%ls'", bstrLocalAddresses); | ||
| 892 | } | ||
| 893 | else if (fUpdateRule) | ||
| 894 | { | ||
| 895 | hr = pNetFwRule->put_LocalAddresses(bstrEmpty); | ||
| 896 | ExitOnFailure(hr, "failed to remove exception local addresses"); | ||
| 897 | } | ||
| 898 | |||
| 899 | if (bstrRemotePort && *bstrRemotePort) | ||
| 900 | { | ||
| 901 | hr = pNetFwRule->put_RemotePorts(bstrRemotePort); | ||
| 902 | ExitOnFailure(hr, "failed to set exception remote ports '%ls'", bstrRemotePort); | ||
| 903 | } | ||
| 904 | |||
| 905 | if (bstrServiceName && *bstrServiceName) | ||
| 906 | { | ||
| 907 | hr = pNetFwRule->put_ServiceName(bstrServiceName); | ||
| 908 | ExitOnFailure(hr, "failed to set exception service name '%ls'", bstrServiceName); | ||
| 909 | } | ||
| 910 | else if (fUpdateRule) | ||
| 911 | { | ||
| 912 | hr = pNetFwRule->put_ServiceName(NULL); | ||
| 913 | ExitOnFailure(hr, "failed to remove exception service name"); | ||
| 409 | } | 914 | } |
| 410 | 915 | ||
| 411 | LExit: | 916 | LExit: |
| 412 | ReleaseBSTR(bstrName); | 917 | ReleaseBSTR(bstrRemoteAddresses); |
| 413 | ReleaseBSTR(bstrFile); | 918 | ReleaseBSTR(bstrFile); |
| 414 | ReleaseObject(pNetFwRules); | 919 | ReleaseBSTR(bstrPort); |
| 415 | ReleaseObject(pNetFwRule); | 920 | ReleaseBSTR(bstrDescription); |
| 921 | ReleaseBSTR(bstrGrouping); | ||
| 922 | ReleaseBSTR(bstrIcmpTypesAndCodes); | ||
| 923 | ReleaseBSTR(bstrInterfaceTypes); | ||
| 924 | ReleaseBSTR(bstrLocalAddresses); | ||
| 925 | ReleaseBSTR(bstrRemotePort); | ||
| 926 | ReleaseBSTR(bstrServiceName); | ||
| 927 | ReleaseVariant(vInterfaces); | ||
| 928 | ReleaseObject(pNetFwRule2); | ||
| 416 | 929 | ||
| 417 | return fIgnoreFailures ? S_OK : hr; | 930 | return hr; |
| 418 | } | 931 | } |
| 419 | 932 | ||
| 420 | /****************************************************************** | 933 | |
| 421 | AddPortException | 934 | /******************************************************************* |
| 935 | AddFirewallException | ||
| 422 | 936 | ||
| 423 | ********************************************************************/ | 937 | ********************************************************************/ |
| 424 | static HRESULT AddPortException( | 938 | static HRESULT AddFirewallException( |
| 425 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs, | 939 | __in FIREWALL_EXCEPTION_ATTRIBUTES const& attrs, |
| 426 | __in BOOL fIgnoreFailures | 940 | __in BOOL fIgnoreFailures |
| 427 | ) | 941 | ) |
| 428 | { | 942 | { |
| 429 | HRESULT hr = S_OK; | 943 | HRESULT hr = S_OK; |
| 430 | BSTR bstrName = NULL; | 944 | BSTR bstrName = NULL; |
| 431 | INetFwRules* pNetFwRules = NULL; | 945 | INetFwRules* pNetFwRules = NULL; |
| 432 | INetFwRule* pNetFwRule = NULL; | 946 | INetFwRule* pNetFwRule = NULL; |
| 433 | 947 | ||
| 948 | BOOL fIgnoreUpdates = feaIgnoreUpdates == (attrs.iAttributes & feaIgnoreUpdates); | ||
| 949 | BOOL fEnableOnUpdate = feaEnableOnUpdate == (attrs.iAttributes & feaEnableOnUpdate); | ||
| 950 | BOOL fAddINetFwRule2 = feaAddINetFwRule2 == (attrs.iAttributes & feaAddINetFwRule2); | ||
| 951 | BOOL fAddINetFwRule3 = feaAddINetFwRule3 == (attrs.iAttributes & feaAddINetFwRule3); | ||
| 952 | |||
| 434 | // convert to BSTRs to make COM happy | 953 | // convert to BSTRs to make COM happy |
| 435 | bstrName = ::SysAllocString(attrs.pwzName); | 954 | bstrName = ::SysAllocString(attrs.pwzName); |
| 436 | ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name"); | 955 | ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name"); |
| 437 | 956 | ||
| 438 | // get the collection of firewall rules | 957 | // get the collection of firewall rules |
| 439 | hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules); | 958 | hr = GetFirewallRules(fIgnoreFailures, &pNetFwRules); |
| 440 | ExitOnFailure(hr, "failed to get firewall rules object"); | 959 | ExitOnFailure(hr, "failed to get firewall exception object"); |
| 441 | if (S_FALSE == hr) // user or package author chose to ignore missing firewall | 960 | if (S_FALSE == hr) // user or package author chose to ignore missing firewall |
| 442 | { | 961 | { |
| 443 | ExitFunction(); | 962 | ExitFunction(); |
| @@ -447,24 +966,56 @@ static HRESULT AddPortException( | |||
| 447 | hr = pNetFwRules->Item(bstrName, &pNetFwRule); | 966 | hr = pNetFwRules->Item(bstrName, &pNetFwRule); |
| 448 | if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) | 967 | if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) |
| 449 | { | 968 | { |
| 450 | hr = CreateFwRuleObject(bstrName, attrs, &pNetFwRule); | 969 | hr = CreateFwRuleObject(bstrName, &pNetFwRule); |
| 451 | ExitOnFailure(hr, "failed to create FwRule object"); | 970 | ExitOnFailure(hr, "failed to create FwRule object '%ls'", attrs.pwzName); |
| 452 | 971 | ||
| 453 | // enable it | 972 | // set attributes of the new firewall rule |
| 454 | hr = pNetFwRule->put_Enabled(VARIANT_TRUE); | 973 | hr = UpdateFwRuleObject(pNetFwRule, FALSE, attrs); |
| 455 | ExitOnFailure(hr, "failed to to enable port exception"); | 974 | ExitOnFailure(hr, "failed to create INetFwRule firewall exception '%ls'", attrs.pwzName); |
| 975 | |||
| 976 | if (fAddINetFwRule2) | ||
| 977 | { | ||
| 978 | hr = UpdateFwRule2Object(pNetFwRule, FALSE, attrs); | ||
| 979 | ExitOnFailure(hr, "failed to create INetFwRule2 firewall exception '%ls'", attrs.pwzName); | ||
| 980 | } | ||
| 981 | |||
| 982 | if (fAddINetFwRule3) | ||
| 983 | { | ||
| 984 | hr = UpdateFwRule3Object(pNetFwRule, FALSE, attrs); | ||
| 985 | ExitOnFailure(hr, "failed to create INetFwRule3 firewall exception '%ls'", attrs.pwzName); | ||
| 986 | } | ||
| 456 | 987 | ||
| 457 | // add it to the list of authorized ports | ||
| 458 | hr = pNetFwRules->Add(pNetFwRule); | 988 | hr = pNetFwRules->Add(pNetFwRule); |
| 459 | ExitOnFailure(hr, "failed to add app to the authorized ports list"); | 989 | ExitOnFailure(hr, "failed to add firewall exception '%ls' to the list", attrs.pwzName); |
| 460 | } | 990 | } |
| 461 | else | 991 | else |
| 462 | { | 992 | { |
| 463 | // we found an existing port exception (if we succeeded, that is) | 993 | // we found an existing firewall rule (if we succeeded, that is) |
| 464 | ExitOnFailure(hr, "failed trying to find existing port rule"); | 994 | ExitOnFailure(hr, "failed trying to find existing firewall exception '%ls'", attrs.pwzName); |
| 995 | |||
| 996 | if (fEnableOnUpdate) | ||
| 997 | { | ||
| 998 | hr = pNetFwRule->put_Enabled(VARIANT_TRUE); | ||
| 999 | ExitOnFailure(hr, "failed to enable existing firewall exception '%ls'", attrs.pwzName); | ||
| 1000 | } | ||
| 1001 | else if (!fIgnoreUpdates) | ||
| 1002 | { | ||
| 1003 | // overwrite attributes of the existing firewall rule | ||
| 1004 | hr = UpdateFwRuleObject(pNetFwRule, TRUE, attrs); | ||
| 1005 | ExitOnFailure(hr, "failed to update INetFwRule firewall exception '%ls'", attrs.pwzName); | ||
| 465 | 1006 | ||
| 466 | // enable it (just in case it was disabled) | 1007 | if (fAddINetFwRule2) |
| 467 | pNetFwRule->put_Enabled(VARIANT_TRUE); | 1008 | { |
| 1009 | hr = UpdateFwRule2Object(pNetFwRule, TRUE, attrs); | ||
| 1010 | ExitOnFailure(hr, "failed to update INetFwRule2 firewall exception '%ls'", attrs.pwzName); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | if (fAddINetFwRule3) | ||
| 1014 | { | ||
| 1015 | hr = UpdateFwRule3Object(pNetFwRule, TRUE, attrs); | ||
| 1016 | ExitOnFailure(hr, "failed to update INetFwRule3 firewall exception '%ls'", attrs.pwzName); | ||
| 1017 | } | ||
| 1018 | } | ||
| 468 | } | 1019 | } |
| 469 | 1020 | ||
| 470 | LExit: | 1021 | LExit: |
| @@ -475,14 +1026,15 @@ LExit: | |||
| 475 | return fIgnoreFailures ? S_OK : hr; | 1026 | return fIgnoreFailures ? S_OK : hr; |
| 476 | } | 1027 | } |
| 477 | 1028 | ||
| 478 | /****************************************************************** | 1029 | |
| 1030 | /******************************************************************* | ||
| 479 | RemoveException - Removes all exception rules with the given name. | 1031 | RemoveException - Removes all exception rules with the given name. |
| 480 | 1032 | ||
| 481 | ********************************************************************/ | 1033 | ********************************************************************/ |
| 482 | static HRESULT RemoveException( | 1034 | static HRESULT RemoveException( |
| 483 | __in LPCWSTR wzName, | 1035 | __in LPCWSTR wzName, |
| 484 | __in BOOL fIgnoreFailures | 1036 | __in BOOL fIgnoreFailures |
| 485 | ) | 1037 | ) |
| 486 | { | 1038 | { |
| 487 | HRESULT hr = S_OK;; | 1039 | HRESULT hr = S_OK;; |
| 488 | INetFwRules* pNetFwRules = NULL; | 1040 | INetFwRules* pNetFwRules = NULL; |
| @@ -500,7 +1052,7 @@ static HRESULT RemoveException( | |||
| 500 | } | 1052 | } |
| 501 | 1053 | ||
| 502 | hr = pNetFwRules->Remove(bstrName); | 1054 | hr = pNetFwRules->Remove(bstrName); |
| 503 | ExitOnFailure(hr, "failed to remove firewall rule"); | 1055 | ExitOnFailure(hr, "failed to remove firewall exception for name %ls", wzName); |
| 504 | 1056 | ||
| 505 | LExit: | 1057 | LExit: |
| 506 | ReleaseBSTR(bstrName); | 1058 | ReleaseBSTR(bstrName); |
| @@ -509,20 +1061,20 @@ LExit: | |||
| 509 | return fIgnoreFailures ? S_OK : hr; | 1061 | return fIgnoreFailures ? S_OK : hr; |
| 510 | } | 1062 | } |
| 511 | 1063 | ||
| 512 | /****************************************************************** | 1064 | |
| 513 | ExecFirewallExceptions - deferred custom action entry point to | 1065 | /******************************************************************* |
| 1066 | ExecFirewallExceptions - deferred custom action entry point to | ||
| 514 | register and remove firewall exceptions. | 1067 | register and remove firewall exceptions. |
| 515 | 1068 | ||
| 516 | ********************************************************************/ | 1069 | ********************************************************************/ |
| 517 | extern "C" UINT __stdcall ExecFirewallExceptions( | 1070 | extern "C" UINT __stdcall ExecFirewallExceptions( |
| 518 | __in MSIHANDLE hInstall | 1071 | __in MSIHANDLE hInstall |
| 519 | ) | 1072 | ) |
| 520 | { | 1073 | { |
| 521 | HRESULT hr = S_OK; | 1074 | HRESULT hr = S_OK; |
| 522 | LPWSTR pwz = NULL; | 1075 | LPWSTR pwz = NULL; |
| 523 | LPWSTR pwzCustomActionData = NULL; | 1076 | LPWSTR pwzCustomActionData = NULL; |
| 524 | int iTodo = WCA_TODO_UNKNOWN; | 1077 | int iTodo = WCA_TODO_UNKNOWN; |
| 525 | int iTarget = fetUnknown; | ||
| 526 | 1078 | ||
| 527 | FIREWALL_EXCEPTION_ATTRIBUTES attrs = { 0 }; | 1079 | FIREWALL_EXCEPTION_ATTRIBUTES attrs = { 0 }; |
| 528 | 1080 | ||
| @@ -530,7 +1082,7 @@ extern "C" UINT __stdcall ExecFirewallExceptions( | |||
| 530 | hr = WcaInitialize(hInstall, "ExecFirewallExceptions"); | 1082 | hr = WcaInitialize(hInstall, "ExecFirewallExceptions"); |
| 531 | ExitOnFailure(hr, "failed to initialize"); | 1083 | ExitOnFailure(hr, "failed to initialize"); |
| 532 | 1084 | ||
| 533 | hr = WcaGetProperty( L"CustomActionData", &pwzCustomActionData); | 1085 | hr = WcaGetProperty(L"CustomActionData", &pwzCustomActionData); |
| 534 | ExitOnFailure(hr, "failed to get CustomActionData"); | 1086 | ExitOnFailure(hr, "failed to get CustomActionData"); |
| 535 | WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCustomActionData); | 1087 | WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCustomActionData); |
| 536 | 1088 | ||
| @@ -569,60 +1121,82 @@ extern "C" UINT __stdcall ExecFirewallExceptions( | |||
| 569 | ExitOnFailure(hr, "failed to read attributes from custom action data"); | 1121 | ExitOnFailure(hr, "failed to read attributes from custom action data"); |
| 570 | BOOL fIgnoreFailures = feaIgnoreFailures == (attrs.iAttributes & feaIgnoreFailures); | 1122 | BOOL fIgnoreFailures = feaIgnoreFailures == (attrs.iAttributes & feaIgnoreFailures); |
| 571 | 1123 | ||
| 572 | hr = WcaReadIntegerFromCaData(&pwz, &iTarget); | 1124 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzApplicationName); |
| 573 | ExitOnFailure(hr, "failed to read target from custom action data"); | 1125 | ExitOnFailure(hr, "failed to read file path from custom action data"); |
| 574 | 1126 | ||
| 575 | if (iTarget == fetApplication) | 1127 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalPorts); |
| 576 | { | ||
| 577 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzProgram); | ||
| 578 | ExitOnFailure(hr, "failed to read file path from custom action data"); | ||
| 579 | } | ||
| 580 | |||
| 581 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzPort); | ||
| 582 | ExitOnFailure(hr, "failed to read port from custom action data"); | 1128 | ExitOnFailure(hr, "failed to read port from custom action data"); |
| 1129 | |||
| 583 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iProtocol); | 1130 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iProtocol); |
| 584 | ExitOnFailure(hr, "failed to read protocol from custom action data"); | 1131 | ExitOnFailure(hr, "failed to read protocol from custom action data"); |
| 1132 | |||
| 585 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzDescription); | 1133 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzDescription); |
| 586 | ExitOnFailure(hr, "failed to read protocol from custom action data"); | 1134 | ExitOnFailure(hr, "failed to read protocol from custom action data"); |
| 1135 | |||
| 587 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iDirection); | 1136 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iDirection); |
| 588 | ExitOnFailure(hr, "failed to read direction from custom action data"); | 1137 | ExitOnFailure(hr, "failed to read direction from custom action data"); |
| 589 | 1138 | ||
| 590 | switch (iTarget) | 1139 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iAction); |
| 591 | { | 1140 | ExitOnFailure(hr, "failed to read action from custom action data"); |
| 592 | case fetPort: | ||
| 593 | switch (iTodo) | ||
| 594 | { | ||
| 595 | case WCA_TODO_INSTALL: | ||
| 596 | case WCA_TODO_REINSTALL: | ||
| 597 | WcaLog(LOGMSG_STANDARD, "Installing firewall exception %ls on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol); | ||
| 598 | hr = AddPortException(attrs, fIgnoreFailures); | ||
| 599 | ExitOnFailure(hr, "failed to add/update port exception for name '%ls' on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol); | ||
| 600 | break; | ||
| 601 | 1141 | ||
| 602 | case WCA_TODO_UNINSTALL: | 1142 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iEdgeTraversal); |
| 603 | WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception %ls on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol); | 1143 | ExitOnFailure(hr, "failed to read edge traversal from custom action data"); |
| 604 | hr = RemoveException(attrs.pwzName, fIgnoreFailures); | ||
| 605 | ExitOnFailure(hr, "failed to remove port exception for name '%ls' on port %ls, protocol %d", attrs.pwzName, attrs.pwzPort, attrs.iProtocol); | ||
| 606 | break; | ||
| 607 | } | ||
| 608 | break; | ||
| 609 | 1144 | ||
| 610 | case fetApplication: | 1145 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iEnabled); |
| 611 | switch (iTodo) | 1146 | ExitOnFailure(hr, "failed to read enabled flag from custom action data"); |
| 612 | { | ||
| 613 | case WCA_TODO_INSTALL: | ||
| 614 | case WCA_TODO_REINSTALL: | ||
| 615 | WcaLog(LOGMSG_STANDARD, "Installing firewall exception %ls (%ls)", attrs.pwzName, attrs.pwzProgram); | ||
| 616 | hr = AddApplicationException(attrs, fIgnoreFailures); | ||
| 617 | ExitOnFailure(hr, "failed to add/update application exception for name '%ls', file '%ls'", attrs.pwzName, attrs.pwzProgram); | ||
| 618 | break; | ||
| 619 | 1147 | ||
| 620 | case WCA_TODO_UNINSTALL: | 1148 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzGrouping); |
| 621 | WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception %ls (%ls)", attrs.pwzName, attrs.pwzProgram); | 1149 | ExitOnFailure(hr, "failed to read grouping from custom action data"); |
| 622 | hr = RemoveException(attrs.pwzName, fIgnoreFailures); | 1150 | |
| 623 | ExitOnFailure(hr, "failed to remove application exception for name '%ls', file '%ls'", attrs.pwzName, attrs.pwzProgram); | 1151 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzIcmpTypesAndCodes); |
| 624 | break; | 1152 | ExitOnFailure(hr, "failed to read icmp types and codes from custom action data"); |
| 625 | } | 1153 | |
| 1154 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzInterfaces); | ||
| 1155 | ExitOnFailure(hr, "failed to read interfaces from custom action data"); | ||
| 1156 | |||
| 1157 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzInterfaceTypes); | ||
| 1158 | ExitOnFailure(hr, "failed to read interface types from custom action data"); | ||
| 1159 | |||
| 1160 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalAddresses); | ||
| 1161 | ExitOnFailure(hr, "failed to read local addresses from custom action data"); | ||
| 1162 | |||
| 1163 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzRemotePorts); | ||
| 1164 | ExitOnFailure(hr, "failed to read remote port from custom action data"); | ||
| 1165 | |||
| 1166 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzServiceName); | ||
| 1167 | ExitOnFailure(hr, "failed to read service name from custom action data"); | ||
| 1168 | |||
| 1169 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalAppPackageId); | ||
| 1170 | ExitOnFailure(hr, "failed to read local app package id from custom action data"); | ||
| 1171 | |||
| 1172 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalUserAuthorizedList); | ||
| 1173 | ExitOnFailure(hr, "failed to read local user authorized list from custom action data"); | ||
| 1174 | |||
| 1175 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzLocalUserOwner); | ||
| 1176 | ExitOnFailure(hr, "failed to read local user owner from custom action data"); | ||
| 1177 | |||
| 1178 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzRemoteMachineAuthorizedList); | ||
| 1179 | ExitOnFailure(hr, "failed to read remote machine authorized list from custom action data"); | ||
| 1180 | |||
| 1181 | hr = WcaReadStringFromCaData(&pwz, &attrs.pwzRemoteUserAuthorizedList); | ||
| 1182 | ExitOnFailure(hr, "failed to read remote user authorized list from custom action data"); | ||
| 1183 | |||
| 1184 | hr = WcaReadIntegerFromCaData(&pwz, &attrs.iSecureFlags); | ||
| 1185 | ExitOnFailure(hr, "failed to read exception secure flags from custom action data"); | ||
| 1186 | |||
| 1187 | switch (iTodo) | ||
| 1188 | { | ||
| 1189 | case WCA_TODO_INSTALL: | ||
| 1190 | case WCA_TODO_REINSTALL: | ||
| 1191 | WcaLog(LOGMSG_STANDARD, "Installing firewall exception %ls", attrs.pwzName); | ||
| 1192 | hr = AddFirewallException(attrs, fIgnoreFailures); | ||
| 1193 | ExitOnFailure(hr, "failed to add/update firewall exception for name '%ls'", attrs.pwzName); | ||
| 1194 | break; | ||
| 1195 | |||
| 1196 | case WCA_TODO_UNINSTALL: | ||
| 1197 | WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception %ls", attrs.pwzName); | ||
| 1198 | hr = RemoveException(attrs.pwzName, fIgnoreFailures); | ||
| 1199 | ExitOnFailure(hr, "failed to remove firewall exception"); | ||
| 626 | break; | 1200 | break; |
| 627 | } | 1201 | } |
| 628 | } | 1202 | } |
| @@ -631,9 +1205,21 @@ LExit: | |||
| 631 | ReleaseStr(pwzCustomActionData); | 1205 | ReleaseStr(pwzCustomActionData); |
| 632 | ReleaseStr(attrs.pwzName); | 1206 | ReleaseStr(attrs.pwzName); |
| 633 | ReleaseStr(attrs.pwzRemoteAddresses); | 1207 | ReleaseStr(attrs.pwzRemoteAddresses); |
| 634 | ReleaseStr(attrs.pwzProgram); | 1208 | ReleaseStr(attrs.pwzApplicationName); |
| 635 | ReleaseStr(attrs.pwzPort); | 1209 | ReleaseStr(attrs.pwzLocalPorts); |
| 636 | ReleaseStr(attrs.pwzDescription); | 1210 | ReleaseStr(attrs.pwzDescription); |
| 1211 | ReleaseStr(attrs.pwzGrouping); | ||
| 1212 | ReleaseStr(attrs.pwzIcmpTypesAndCodes); | ||
| 1213 | ReleaseStr(attrs.pwzInterfaces); | ||
| 1214 | ReleaseStr(attrs.pwzInterfaceTypes); | ||
| 1215 | ReleaseStr(attrs.pwzLocalAddresses); | ||
| 1216 | ReleaseStr(attrs.pwzRemotePorts); | ||
| 1217 | ReleaseStr(attrs.pwzServiceName); | ||
| 1218 | ReleaseStr(attrs.pwzLocalAppPackageId); | ||
| 1219 | ReleaseStr(attrs.pwzLocalUserAuthorizedList); | ||
| 1220 | ReleaseStr(attrs.pwzLocalUserOwner); | ||
| 1221 | ReleaseStr(attrs.pwzRemoteMachineAuthorizedList); | ||
| 1222 | ReleaseStr(attrs.pwzRemoteUserAuthorizedList); | ||
| 637 | ::CoUninitialize(); | 1223 | ::CoUninitialize(); |
| 638 | 1224 | ||
| 639 | return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); | 1225 | return WcaFinalize(FAILED(hr) ? ERROR_INSTALL_FAILURE : ERROR_SUCCESS); |
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs b/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs index 7119e92d..df18f0e0 100644 --- a/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs +++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | namespace WixToolsetTest.Firewall | 3 | namespace WixToolsetTest.Firewall |
| 4 | { | 4 | { |
| 5 | using System.Data; | ||
| 5 | using System.IO; | 6 | using System.IO; |
| 6 | using System.Linq; | 7 | using System.Linq; |
| 7 | using System.Xml.Linq; | 8 | using System.Xml.Linq; |
| @@ -27,12 +28,27 @@ namespace WixToolsetTest.Firewall | |||
| 27 | "CustomAction:Wix5RollbackFirewallExceptionsUninstall_X86\t3329\tWix5FWCA_X86\tExecFirewallExceptions\t", | 28 | "CustomAction:Wix5RollbackFirewallExceptionsUninstall_X86\t3329\tWix5FWCA_X86\tExecFirewallExceptions\t", |
| 28 | "CustomAction:Wix5SchedFirewallExceptionsInstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsInstall\t", | 29 | "CustomAction:Wix5SchedFirewallExceptionsInstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsInstall\t", |
| 29 | "CustomAction:Wix5SchedFirewallExceptionsUninstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsUninstall\t", | 30 | "CustomAction:Wix5SchedFirewallExceptionsUninstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsUninstall\t", |
| 30 | "Wix5FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1", | 31 | "Wix5FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t2\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 31 | "Wix5FirewallException:fex_ZpDsnKyHlYiA24JHzvFxm3uLZ8\tExampleDefaultGatewayScope\tDefaultGateway\t4432\t6\t\t0\t2\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tdefaultGateway scope firewall exception\t1", | 32 | "Wix5FirewallException:fex.BGtyMRGAhxb2hG.49JvWYz7fM0\tLocalScopeExample2\t*\t\t-2147483648\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with local scope property\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t[LOCALSCOPE_PROP]\t\t\t\t\t\t\t\t-2147483648", |
| 32 | "Wix5FirewallException:fex6bkfWwpiRGI.wVFx0T7W4LXIHxU\tExampleDHCPScope\tdhcp\t\t211\ttest.exe\t0\t4\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDHCP scope firewall exception\t1", | 33 | "Wix5FirewallException:fex0HTxATWjpC2PCoY6DB7f2D1WaKU\tLocalScopeExample1\t*\t\t-2147483648\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple rule with local scope\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\tLocalSubnet\t\t\t\t\t\t\t\t-2147483648", |
| 33 | "Wix5FirewallException:fex70IVsYNnbwiHQrEepmdTPKH8XYs\tExamplePort\tLocalSubnet\t42\t6\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2", | 34 | "Wix5FirewallException:fex4FeP470wYcFpw.g7fbIKiLnZPzg\tExampleDNSScope\tdns\t356\t17\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDNS scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 34 | "Wix5FirewallException:fexXxaXCXXFh.UxO_BjmZxi1B1du_Q\tExampleWINSScope\twins\t6573\t6\t\t0\t1\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tWINS scope firewall exception\t1", | 35 | "Wix5FirewallException:fex4zTcT0Iwu3dUtHIHXD5qfymvpcM\tdefertouser\t\t\t-2147483648\tfw.exe\t8\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDefer to user edge traversal\t1\t-2147483648\t3\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 35 | "Wix5FirewallException:fexxY71H2ZBkPalv7uid1Yy4qaA_lA\tExampleDNSScope\tdns\t356\t17\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDNS scope firewall exception\t1", | 36 | "Wix5FirewallException:fex8vMfBplrod4daEz3PqDTeX6olGE\tExampleDefaultGatewayScope\tDefaultGateway\t4432\t6\t\t0\t2\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tdefaultGateway scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 37 | "Wix5FirewallException:fexAMmHzFDyQmubTOnKS1Cn0Y3q_Ug\tINetFwRule3 properties\t*\t\t-2147483648\t\t16\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tINetFwRule3 passed via properties\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t[PROP1]\t[PROP2]\t[PROP3]\t[PROP4]\t[PROP5]\t[PROP6]", | ||
| 38 | "Wix5FirewallException:fexArlOkFR7CAwVZ2wk8yNdiREydu0\tRemotePortExample2\t\t\t6\tfw.exe\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with remote port property\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t[REMOTEPORT_PROP]\t\t\t\t\t\t\t-2147483648", | ||
| 39 | "Wix5FirewallException:fexaUTe2tRRcSYrPUTn44DAZhE.40Q\tExamplePort\tLocalSubnet\t42\t6\t\t4\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 40 | "Wix5FirewallException:fexD6w20c5HfNi4l1vHFj_eet4cC8I\tExampleWINSScope\twins\t6573\t6\t\t0\t1\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tWINS scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 41 | "Wix5FirewallException:fexeD3yox6fMflfRy7sDwSN2CMCS2s\tExampleService\t\t12000\t6\t%windir%\\system32\\svchost.exe\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based service exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\tDHCP,WINS\t\tftpsrv\t\t\t\t\t\t-2147483648", | ||
| 42 | "Wix5FirewallException:fexeok6aI2_AlclZggec4d8PBLFXLw\tinterface property\t\t54671\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tInterfaces with property\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t[INTERFACE_PROPERTY]\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 43 | "Wix5FirewallException:fexEPvcf4iexD1mVQdvxm7tD02nZEc\tICMPExample1\t\t\t2\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple ICMP rule\t1\t-2147483648\t-2147483648\t-2147483648\t\t4:*,9:*,12:*\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 44 | "Wix5FirewallException:fexfzjTQsWwZkHQpObtl0XaUosfcRk\tGroupingExample1\t\t\t-2147483648\tfw.exe\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple rule with grouping\t1\t-2147483648\t-2147483648\t-2147483648\t@yourresources.dll,-1005\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 45 | "Wix5FirewallException:fexHx2xbwZYzAi0oYp4YGWevJQs5eM\tRemotePortExample1\t*\t\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple rule with remote port\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t34560\t\t\t\t\t\t\t-2147483648", | ||
| 46 | "Wix5FirewallException:fexpWUzK53RVnaluW36gSmphPRY8VY\tExampleDHCPScope\tdhcp\t\t211\ttest.exe\t0\t4\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDHCP scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 47 | "Wix5FirewallException:fexuanTga5xaaFzr9JsAnUmpCNediw\tICMPExample2\t\t\t2\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with ICMP property\t1\t-2147483648\t-2147483648\t-2147483648\t\t[ICMP_PROP]\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 48 | "Wix5FirewallException:fexv60s7u2Dmd1imH5vEFYKPgEWhG4\tinterface nested\t127.0.0.1\t54671\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tInterfaces with nested elements\t1\t-2147483648\t-2147483648\t-2147483648\t\t\tWi-Fi|Local Area Connection\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 49 | "Wix5FirewallException:fexVr6uHcOCak5MHuTLwujjh_oKtbI\tGroupingExample2\t\t8732\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with grouping property\t1\t-2147483648\t-2147483648\t-2147483648\t[GROUPING_PROP]\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 50 | "Wix5FirewallException:fexwjf4OTFVE9SNiC4goVxBA6ENJBE\tINetFwRule3 values\t*\t\t-2147483648\t\t16\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple INetFwRule3 values\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\tS-1-15-2-1239072475-3687740317-1842961305-3395936705-4023953123-1525404051-2779347315\tO:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)\tS-1-5-21-1898747406-2352535518-1247798438-1914\t127.0.0.1\tO:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)\t3", | ||
| 51 | "Wix5FirewallException:ServiceInstall.nested\tExampleNestedService\tLocalSubnet\t3546-7890\t6\t\t1\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception for a windows service\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\tLan,Wireless\t\t\tsvc1\t\t\t\t\t\t-2147483648", | ||
| 36 | }, results); | 52 | }, results); |
| 37 | } | 53 | } |
| 38 | 54 | ||
| @@ -51,12 +67,69 @@ namespace WixToolsetTest.Firewall | |||
| 51 | "CustomAction:Wix5RollbackFirewallExceptionsUninstall_A64\t3329\tWix5FWCA_A64\tExecFirewallExceptions\t", | 67 | "CustomAction:Wix5RollbackFirewallExceptionsUninstall_A64\t3329\tWix5FWCA_A64\tExecFirewallExceptions\t", |
| 52 | "CustomAction:Wix5SchedFirewallExceptionsInstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsInstall\t", | 68 | "CustomAction:Wix5SchedFirewallExceptionsInstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsInstall\t", |
| 53 | "CustomAction:Wix5SchedFirewallExceptionsUninstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsUninstall\t", | 69 | "CustomAction:Wix5SchedFirewallExceptionsUninstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsUninstall\t", |
| 54 | "Wix5FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1", | 70 | "Wix5FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t2\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 55 | "Wix5FirewallException:fex_ZpDsnKyHlYiA24JHzvFxm3uLZ8\tExampleDefaultGatewayScope\tDefaultGateway\t4432\t6\t\t0\t2\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tdefaultGateway scope firewall exception\t1", | 71 | "Wix5FirewallException:fex.BGtyMRGAhxb2hG.49JvWYz7fM0\tLocalScopeExample2\t*\t\t-2147483648\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with local scope property\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t[LOCALSCOPE_PROP]\t\t\t\t\t\t\t\t-2147483648", |
| 56 | "Wix5FirewallException:fex6bkfWwpiRGI.wVFx0T7W4LXIHxU\tExampleDHCPScope\tdhcp\t\t211\ttest.exe\t0\t4\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDHCP scope firewall exception\t1", | 72 | "Wix5FirewallException:fex0HTxATWjpC2PCoY6DB7f2D1WaKU\tLocalScopeExample1\t*\t\t-2147483648\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple rule with local scope\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\tLocalSubnet\t\t\t\t\t\t\t\t-2147483648", |
| 57 | "Wix5FirewallException:fex70IVsYNnbwiHQrEepmdTPKH8XYs\tExamplePort\tLocalSubnet\t42\t6\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2", | 73 | "Wix5FirewallException:fex4FeP470wYcFpw.g7fbIKiLnZPzg\tExampleDNSScope\tdns\t356\t17\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDNS scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 58 | "Wix5FirewallException:fexXxaXCXXFh.UxO_BjmZxi1B1du_Q\tExampleWINSScope\twins\t6573\t6\t\t0\t1\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tWINS scope firewall exception\t1", | 74 | "Wix5FirewallException:fex4zTcT0Iwu3dUtHIHXD5qfymvpcM\tdefertouser\t\t\t-2147483648\tfw.exe\t8\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDefer to user edge traversal\t1\t-2147483648\t3\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 59 | "Wix5FirewallException:fexxY71H2ZBkPalv7uid1Yy4qaA_lA\tExampleDNSScope\tdns\t356\t17\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDNS scope firewall exception\t1", | 75 | "Wix5FirewallException:fex8vMfBplrod4daEz3PqDTeX6olGE\tExampleDefaultGatewayScope\tDefaultGateway\t4432\t6\t\t0\t2\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tdefaultGateway scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", |
| 76 | "Wix5FirewallException:fexAMmHzFDyQmubTOnKS1Cn0Y3q_Ug\tINetFwRule3 properties\t*\t\t-2147483648\t\t16\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tINetFwRule3 passed via properties\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t[PROP1]\t[PROP2]\t[PROP3]\t[PROP4]\t[PROP5]\t[PROP6]", | ||
| 77 | "Wix5FirewallException:fexArlOkFR7CAwVZ2wk8yNdiREydu0\tRemotePortExample2\t\t\t6\tfw.exe\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with remote port property\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t[REMOTEPORT_PROP]\t\t\t\t\t\t\t-2147483648", | ||
| 78 | "Wix5FirewallException:fexaUTe2tRRcSYrPUTn44DAZhE.40Q\tExamplePort\tLocalSubnet\t42\t6\t\t4\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 79 | "Wix5FirewallException:fexD6w20c5HfNi4l1vHFj_eet4cC8I\tExampleWINSScope\twins\t6573\t6\t\t0\t1\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tWINS scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 80 | "Wix5FirewallException:fexeD3yox6fMflfRy7sDwSN2CMCS2s\tExampleService\t\t12000\t6\t%windir%\\system32\\svchost.exe\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based service exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\tDHCP,WINS\t\tftpsrv\t\t\t\t\t\t-2147483648", | ||
| 81 | "Wix5FirewallException:fexeok6aI2_AlclZggec4d8PBLFXLw\tinterface property\t\t54671\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tInterfaces with property\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t[INTERFACE_PROPERTY]\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 82 | "Wix5FirewallException:fexEPvcf4iexD1mVQdvxm7tD02nZEc\tICMPExample1\t\t\t2\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple ICMP rule\t1\t-2147483648\t-2147483648\t-2147483648\t\t4:*,9:*,12:*\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 83 | "Wix5FirewallException:fexfzjTQsWwZkHQpObtl0XaUosfcRk\tGroupingExample1\t\t\t-2147483648\tfw.exe\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple rule with grouping\t1\t-2147483648\t-2147483648\t-2147483648\t@yourresources.dll,-1005\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 84 | "Wix5FirewallException:fexHx2xbwZYzAi0oYp4YGWevJQs5eM\tRemotePortExample1\t*\t\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple rule with remote port\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t34560\t\t\t\t\t\t\t-2147483648", | ||
| 85 | "Wix5FirewallException:fexpWUzK53RVnaluW36gSmphPRY8VY\tExampleDHCPScope\tdhcp\t\t211\ttest.exe\t0\t4\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDHCP scope firewall exception\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 86 | "Wix5FirewallException:fexuanTga5xaaFzr9JsAnUmpCNediw\tICMPExample2\t\t\t2\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with ICMP property\t1\t-2147483648\t-2147483648\t-2147483648\t\t[ICMP_PROP]\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 87 | "Wix5FirewallException:fexv60s7u2Dmd1imH5vEFYKPgEWhG4\tinterface nested\t127.0.0.1\t54671\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tInterfaces with nested elements\t1\t-2147483648\t-2147483648\t-2147483648\t\t\tWi-Fi|Local Area Connection\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 88 | "Wix5FirewallException:fexVr6uHcOCak5MHuTLwujjh_oKtbI\tGroupingExample2\t\t8732\t6\t\t0\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tRule with grouping property\t1\t-2147483648\t-2147483648\t-2147483648\t[GROUPING_PROP]\t\t\t\t\t\t\t\t\t\t\t\t-2147483648", | ||
| 89 | "Wix5FirewallException:fexwjf4OTFVE9SNiC4goVxBA6ENJBE\tINetFwRule3 values\t*\t\t-2147483648\t\t16\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tSimple INetFwRule3 values\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\t\t\t\t\tS-1-15-2-1239072475-3687740317-1842961305-3395936705-4023953123-1525404051-2779347315\tO:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)\tS-1-5-21-1898747406-2352535518-1247798438-1914\t127.0.0.1\tO:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)\t3", | ||
| 90 | "Wix5FirewallException:ServiceInstall.nested\tExampleNestedService\tLocalSubnet\t3546-7890\t6\t\t1\t-2147483648\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception for a windows service\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t\tLan,Wireless\t\t\tsvc1\t\t\t\t\t\t-2147483648", | ||
| 91 | }, results); | ||
| 92 | } | ||
| 93 | |||
| 94 | [Fact] | ||
| 95 | public void CanBuildWithProperties() | ||
| 96 | { | ||
| 97 | var folder = TestData.Get(@"TestData\UsingProperties"); | ||
| 98 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); | ||
| 99 | |||
| 100 | var results = build.BuildAndQuery(Build, "Wix5FirewallException", "CustomAction"); | ||
| 101 | WixAssert.CompareLineByLine(new[] | ||
| 102 | { | ||
| 103 | "CustomAction:Wix5ExecFirewallExceptionsInstall_X86\t3073\tWix5FWCA_X86\tExecFirewallExceptions\t", | ||
| 104 | "CustomAction:Wix5ExecFirewallExceptionsUninstall_X86\t3073\tWix5FWCA_X86\tExecFirewallExceptions\t", | ||
| 105 | "CustomAction:Wix5RollbackFirewallExceptionsInstall_X86\t3329\tWix5FWCA_X86\tExecFirewallExceptions\t", | ||
| 106 | "CustomAction:Wix5RollbackFirewallExceptionsUninstall_X86\t3329\tWix5FWCA_X86\tExecFirewallExceptions\t", | ||
| 107 | "CustomAction:Wix5SchedFirewallExceptionsInstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsInstall\t", | ||
| 108 | "CustomAction:Wix5SchedFirewallExceptionsUninstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsUninstall\t", | ||
| 109 | "Wix5FirewallException:fexRrE4bS.DwUJQMvzX0ALEsx7jrZs\tSingle Nested properties\t[REMOTEADDRESS]\t\t-2147483648\t\t0\t-2147483648\tFirewallComponent\t\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t[INTERFACE]\t[INTERFACETYPE]\t[LOCALADDRESS]\t\t\t\t\t\t\t\t-2147483648", | ||
| 110 | "Wix5FirewallException:fexvEy1GfdOjHlKcvsguyqK6mvYKyk\t[NAME]\t[REMOTESCOPE]\t[LOCALPORT]\t[PROTOCOL]\t[PROGRAM]\t16\t[PROFILE]\tFirewallComponent\t[DESCRIPTION]\t1\t[ACTION]\t[EDGETRAVERSAL]\t[ENABLED]\t[GROUPING]\t[ICMPTYPES]\t[INTERFACE]\t[INTERFACETYPE]\t[LOCALSCOPE]\t[REMOTEPORT]\t[SERVICE]\t[PACKAGEID]\t[LOCALUSERS]\t[LOCALOWNER]\t[REMOTEMACHINES]\t[REMOTEUSERS]\t[SECUREFLAGS]", | ||
| 111 | "Wix5FirewallException:fexWywW3VGiEuG23FOv1YM6h7R6F5Q\tMultiple Nested properties\t[REMOTEADDRESS1],[REMOTEADDRESS2]\t\t-2147483648\t\t0\t-2147483648\tFirewallComponent\t\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t[INTERFACE1]|[INTERFACE2]\t[INTERFACETYPE1],[INTERFACETYPE2]\t[LOCALADDRESS1],[LOCALADDRESS2]\t\t\t\t\t\t\t\t-2147483648", | ||
| 112 | }, results); | ||
| 113 | } | ||
| 114 | |||
| 115 | [Fact] | ||
| 116 | public void CanBuildWithPropertiesUsingFirewallARM64() | ||
| 117 | { | ||
| 118 | var folder = TestData.Get(@"TestData\UsingProperties"); | ||
| 119 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); | ||
| 120 | |||
| 121 | var results = build.BuildAndQuery(BuildARM64, "Wix5FirewallException", "CustomAction"); | ||
| 122 | WixAssert.CompareLineByLine(new[] | ||
| 123 | { | ||
| 124 | "CustomAction:Wix5ExecFirewallExceptionsInstall_A64\t3073\tWix5FWCA_A64\tExecFirewallExceptions\t", | ||
| 125 | "CustomAction:Wix5ExecFirewallExceptionsUninstall_A64\t3073\tWix5FWCA_A64\tExecFirewallExceptions\t", | ||
| 126 | "CustomAction:Wix5RollbackFirewallExceptionsInstall_A64\t3329\tWix5FWCA_A64\tExecFirewallExceptions\t", | ||
| 127 | "CustomAction:Wix5RollbackFirewallExceptionsUninstall_A64\t3329\tWix5FWCA_A64\tExecFirewallExceptions\t", | ||
| 128 | "CustomAction:Wix5SchedFirewallExceptionsInstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsInstall\t", | ||
| 129 | "CustomAction:Wix5SchedFirewallExceptionsUninstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsUninstall\t", | ||
| 130 | "Wix5FirewallException:fexRrE4bS.DwUJQMvzX0ALEsx7jrZs\tSingle Nested properties\t[REMOTEADDRESS]\t\t-2147483648\t\t0\t-2147483648\tFirewallComponent\t\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t[INTERFACE]\t[INTERFACETYPE]\t[LOCALADDRESS]\t\t\t\t\t\t\t\t-2147483648", | ||
| 131 | "Wix5FirewallException:fexvEy1GfdOjHlKcvsguyqK6mvYKyk\t[NAME]\t[REMOTESCOPE]\t[LOCALPORT]\t[PROTOCOL]\t[PROGRAM]\t16\t[PROFILE]\tFirewallComponent\t[DESCRIPTION]\t1\t[ACTION]\t[EDGETRAVERSAL]\t[ENABLED]\t[GROUPING]\t[ICMPTYPES]\t[INTERFACE]\t[INTERFACETYPE]\t[LOCALSCOPE]\t[REMOTEPORT]\t[SERVICE]\t[PACKAGEID]\t[LOCALUSERS]\t[LOCALOWNER]\t[REMOTEMACHINES]\t[REMOTEUSERS]\t[SECUREFLAGS]", | ||
| 132 | "Wix5FirewallException:fexWywW3VGiEuG23FOv1YM6h7R6F5Q\tMultiple Nested properties\t[REMOTEADDRESS1],[REMOTEADDRESS2]\t\t-2147483648\t\t0\t-2147483648\tFirewallComponent\t\t1\t-2147483648\t-2147483648\t-2147483648\t\t\t[INTERFACE1]|[INTERFACE2]\t[INTERFACETYPE1],[INTERFACETYPE2]\t[LOCALADDRESS1],[LOCALADDRESS2]\t\t\t\t\t\t\t\t-2147483648", | ||
| 60 | }, results); | 133 | }, results); |
| 61 | } | 134 | } |
| 62 | 135 | ||
| @@ -83,6 +156,59 @@ namespace WixToolsetTest.Firewall | |||
| 83 | "FirewallException", | 156 | "FirewallException", |
| 84 | "FirewallException", | 157 | "FirewallException", |
| 85 | "FirewallException", | 158 | "FirewallException", |
| 159 | "FirewallException", | ||
| 160 | "FirewallException", | ||
| 161 | "LocalAddress", | ||
| 162 | "LocalAddress", | ||
| 163 | "FirewallException", | ||
| 164 | "RemoteAddress", | ||
| 165 | "Interface", | ||
| 166 | "Interface", | ||
| 167 | "FirewallException", | ||
| 168 | "FirewallException", | ||
| 169 | "InterfaceType", | ||
| 170 | "InterfaceType", | ||
| 171 | "FirewallException", | ||
| 172 | "FirewallException", | ||
| 173 | "FirewallException", | ||
| 174 | "FirewallException", | ||
| 175 | "FirewallException", | ||
| 176 | "FirewallException", | ||
| 177 | "FirewallException", | ||
| 178 | "FirewallException", | ||
| 179 | "FirewallException", | ||
| 180 | "FirewallException", | ||
| 181 | }, actual.Select(a => a.Name).ToArray()); | ||
| 182 | } | ||
| 183 | |||
| 184 | [Fact] | ||
| 185 | public void CanRoundtripFirewallExceptionsWithProperties() | ||
| 186 | { | ||
| 187 | var folder = TestData.Get(@"TestData", "UsingProperties"); | ||
| 188 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); | ||
| 189 | var output = Path.Combine(folder, "FirewallPropertiesDecompile.xml"); | ||
| 190 | |||
| 191 | build.BuildAndDecompileAndBuild(Build, Decompile, output); | ||
| 192 | |||
| 193 | var doc = XDocument.Load(output); | ||
| 194 | var actual = doc.Descendants() | ||
| 195 | .Where(e => e.Name.Namespace == "http://wixtoolset.org/schemas/v4/wxs/firewall") | ||
| 196 | .Select(fe => new { Name = fe.Name.LocalName, Attributes = fe.Attributes().Select(a => $"{a.Name.LocalName}={a.Value}").ToArray() }) | ||
| 197 | .ToArray(); | ||
| 198 | |||
| 199 | WixAssert.CompareLineByLine(new[] | ||
| 200 | { | ||
| 201 | "FirewallException", | ||
| 202 | "FirewallException", | ||
| 203 | "FirewallException", | ||
| 204 | "RemoteAddress", | ||
| 205 | "RemoteAddress", | ||
| 206 | "Interface", | ||
| 207 | "Interface", | ||
| 208 | "InterfaceType", | ||
| 209 | "InterfaceType", | ||
| 210 | "LocalAddress", | ||
| 211 | "LocalAddress", | ||
| 86 | }, actual.Select(a => a.Name).ToArray()); | 212 | }, actual.Select(a => a.Name).ToArray()); |
| 87 | } | 213 | } |
| 88 | 214 | ||
| @@ -98,9 +224,8 @@ namespace WixToolsetTest.Firewall | |||
| 98 | "Port=42", | 224 | "Port=42", |
| 99 | "Protocol=tcp", | 225 | "Protocol=tcp", |
| 100 | "Program=[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]", | 226 | "Program=[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]", |
| 101 | "Profile=all", | 227 | "OnUpdate=DoNothing", |
| 102 | "Description=An app-based firewall exception", | 228 | "Description=An app-based firewall exception", |
| 103 | "Outbound=no", | ||
| 104 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | 229 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", |
| 105 | }, actual.Attributes); | 230 | }, actual.Attributes); |
| 106 | } | 231 | } |
| @@ -111,12 +236,12 @@ namespace WixToolsetTest.Firewall | |||
| 111 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExamplePort"); | 236 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExamplePort"); |
| 112 | WixAssert.CompareLineByLine(new[] | 237 | WixAssert.CompareLineByLine(new[] |
| 113 | { | 238 | { |
| 114 | "Id=fex70IVsYNnbwiHQrEepmdTPKH8XYs", | 239 | "Id=fexaUTe2tRRcSYrPUTn44DAZhE.40Q", |
| 115 | "Name=ExamplePort", | 240 | "Name=ExamplePort", |
| 116 | "Scope=localSubnet", | 241 | "Scope=localSubnet", |
| 117 | "Port=42", | 242 | "Port=42", |
| 118 | "Protocol=tcp", | 243 | "Protocol=tcp", |
| 119 | "Profile=all", | 244 | "OnUpdate=EnableOnly", |
| 120 | "Description=A port-based firewall exception", | 245 | "Description=A port-based firewall exception", |
| 121 | "Outbound=yes", | 246 | "Outbound=yes", |
| 122 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | 247 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", |
| @@ -129,14 +254,12 @@ namespace WixToolsetTest.Firewall | |||
| 129 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDNSScope"); | 254 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDNSScope"); |
| 130 | WixAssert.CompareLineByLine(new[] | 255 | WixAssert.CompareLineByLine(new[] |
| 131 | { | 256 | { |
| 132 | "Id=fexxY71H2ZBkPalv7uid1Yy4qaA_lA", | 257 | "Id=fex4FeP470wYcFpw.g7fbIKiLnZPzg", |
| 133 | "Name=ExampleDNSScope", | 258 | "Name=ExampleDNSScope", |
| 134 | "Scope=DNS", | 259 | "Scope=DNS", |
| 135 | "Port=356", | 260 | "Port=356", |
| 136 | "Protocol=udp", | 261 | "Protocol=udp", |
| 137 | "Profile=all", | ||
| 138 | "Description=DNS scope firewall exception", | 262 | "Description=DNS scope firewall exception", |
| 139 | "Outbound=no", | ||
| 140 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | 263 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", |
| 141 | }, actual.Attributes); | 264 | }, actual.Attributes); |
| 142 | } | 265 | } |
| @@ -147,14 +270,13 @@ namespace WixToolsetTest.Firewall | |||
| 147 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDHCPScope"); | 270 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDHCPScope"); |
| 148 | WixAssert.CompareLineByLine(new[] | 271 | WixAssert.CompareLineByLine(new[] |
| 149 | { | 272 | { |
| 150 | "Id=fex6bkfWwpiRGI.wVFx0T7W4LXIHxU", | 273 | "Id=fexpWUzK53RVnaluW36gSmphPRY8VY", |
| 151 | "Name=ExampleDHCPScope", | 274 | "Name=ExampleDHCPScope", |
| 152 | "Scope=DHCP", | 275 | "Scope=DHCP", |
| 153 | "Protocol=211", | 276 | "Protocol=211", |
| 154 | "Program=test.exe", | 277 | "Program=test.exe", |
| 155 | "Profile=public", | 278 | "Profile=public", |
| 156 | "Description=DHCP scope firewall exception", | 279 | "Description=DHCP scope firewall exception", |
| 157 | "Outbound=no", | ||
| 158 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall" | 280 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall" |
| 159 | }, actual.Attributes); | 281 | }, actual.Attributes); |
| 160 | } | 282 | } |
| @@ -165,14 +287,13 @@ namespace WixToolsetTest.Firewall | |||
| 165 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleWINSScope"); | 287 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleWINSScope"); |
| 166 | WixAssert.CompareLineByLine(new[] | 288 | WixAssert.CompareLineByLine(new[] |
| 167 | { | 289 | { |
| 168 | "Id=fexXxaXCXXFh.UxO_BjmZxi1B1du_Q", | 290 | "Id=fexD6w20c5HfNi4l1vHFj_eet4cC8I", |
| 169 | "Name=ExampleWINSScope", | 291 | "Name=ExampleWINSScope", |
| 170 | "Scope=WINS", | 292 | "Scope=WINS", |
| 171 | "Port=6573", | 293 | "Port=6573", |
| 172 | "Protocol=tcp", | 294 | "Protocol=tcp", |
| 173 | "Profile=domain", | 295 | "Profile=domain", |
| 174 | "Description=WINS scope firewall exception", | 296 | "Description=WINS scope firewall exception", |
| 175 | "Outbound=no", | ||
| 176 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | 297 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", |
| 177 | }, actual.Attributes); | 298 | }, actual.Attributes); |
| 178 | } | 299 | } |
| @@ -183,18 +304,322 @@ namespace WixToolsetTest.Firewall | |||
| 183 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDefaultGatewayScope"); | 304 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDefaultGatewayScope"); |
| 184 | WixAssert.CompareLineByLine(new[] | 305 | WixAssert.CompareLineByLine(new[] |
| 185 | { | 306 | { |
| 186 | "Id=fex_ZpDsnKyHlYiA24JHzvFxm3uLZ8", | 307 | "Id=fex8vMfBplrod4daEz3PqDTeX6olGE", |
| 187 | "Name=ExampleDefaultGatewayScope", | 308 | "Name=ExampleDefaultGatewayScope", |
| 188 | "Scope=defaultGateway", | 309 | "Scope=defaultGateway", |
| 189 | "Port=4432", | 310 | "Port=4432", |
| 190 | "Protocol=tcp", | 311 | "Protocol=tcp", |
| 191 | "Profile=private", | 312 | "Profile=private", |
| 192 | "Description=defaultGateway scope firewall exception", | 313 | "Description=defaultGateway scope firewall exception", |
| 193 | "Outbound=no", | ||
| 194 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | 314 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", |
| 195 | }, actual.Attributes); | 315 | }, actual.Attributes); |
| 196 | } | 316 | } |
| 197 | 317 | ||
| 318 | [Fact] | ||
| 319 | public void RoundtripAttributesAreCorrectForINetFwRule3Values() | ||
| 320 | { | ||
| 321 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "INetFwRule3 values"); | ||
| 322 | WixAssert.CompareLineByLine(new[] | ||
| 323 | { | ||
| 324 | "Id=fexwjf4OTFVE9SNiC4goVxBA6ENJBE", | ||
| 325 | "Name=INetFwRule3 values", | ||
| 326 | "Scope=any", | ||
| 327 | "Description=Simple INetFwRule3 values", | ||
| 328 | "LocalAppPackageId=S-1-15-2-1239072475-3687740317-1842961305-3395936705-4023953123-1525404051-2779347315", | ||
| 329 | "LocalUserAuthorizedList=O:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)", | ||
| 330 | "LocalUserOwner=S-1-5-21-1898747406-2352535518-1247798438-1914", | ||
| 331 | "RemoteMachineAuthorizedList=127.0.0.1", | ||
| 332 | "RemoteUserAuthorizedList=O:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)", | ||
| 333 | "IPSecSecureFlags=NegotiateEncryption", | ||
| 334 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 335 | }, actual.Attributes); | ||
| 336 | } | ||
| 337 | |||
| 338 | [Fact] | ||
| 339 | public void RoundtripAttributesAreCorrectForINetFwRule3Properties() | ||
| 340 | { | ||
| 341 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "INetFwRule3 properties"); | ||
| 342 | WixAssert.CompareLineByLine(new[] | ||
| 343 | { | ||
| 344 | "Id=fexAMmHzFDyQmubTOnKS1Cn0Y3q_Ug", | ||
| 345 | "Name=INetFwRule3 properties", | ||
| 346 | "Scope=any", | ||
| 347 | "Description=INetFwRule3 passed via properties", | ||
| 348 | "LocalAppPackageId=[PROP1]", | ||
| 349 | "LocalUserAuthorizedList=[PROP2]", | ||
| 350 | "LocalUserOwner=[PROP3]", | ||
| 351 | "RemoteMachineAuthorizedList=[PROP4]", | ||
| 352 | "RemoteUserAuthorizedList=[PROP5]", | ||
| 353 | "IPSecSecureFlags=[PROP6]", | ||
| 354 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 355 | }, actual.Attributes); | ||
| 356 | } | ||
| 357 | |||
| 358 | [Fact] | ||
| 359 | public void RoundtripAttributesAreCorrectForGroupingValue() | ||
| 360 | { | ||
| 361 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "GroupingExample1"); | ||
| 362 | WixAssert.CompareLineByLine(new[] | ||
| 363 | { | ||
| 364 | "Id=fexfzjTQsWwZkHQpObtl0XaUosfcRk", | ||
| 365 | "Name=GroupingExample1", | ||
| 366 | "Program=fw.exe", | ||
| 367 | "Description=Simple rule with grouping", | ||
| 368 | "Grouping=@yourresources.dll,-1005", | ||
| 369 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 370 | }, actual.Attributes); | ||
| 371 | } | ||
| 372 | |||
| 373 | [Fact] | ||
| 374 | public void RoundtripAttributesAreCorrectForGroupingProperty() | ||
| 375 | { | ||
| 376 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "GroupingExample2"); | ||
| 377 | WixAssert.CompareLineByLine(new[] | ||
| 378 | { | ||
| 379 | "Id=fexVr6uHcOCak5MHuTLwujjh_oKtbI", | ||
| 380 | "Name=GroupingExample2", | ||
| 381 | "Port=8732", | ||
| 382 | "Protocol=tcp", | ||
| 383 | "Description=Rule with grouping property", | ||
| 384 | "Grouping=[GROUPING_PROP]", | ||
| 385 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 386 | }, actual.Attributes); | ||
| 387 | } | ||
| 388 | |||
| 389 | [Fact] | ||
| 390 | public void RoundtripAttributesAreCorrectForIcmpValue() | ||
| 391 | { | ||
| 392 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ICMPExample1"); | ||
| 393 | WixAssert.CompareLineByLine(new[] | ||
| 394 | { | ||
| 395 | "Id=fexEPvcf4iexD1mVQdvxm7tD02nZEc", | ||
| 396 | "Name=ICMPExample1", | ||
| 397 | "Protocol=2", | ||
| 398 | "Description=Simple ICMP rule", | ||
| 399 | "IcmpTypesAndCodes=4:*,9:*,12:*", | ||
| 400 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 401 | }, actual.Attributes); | ||
| 402 | } | ||
| 403 | |||
| 404 | [Fact] | ||
| 405 | public void RoundtripAttributesAreCorrectForIcmpProperty() | ||
| 406 | { | ||
| 407 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ICMPExample2"); | ||
| 408 | WixAssert.CompareLineByLine(new[] | ||
| 409 | { | ||
| 410 | "Id=fexuanTga5xaaFzr9JsAnUmpCNediw", | ||
| 411 | "Name=ICMPExample2", | ||
| 412 | "Protocol=2", | ||
| 413 | "Description=Rule with ICMP property", | ||
| 414 | "IcmpTypesAndCodes=[ICMP_PROP]", | ||
| 415 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 416 | }, actual.Attributes); | ||
| 417 | } | ||
| 418 | |||
| 419 | [Fact] | ||
| 420 | public void RoundtripAttributesAreCorrectForLocalScopeValue() | ||
| 421 | { | ||
| 422 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "LocalScopeExample1"); | ||
| 423 | WixAssert.CompareLineByLine(new[] | ||
| 424 | { | ||
| 425 | "Id=fex0HTxATWjpC2PCoY6DB7f2D1WaKU", | ||
| 426 | "Name=LocalScopeExample1", | ||
| 427 | "Scope=any", | ||
| 428 | "Description=Simple rule with local scope", | ||
| 429 | "LocalScope=localSubnet", | ||
| 430 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 431 | }, actual.Attributes); | ||
| 432 | } | ||
| 433 | |||
| 434 | [Fact] | ||
| 435 | public void RoundtripAttributesAreCorrectForLocalScopeProperty() | ||
| 436 | { | ||
| 437 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "LocalScopeExample2"); | ||
| 438 | WixAssert.CompareLineByLine(new[] | ||
| 439 | { | ||
| 440 | "Id=fex.BGtyMRGAhxb2hG.49JvWYz7fM0", | ||
| 441 | "Name=LocalScopeExample2", | ||
| 442 | "Scope=any", | ||
| 443 | "Description=Rule with local scope property", | ||
| 444 | "LocalScope=[LOCALSCOPE_PROP]", | ||
| 445 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 446 | }, actual.Attributes); | ||
| 447 | } | ||
| 448 | |||
| 449 | [Fact] | ||
| 450 | public void RoundtripAttributesAreCorrectForRemotePorts() | ||
| 451 | { | ||
| 452 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "RemotePortExample1"); | ||
| 453 | WixAssert.CompareLineByLine(new[] | ||
| 454 | { | ||
| 455 | "Id=fexHx2xbwZYzAi0oYp4YGWevJQs5eM", | ||
| 456 | "Name=RemotePortExample1", | ||
| 457 | "Scope=any", | ||
| 458 | "Protocol=tcp", | ||
| 459 | "Description=Simple rule with remote port", | ||
| 460 | "RemotePort=34560", | ||
| 461 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 462 | }, actual.Attributes); | ||
| 463 | } | ||
| 464 | |||
| 465 | [Fact] | ||
| 466 | public void RoundtripAttributesAreCorrectForRemotePortsProperty() | ||
| 467 | { | ||
| 468 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "RemotePortExample2"); | ||
| 469 | WixAssert.CompareLineByLine(new[] | ||
| 470 | { | ||
| 471 | "Id=fexArlOkFR7CAwVZ2wk8yNdiREydu0", | ||
| 472 | "Name=RemotePortExample2", | ||
| 473 | "Protocol=tcp", | ||
| 474 | "Program=fw.exe", | ||
| 475 | "Description=Rule with remote port property", | ||
| 476 | "RemotePort=[REMOTEPORT_PROP]", | ||
| 477 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall", | ||
| 478 | }, actual.Attributes); | ||
| 479 | } | ||
| 480 | |||
| 481 | [Fact] | ||
| 482 | public void RoundtripAttributesAreCorrectWhenPropertiesAreUsed() | ||
| 483 | { | ||
| 484 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "[NAME]", "UsingProperties"); | ||
| 485 | WixAssert.CompareLineByLine(new[] | ||
| 486 | { | ||
| 487 | "Id=fexvEy1GfdOjHlKcvsguyqK6mvYKyk", | ||
| 488 | "Name=[NAME]", | ||
| 489 | "Scope=[REMOTESCOPE]", | ||
| 490 | "Port=[LOCALPORT]", | ||
| 491 | "Protocol=[PROTOCOL]", | ||
| 492 | "Program=[PROGRAM]", | ||
| 493 | "Profile=[PROFILE]", | ||
| 494 | "Description=[DESCRIPTION]", | ||
| 495 | "Action=[ACTION]", | ||
| 496 | "EdgeTraversal=[EDGETRAVERSAL]", | ||
| 497 | "Enabled=[ENABLED]", | ||
| 498 | "Grouping=[GROUPING]", | ||
| 499 | "IcmpTypesAndCodes=[ICMPTYPES]", | ||
| 500 | "Interface=[INTERFACE]", | ||
| 501 | "InterfaceType=[INTERFACETYPE]", | ||
| 502 | "LocalScope=[LOCALSCOPE]", | ||
| 503 | "RemotePort=[REMOTEPORT]", | ||
| 504 | "Service=[SERVICE]", | ||
| 505 | "LocalAppPackageId=[PACKAGEID]", | ||
| 506 | "LocalUserAuthorizedList=[LOCALUSERS]", | ||
| 507 | "LocalUserOwner=[LOCALOWNER]", | ||
| 508 | "RemoteMachineAuthorizedList=[REMOTEMACHINES]", | ||
| 509 | "RemoteUserAuthorizedList=[REMOTEUSERS]", | ||
| 510 | "IPSecSecureFlags=[SECUREFLAGS]", | ||
| 511 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall" | ||
| 512 | }, actual.Attributes); | ||
| 513 | |||
| 514 | var folder = TestData.Get(@"TestData", "UsingProperties"); | ||
| 515 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); | ||
| 516 | var output = Path.Combine(folder, $"FirewallNothingNested.xml"); | ||
| 517 | |||
| 518 | build.BuildAndDecompileAndBuild(Build, Decompile, output); | ||
| 519 | |||
| 520 | var doc = XDocument.Load(output); | ||
| 521 | var related = doc.Descendants() | ||
| 522 | .Where(e => | ||
| 523 | { | ||
| 524 | return e.Name.Namespace == "http://wixtoolset.org/schemas/v4/wxs/firewall" && | ||
| 525 | e.Parent.Attributes().Any(a => a.Name.LocalName == "Name" && a.Value == "[NAME]"); | ||
| 526 | }); | ||
| 527 | |||
| 528 | var nested = related.Select(e => e.Attributes().Single(a => a.Name.LocalName == "Name").Value); | ||
| 529 | Assert.False(nested.Any()); | ||
| 530 | } | ||
| 531 | |||
| 532 | [Fact] | ||
| 533 | public void RoundtripAttributesAreCorrectWhenNestedPropertiesAreUsed() | ||
| 534 | { | ||
| 535 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "Single Nested properties", "UsingProperties"); | ||
| 536 | WixAssert.CompareLineByLine(new[] | ||
| 537 | { | ||
| 538 | "Id=fexRrE4bS.DwUJQMvzX0ALEsx7jrZs", | ||
| 539 | "Name=Single Nested properties", | ||
| 540 | "Scope=[REMOTEADDRESS]", | ||
| 541 | "Interface=[INTERFACE]", | ||
| 542 | "InterfaceType=[INTERFACETYPE]", | ||
| 543 | "LocalScope=[LOCALADDRESS]", | ||
| 544 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall" | ||
| 545 | }, actual.Attributes); | ||
| 546 | |||
| 547 | var folder = TestData.Get(@"TestData", "UsingProperties"); | ||
| 548 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); | ||
| 549 | var output = Path.Combine(folder, $"FirewallSingleNested.xml"); | ||
| 550 | |||
| 551 | build.BuildAndDecompileAndBuild(Build, Decompile, output); | ||
| 552 | |||
| 553 | var doc = XDocument.Load(output); | ||
| 554 | var related = doc.Descendants() | ||
| 555 | .Where(e => | ||
| 556 | { | ||
| 557 | return e.Name.Namespace == "http://wixtoolset.org/schemas/v4/wxs/firewall" && | ||
| 558 | e.Parent.Attributes().Any(a => a.Name.LocalName == "Name" && a.Value == "Single Nested properties"); | ||
| 559 | }); | ||
| 560 | |||
| 561 | var nested = related.Select(e => e.Attributes().Single(a => a.Name.LocalName == "Name").Value); | ||
| 562 | Assert.False(nested.Any()); | ||
| 563 | } | ||
| 564 | |||
| 565 | [Fact] | ||
| 566 | public void RoundtripAttributesAreCorrectWhenMultipleNestedPropertiesAreUsed() | ||
| 567 | { | ||
| 568 | var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "Multiple Nested properties", "UsingProperties"); | ||
| 569 | WixAssert.CompareLineByLine(new[] | ||
| 570 | { | ||
| 571 | "Id=fexWywW3VGiEuG23FOv1YM6h7R6F5Q", | ||
| 572 | "Name=Multiple Nested properties", | ||
| 573 | "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall" | ||
| 574 | }, actual.Attributes); | ||
| 575 | |||
| 576 | var folder = TestData.Get(@"TestData", "UsingProperties"); | ||
| 577 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); | ||
| 578 | var output = Path.Combine(folder, $"FirewallMultipleNested.xml"); | ||
| 579 | |||
| 580 | build.BuildAndDecompileAndBuild(Build, Decompile, output); | ||
| 581 | |||
| 582 | var doc = XDocument.Load(output); | ||
| 583 | var related = doc.Descendants() | ||
| 584 | .Where(e => | ||
| 585 | { | ||
| 586 | return e.Name.Namespace == "http://wixtoolset.org/schemas/v4/wxs/firewall" && | ||
| 587 | e.Parent.Attributes().Any(a => a.Name.LocalName == "Name" && a.Value == "Multiple Nested properties"); | ||
| 588 | }); | ||
| 589 | |||
| 590 | var interfaces = related.Where(e => e.Name.LocalName == "Interface") | ||
| 591 | .Select(e => e.Attributes().Single(a => a.Name.LocalName == "Name").Value); | ||
| 592 | WixAssert.CompareLineByLine(new[] | ||
| 593 | { | ||
| 594 | "[INTERFACE1]", | ||
| 595 | "[INTERFACE2]", | ||
| 596 | }, interfaces.ToArray()); | ||
| 597 | |||
| 598 | var interfaceTypes = related.Where(e => e.Name.LocalName == "InterfaceType") | ||
| 599 | .Select(e => e.Attributes().Single(a => a.Name.LocalName == "Value").Value); | ||
| 600 | WixAssert.CompareLineByLine(new[] | ||
| 601 | { | ||
| 602 | "[INTERFACETYPE1]", | ||
| 603 | "[INTERFACETYPE2]", | ||
| 604 | }, interfaceTypes.ToArray()); | ||
| 605 | |||
| 606 | var remotes = related.Where(e => e.Name.LocalName == "RemoteAddress") | ||
| 607 | .Select(e => e.Attributes().Single(a => a.Name.LocalName == "Value").Value); | ||
| 608 | WixAssert.CompareLineByLine(new[] | ||
| 609 | { | ||
| 610 | "[REMOTEADDRESS1]", | ||
| 611 | "[REMOTEADDRESS2]", | ||
| 612 | }, remotes.ToArray()); | ||
| 613 | |||
| 614 | var locals = related.Where(e => e.Name.LocalName == "LocalAddress") | ||
| 615 | .Select(e => e.Attributes().Single(a => a.Name.LocalName == "Value").Value); | ||
| 616 | WixAssert.CompareLineByLine(new[] | ||
| 617 | { | ||
| 618 | "[LOCALADDRESS1]", | ||
| 619 | "[LOCALADDRESS2]", | ||
| 620 | }, locals.ToArray()); | ||
| 621 | } | ||
| 622 | |||
| 198 | private static void Build(string[] args) | 623 | private static void Build(string[] args) |
| 199 | { | 624 | { |
| 200 | var result = WixRunner.Execute(args); | 625 | var result = WixRunner.Execute(args); |
| @@ -216,15 +641,16 @@ namespace WixToolsetTest.Firewall | |||
| 216 | var result = WixRunner.Execute(args); | 641 | var result = WixRunner.Execute(args); |
| 217 | result.AssertSuccess(); | 642 | result.AssertSuccess(); |
| 218 | } | 643 | } |
| 644 | |||
| 219 | class AttributeVerifier | 645 | class AttributeVerifier |
| 220 | { | 646 | { |
| 221 | public string Name { get; set; } | 647 | public string Name { get; set; } |
| 222 | public string[] Attributes { get; set; } | 648 | public string[] Attributes { get; set; } |
| 223 | } | 649 | } |
| 224 | 650 | ||
| 225 | private static AttributeVerifier BuildAndDecompileAndBuild(string nameSpace, string ruleName) | 651 | private static AttributeVerifier BuildAndDecompileAndBuild(string nameSpace, string ruleName, string path = "UsingFirewall") |
| 226 | { | 652 | { |
| 227 | var folder = TestData.Get(@"TestData", "UsingFirewall"); | 653 | var folder = TestData.Get(@"TestData", path); |
| 228 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); | 654 | var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder }); |
| 229 | var output = Path.Combine(folder, $"Firewall{ruleName}.xml"); | 655 | var output = Path.Combine(folder, $"Firewall{ruleName}.xml"); |
| 230 | 656 | ||
| @@ -232,7 +658,10 @@ namespace WixToolsetTest.Firewall | |||
| 232 | 658 | ||
| 233 | var doc = XDocument.Load(output); | 659 | var doc = XDocument.Load(output); |
| 234 | var actual = doc.Descendants() | 660 | var actual = doc.Descendants() |
| 235 | .Where(e => e.Name.Namespace == nameSpace) | 661 | .Where(e => |
| 662 | { | ||
| 663 | return e.Name.Namespace == nameSpace && e.Name.LocalName == "FirewallException"; | ||
| 664 | }) | ||
| 236 | .Select(fe => new AttributeVerifier | 665 | .Select(fe => new AttributeVerifier |
| 237 | { | 666 | { |
| 238 | Name = fe.Attributes().Single(a => a.Name.LocalName == "Name").Value, | 667 | Name = fe.Attributes().Single(a => a.Name.LocalName == "Name").Value, |
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs index 957aa642..4bb2e192 100644 --- a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs +++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs | |||
| @@ -6,16 +6,51 @@ | |||
| 6 | <Component> | 6 | <Component> |
| 7 | <File Name="fw.exe" Source="example.txt"> | 7 | <File Name="fw.exe" Source="example.txt"> |
| 8 | <Shortcut Id="FwShortcut" Directory="INSTALLFOLDER" Name="Firewall" /> | 8 | <Shortcut Id="FwShortcut" Directory="INSTALLFOLDER" Name="Firewall" /> |
| 9 | <fw:FirewallException Id="ExampleFirewall" Description="An app-based firewall exception" Name="ExampleApp" Port="42"> | 9 | <fw:FirewallException Id="ExampleFirewall" Description="An app-based firewall exception" Name="ExampleApp" Port="42" OnUpdate="DoNothing" > |
| 10 | <fw:RemoteAddress Value="*" /> | 10 | <fw:RemoteAddress Value="*" /> |
| 11 | </fw:FirewallException> | 11 | </fw:FirewallException> |
| 12 | </File> | 12 | </File> |
| 13 | 13 | ||
| 14 | <fw:FirewallException Description="A port-based firewall exception" Name="ExamplePort" Port="42" Outbound="yes" Scope="localSubnet" /> | 14 | <fw:FirewallException Description="A port-based firewall exception" Name="ExamplePort" Port="42" Outbound="yes" Scope="localSubnet" OnUpdate="EnableOnly" /> |
| 15 | <fw:FirewallException Description="DNS scope firewall exception" Name="ExampleDNSScope" Port="356" Protocol="udp" Scope="DNS" /> | 15 | <fw:FirewallException Description="DNS scope firewall exception" Name="ExampleDNSScope" Port="356" Protocol="udp" Scope="DNS" /> |
| 16 | <fw:FirewallException Description="DHCP scope firewall exception" Name="ExampleDHCPScope" Program="test.exe" Protocol="211" Scope="DHCP" Profile="public" /> | 16 | <fw:FirewallException Description="DHCP scope firewall exception" Name="ExampleDHCPScope" Program="test.exe" Protocol="211" Scope="DHCP" Profile="public" /> |
| 17 | <fw:FirewallException Description="WINS scope firewall exception" Name="ExampleWINSScope" Port="6573" Scope="WINS" Profile="domain"/> | 17 | <fw:FirewallException Description="WINS scope firewall exception" Name="ExampleWINSScope" Port="6573" Scope="WINS" Profile="domain"/> |
| 18 | <fw:FirewallException Description="defaultGateway scope firewall exception" Name="ExampleDefaultGatewayScope" Port="4432" Scope="defaultGateway" Profile="private" /> | 18 | <fw:FirewallException Description="defaultGateway scope firewall exception" Name="ExampleDefaultGatewayScope" Port="4432" Scope="defaultGateway" Profile="private" /> |
| 19 | |||
| 20 | <fw:FirewallException Description="Defer to user edge traversal" Name="defertouser" Program="fw.exe" EdgeTraversal="DeferToUser" /> | ||
| 21 | <fw:FirewallException Description="A port-based service exception" Name="ExampleService" Port="12000" Service="ftpsrv" Program="%windir%\system32\svchost.exe" > | ||
| 22 | <fw:LocalAddress Value="DHCP"/> | ||
| 23 | <fw:LocalAddress Value="WINS"/> | ||
| 24 | </fw:FirewallException> | ||
| 25 | |||
| 26 | <fw:FirewallException Description="Interfaces with nested elements" Name="interface nested" Port="54671" > | ||
| 27 | <fw:RemoteAddress Value="127.0.0.1"/> | ||
| 28 | <fw:Interface Name="Wi-Fi" /> | ||
| 29 | <fw:Interface Name="Local Area Connection" /> | ||
| 30 | </fw:FirewallException> | ||
| 31 | <fw:FirewallException Description="Interfaces with property" Name="interface property" Port="54671" Interface="[INTERFACE_PROPERTY]" /> | ||
| 32 | |||
| 33 | <ServiceInstall Name="svc1" Type="ownProcess" Start="disabled" ErrorControl="ignore" > | ||
| 34 | <fw:FirewallException Id="ServiceInstall.nested" IgnoreFailure="true" Description="A port-based firewall exception for a windows service" Name="ExampleNestedService" Port="3546-7890" Scope="localSubnet" > | ||
| 35 | <fw:InterfaceType Value="Lan" /> | ||
| 36 | <fw:InterfaceType Value="Wireless" /> | ||
| 37 | </fw:FirewallException> | ||
| 38 | </ServiceInstall> | ||
| 39 | |||
| 40 | <fw:FirewallException Description="Simple INetFwRule3 values" Name="INetFwRule3 values" Scope="any" LocalAppPackageId="S-1-15-2-1239072475-3687740317-1842961305-3395936705-4023953123-1525404051-2779347315" LocalUserAuthorizedList="O:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)" LocalUserOwner="S-1-5-21-1898747406-2352535518-1247798438-1914" RemoteMachineAuthorizedList="127.0.0.1" RemoteUserAuthorizedList="O:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)" IPSecSecureFlags="NegotiateEncryption" /> | ||
| 41 | <fw:FirewallException Description="INetFwRule3 passed via properties" Name="INetFwRule3 properties" Scope="any" LocalAppPackageId="[PROP1]" LocalUserAuthorizedList="[PROP2]" LocalUserOwner="[PROP3]" RemoteMachineAuthorizedList="[PROP4]" RemoteUserAuthorizedList="[PROP5]" IPSecSecureFlags="[PROP6]" /> | ||
| 42 | |||
| 43 | <fw:FirewallException Description="Simple rule with grouping" Name="GroupingExample1" Program="fw.exe" Grouping="@yourresources.dll,-1005" /> | ||
| 44 | <fw:FirewallException Description="Rule with grouping property" Name="GroupingExample2" Port="8732" Grouping="[GROUPING_PROP]" /> | ||
| 45 | |||
| 46 | <fw:FirewallException Description="Simple ICMP rule" Name="ICMPExample1" Protocol="2" IcmpTypesAndCodes="4:*,9:*,12:*" /> | ||
| 47 | <fw:FirewallException Description="Rule with ICMP property" Name="ICMPExample2" Protocol="2" IcmpTypesAndCodes="[ICMP_PROP]" /> | ||
| 48 | |||
| 49 | <fw:FirewallException Description="Simple rule with local scope" Name="LocalScopeExample1" Scope="any" LocalScope="localSubnet" /> | ||
| 50 | <fw:FirewallException Description="Rule with local scope property" Name="LocalScopeExample2" Scope="any" LocalScope="[LOCALSCOPE_PROP]" /> | ||
| 51 | |||
| 52 | <fw:FirewallException Description="Simple rule with remote port" Name="RemotePortExample1" Scope="any" RemotePort="34560" /> | ||
| 53 | <fw:FirewallException Description="Rule with remote port property" Name="RemotePortExample2" Program="fw.exe" RemotePort="[REMOTEPORT_PROP]" /> | ||
| 19 | </Component> | 54 | </Component> |
| 20 | </ComponentGroup> | 55 | </ComponentGroup> |
| 21 | </Fragment> | 56 | </Fragment> |
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/Package.en-us.wxl b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/Package.en-us.wxl new file mode 100644 index 00000000..f1df1234 --- /dev/null +++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/Package.en-us.wxl | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | <!-- | ||
| 2 | This file contains the declaration of all the localizable strings. | ||
| 3 | --> | ||
| 4 | <WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US"> | ||
| 5 | |||
| 6 | <String Id="DowngradeError" Value="A newer version of [ProductName] is already installed." /> | ||
| 7 | <String Id="FeatureTitle" Value="MsiPackage" /> | ||
| 8 | |||
| 9 | </WixLocalization> | ||
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/Package.wxs b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/Package.wxs new file mode 100644 index 00000000..814becd1 --- /dev/null +++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/Package.wxs | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
| 2 | <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="BB4E61B3-EBE5-4DE7-B3E0-8699B5901D2E"> | ||
| 3 | <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" /> | ||
| 4 | |||
| 5 | <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)"> | ||
| 6 | <ComponentGroupRef Id="ProductComponents" /> | ||
| 7 | </Feature> | ||
| 8 | </Package> | ||
| 9 | |||
| 10 | <Fragment> | ||
| 11 | <StandardDirectory Id="ProgramFilesFolder"> | ||
| 12 | <Directory Id="INSTALLFOLDER" Name="MsiPackage" /> | ||
| 13 | </StandardDirectory> | ||
| 14 | </Fragment> | ||
| 15 | </Wix> | ||
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/PackageComponents.wxs b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/PackageComponents.wxs new file mode 100644 index 00000000..05c3ea8a --- /dev/null +++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/PackageComponents.wxs | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" | ||
| 3 | xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall"> | ||
| 4 | <Fragment> | ||
| 5 | <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"> | ||
| 6 | <Component Id="FirewallComponent" Guid="28DF3387-F30E-4DBE-90E2-D2C760CB4DD9"> | ||
| 7 | <fw:FirewallException | ||
| 8 | Name="[NAME]" | ||
| 9 | Port="[LOCALPORT]" | ||
| 10 | Protocol="[PROTOCOL]" | ||
| 11 | Program="[PROGRAM]" | ||
| 12 | Profile="[PROFILE]" | ||
| 13 | Description="[DESCRIPTION]" | ||
| 14 | Scope="[REMOTESCOPE]" | ||
| 15 | Action="[ACTION]" | ||
| 16 | EdgeTraversal="[EDGETRAVERSAL]" | ||
| 17 | Enabled="[ENABLED]" | ||
| 18 | Grouping="[GROUPING]" | ||
| 19 | IcmpTypesAndCodes="[ICMPTYPES]" | ||
| 20 | Interface="[INTERFACE]" | ||
| 21 | InterfaceType="[INTERFACETYPE]" | ||
| 22 | LocalScope="[LOCALSCOPE]" | ||
| 23 | RemotePort="[REMOTEPORT]" | ||
| 24 | Service="[SERVICE]" | ||
| 25 | LocalAppPackageId="[PACKAGEID]" | ||
| 26 | LocalUserAuthorizedList="[LOCALUSERS]" | ||
| 27 | LocalUserOwner="[LOCALOWNER]" | ||
| 28 | RemoteMachineAuthorizedList="[REMOTEMACHINES]" | ||
| 29 | RemoteUserAuthorizedList="[REMOTEUSERS]" | ||
| 30 | IPSecSecureFlags="[SECUREFLAGS]" | ||
| 31 | /> | ||
| 32 | |||
| 33 | <fw:FirewallException Name="Single Nested properties" > | ||
| 34 | <fw:RemoteAddress Value="[REMOTEADDRESS]" /> | ||
| 35 | <fw:LocalAddress Value="[LOCALADDRESS]" /> | ||
| 36 | <fw:InterfaceType Value="[INTERFACETYPE]" /> | ||
| 37 | <fw:Interface Name="[INTERFACE]" /> | ||
| 38 | </fw:FirewallException> | ||
| 39 | |||
| 40 | <fw:FirewallException Name="Multiple Nested properties" > | ||
| 41 | <fw:RemoteAddress Value="[REMOTEADDRESS1]" /> | ||
| 42 | <fw:RemoteAddress Value="[REMOTEADDRESS2]" /> | ||
| 43 | <fw:LocalAddress Value="[LOCALADDRESS1]" /> | ||
| 44 | <fw:LocalAddress Value="[LOCALADDRESS2]" /> | ||
| 45 | <fw:InterfaceType Value="[INTERFACETYPE1]" /> | ||
| 46 | <fw:InterfaceType Value="[INTERFACETYPE2]" /> | ||
| 47 | <fw:Interface Name="[INTERFACE1]" /> | ||
| 48 | <fw:Interface Name="[INTERFACE2]" /> | ||
| 49 | </fw:FirewallException> | ||
| 50 | </Component> | ||
| 51 | </ComponentGroup> | ||
| 52 | </Fragment> | ||
| 53 | </Wix> | ||
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/example.txt b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/example.txt new file mode 100644 index 00000000..1b4ffe8a --- /dev/null +++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingProperties/example.txt | |||
| @@ -0,0 +1 @@ | |||
| This is example.txt. \ No newline at end of file | |||
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj b/src/ext/Firewall/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj index e46020a6..68acfe52 100644 --- a/src/ext/Firewall/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj +++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/WixToolsetTest.Firewall.csproj | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | <PropertyGroup> | 5 | <PropertyGroup> |
| 6 | <TargetFramework>net6.0</TargetFramework> | 6 | <TargetFramework>net6.0</TargetFramework> |
| 7 | <IsWixTestProject>true</IsWixTestProject> | 7 | <IsWixTestProject>true</IsWixTestProject> |
| 8 | <GenerateAssemblyInfo>false</GenerateAssemblyInfo> | ||
| 9 | <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute> | ||
| 8 | </PropertyGroup> | 10 | </PropertyGroup> |
| 9 | 11 | ||
| 10 | <ItemGroup> | 12 | <ItemGroup> |
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" /> |
diff --git a/src/ext/Util/wixext/UtilCompiler.cs b/src/ext/Util/wixext/UtilCompiler.cs index 5fefed91..f7bb0614 100644 --- a/src/ext/Util/wixext/UtilCompiler.cs +++ b/src/ext/Util/wixext/UtilCompiler.cs | |||
| @@ -3123,8 +3123,14 @@ namespace WixToolset.Util | |||
| 3123 | // if this element is a child of ServiceInstall then ignore the service name provided. | 3123 | // if this element is a child of ServiceInstall then ignore the service name provided. |
| 3124 | if ("ServiceInstall" == parentTableName) | 3124 | if ("ServiceInstall" == parentTableName) |
| 3125 | { | 3125 | { |
| 3126 | // TODO: the ServiceName attribute should not be allowed in this case (the overwriting behavior may confuse users) | 3126 | if (null == serviceName || parentTableServiceName == serviceName) |
| 3127 | serviceName = parentTableServiceName; | 3127 | { |
| 3128 | serviceName = parentTableServiceName; | ||
| 3129 | } | ||
| 3130 | else | ||
| 3131 | { | ||
| 3132 | this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "ServiceName", parentTableName)); | ||
| 3133 | } | ||
| 3128 | newService = true; | 3134 | newService = true; |
| 3129 | } | 3135 | } |
| 3130 | else | 3136 | else |
| @@ -3136,7 +3142,8 @@ namespace WixToolset.Util | |||
| 3136 | } | 3142 | } |
| 3137 | } | 3143 | } |
| 3138 | 3144 | ||
| 3139 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); | 3145 | var context = new Dictionary<string, string>() { { "ServiceConfigComponentId", componentId }, { "ServiceConfigServiceName", serviceName } }; |
| 3146 | this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element, context); | ||
| 3140 | 3147 | ||
| 3141 | if (!this.Messaging.EncounteredError) | 3148 | if (!this.Messaging.EncounteredError) |
| 3142 | { | 3149 | { |
diff --git a/src/internal/SetBuildNumber/Directory.Packages.props.pp b/src/internal/SetBuildNumber/Directory.Packages.props.pp index b39eeb78..ead26299 100644 --- a/src/internal/SetBuildNumber/Directory.Packages.props.pp +++ b/src/internal/SetBuildNumber/Directory.Packages.props.pp | |||
| @@ -47,6 +47,7 @@ | |||
| 47 | <PackageVersion Include="System.DirectoryServices.AccountManagement" Version="4.7.0" /> | 47 | <PackageVersion Include="System.DirectoryServices.AccountManagement" Version="4.7.0" /> |
| 48 | <PackageVersion Include="System.IO.Compression" Version="4.3.0" /> | 48 | <PackageVersion Include="System.IO.Compression" Version="4.3.0" /> |
| 49 | <PackageVersion Include="System.IO.FileSystem.AccessControl" Version="4.7.0" /> | 49 | <PackageVersion Include="System.IO.FileSystem.AccessControl" Version="4.7.0" /> |
| 50 | <PackageVersion Include="System.Net.NetworkInformation" Version="4.3.0" /> | ||
| 50 | <PackageVersion Include="System.Reflection.Metadata" Version="1.6.0" /> | 51 | <PackageVersion Include="System.Reflection.Metadata" Version="1.6.0" /> |
| 51 | <PackageVersion Include="System.Security.Principal.Windows" Version="4.7.0" /> | 52 | <PackageVersion Include="System.Security.Principal.Windows" Version="4.7.0" /> |
| 52 | <PackageVersion Include="System.Text.Encoding.CodePages" Version="4.7.0" /> | 53 | <PackageVersion Include="System.Text.Encoding.CodePages" Version="4.7.0" /> |
diff --git a/src/test/burn/WixTestTools/Firewall/RuleDetails.cs b/src/test/burn/WixTestTools/Firewall/RuleDetails.cs index d1e53de4..8c8cdda3 100644 --- a/src/test/burn/WixTestTools/Firewall/RuleDetails.cs +++ b/src/test/burn/WixTestTools/Firewall/RuleDetails.cs | |||
| @@ -146,7 +146,9 @@ namespace WixTestTools.Firewall | |||
| 146 | /// This parameter allows the specification of an array of interface LUIDs (locally unique identifiers) supplied as strings.<br/> | 146 | /// This parameter allows the specification of an array of interface LUIDs (locally unique identifiers) supplied as strings.<br/> |
| 147 | /// This is commonly used by USB RNDIS (Remote Network Driver Interface Specification) devices to restrict traffic to a specific non-routable interface.<br/> | 147 | /// This is commonly used by USB RNDIS (Remote Network Driver Interface Specification) devices to restrict traffic to a specific non-routable interface.<br/> |
| 148 | /// Use <b>netsh trace show interfaces</b> to show a list of local interfaces and their LUIDs.<br/> | 148 | /// Use <b>netsh trace show interfaces</b> to show a list of local interfaces and their LUIDs.<br/> |
| 149 | /// Example: new object[] { "Wi-Fi", "Local Area Connection* 14" } | 149 | /// The interfaces are stored in the registry as GUIDs, but need to be passed to the API as text. eg from the registry<br/> |
| 150 | /// v2.30|Action=Allow|Active=TRUE|Dir=In|Protocol=6|LPort=23456|IF={423411CD-E627-4A1A-9E1F-C5BE6CD2CC99}|IF={49A98AD0-8379-4079-A445-77066C52E338}|Name=WiXToolset401 Test - 0002|Desc=WiX Toolset firewall exception rule integration test - minimal port properties|<br/> | ||
| 151 | /// Example API value: new object[] { "Wi-Fi", "Local Area Connection* 14" } | ||
| 150 | /// </summary> | 152 | /// </summary> |
| 151 | public object[] Interfaces { get; set; } | 153 | public object[] Interfaces { get; set; } |
| 152 | 154 | ||
| @@ -227,13 +229,13 @@ namespace WixTestTools.Firewall | |||
| 227 | public string LocalUserOwner { get; set; } | 229 | public string LocalUserOwner { get; set; } |
| 228 | 230 | ||
| 229 | /// <summary> | 231 | /// <summary> |
| 230 | /// This property is optional. It specifies a list of authorized local users for an app container.<br/> | 232 | /// This property is optional. It specifies a list of authorized local users for an app container (using SDDL).<br/> |
| 231 | /// Example: "O:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)" | 233 | /// Example: "O:LSD:(A;;CC;;;S-1-5-84-0-0-0-0-0)" |
| 232 | /// </summary> | 234 | /// </summary> |
| 233 | public string LocalUserAuthorizedList { get; set; } | 235 | public string LocalUserAuthorizedList { get; set; } |
| 234 | 236 | ||
| 235 | /// <summary> | 237 | /// <summary> |
| 236 | /// This property is optional. It specifies a list of remote users who are authorized to access an app container.<br/> | 238 | /// This property is optional. It specifies a list of remote users who are authorized to access an app container (using SDDL).<br/> |
| 237 | /// </summary> | 239 | /// </summary> |
| 238 | public string RemoteUserAuthorizedList { get; set; } | 240 | public string RemoteUserAuthorizedList { get; set; } |
| 239 | 241 | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/CrossVersionMerge.wixproj b/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/CrossVersionMerge.wixproj new file mode 100644 index 00000000..f1c71d3d --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/CrossVersionMerge.wixproj | |||
| @@ -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 | <SuppressSpecificWarnings>1055;1056</SuppressSpecificWarnings> | ||
| 5 | </PropertyGroup> | ||
| 6 | <ItemGroup> | ||
| 7 | <!-- <ProjectReference Include="..\Module401\Module401.wixproj" /> --> | ||
| 8 | <ProjectReference Include="..\ModuleCurrent\ModuleCurrent.wixproj" /> | ||
| 9 | </ItemGroup> | ||
| 10 | <ItemGroup> | ||
| 11 | <PackageReference Include="WixToolset.Firewall.wixext" /> | ||
| 12 | </ItemGroup> | ||
| 13 | </Project> | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/Module401.msm b/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/Module401.msm new file mode 100644 index 00000000..4dd5bd09 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/Module401.msm | |||
| Binary files differ | |||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/package.wxs b/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/package.wxs new file mode 100644 index 00000000..6d5ea47a --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/CrossVersionMerge/package.wxs | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall"> | ||
| 2 | <Package Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" | ||
| 3 | UpgradeCode="41B5F815-E7F6-44E0-B92A-AE95DFF683F9" Compressed="yes" Scope="perMachine"> | ||
| 4 | <MediaTemplate EmbedCab="yes" /> | ||
| 5 | |||
| 6 | <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." /> | ||
| 7 | |||
| 8 | <Feature Id="ProductFeature" Title="Feature with merged modules"> | ||
| 9 | <MergeRef Id="TestMsm1" /> | ||
| 10 | <MergeRef Id="TestMsm2" /> | ||
| 11 | <ComponentRef Id="FirewallComponent1" /> | ||
| 12 | </Feature> | ||
| 13 | </Package> | ||
| 14 | |||
| 15 | <Fragment> | ||
| 16 | <StandardDirectory Id="ProgramFilesFolder"> | ||
| 17 | <Directory Id="INSTALLFOLDER" Name="MsiPackage"> | ||
| 18 | <Merge Id="TestMsm1" Language="1033" SourceFile="Module401.msm" /> | ||
| 19 | <Merge Id="TestMsm2" Language="1033" SourceFile="ModuleCurrent.msm" /> | ||
| 20 | </Directory> | ||
| 21 | </StandardDirectory> | ||
| 22 | </Fragment> | ||
| 23 | |||
| 24 | <Fragment> | ||
| 25 | <Property Id="MSIPORT1" Value="20001" /> | ||
| 26 | <Property Id="MSIPORT2" Value="20002" /> | ||
| 27 | |||
| 28 | <Component Id="FirewallComponent1" Guid="3E9A6190-3E6B-4BC2-8C84-D89D1549FEBD" Directory="INSTALLFOLDER"> | ||
| 29 | <File Source="$(sys.SOURCEFILEPATH)"> | ||
| 30 | <fw:FirewallException Id="FirewallException1" Description="WiX Toolset firewall exception rule integration test - package app" Name="WiXToolset Test - 0026" Scope="any" Port="[MSIPORT1]" /> | ||
| 31 | </File> | ||
| 32 | <fw:FirewallException Id="FirewallException2" Description="WiX Toolset firewall exception rule integration test - package port" Name="WiXToolset Test - 0027" Scope="any" Port="[MSIPORT2]" /> | ||
| 33 | </Component> | ||
| 34 | </Fragment> | ||
| 35 | </Wix> | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesInterfaces/FirewallRulesInterfaces.wixproj b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesInterfaces/FirewallRulesInterfaces.wixproj new file mode 100644 index 00000000..3c6ef5cf --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesInterfaces/FirewallRulesInterfaces.wixproj | |||
| @@ -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>{F153C27F-0236-4A0F-ADB3-50BFC73B4FEA}</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 | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesInterfaces/product.wxs b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesInterfaces/product.wxs new file mode 100644 index 00000000..142c8f68 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesInterfaces/product.wxs | |||
| @@ -0,0 +1,32 @@ | |||
| 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 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall"> | ||
| 5 | <Fragment> | ||
| 6 | <ComponentGroup Id="ProductComponents"> | ||
| 7 | <ComponentRef Id="FirewallComponent1"/> | ||
| 8 | </ComponentGroup> | ||
| 9 | </Fragment> | ||
| 10 | |||
| 11 | <Fragment> | ||
| 12 | <Component Id="FirewallComponent1" Guid="08044660-CB5D-4891-8BD5-0CB5BB668D78" Directory="INSTALLFOLDER"> | ||
| 13 | <File Source="$(sys.SOURCEFILEPATH)" KeyPath="yes" > | ||
| 14 | <fw:FirewallException Id="FirewallException28" | ||
| 15 | Description="WiX Toolset firewall exception rule integration test - three interfaces" | ||
| 16 | Name="WiXToolset500 Test - 0028" Scope="any" > | ||
| 17 | <fw:Interface Name="[INTERFACE1]" /> | ||
| 18 | <fw:Interface Name="[INTERFACE2]" /> | ||
| 19 | <fw:Interface Name="[INTERFACE3]" /> | ||
| 20 | <fw:InterfaceType Value="RemoteAccess" /> | ||
| 21 | <fw:InterfaceType Value="Lan" /> | ||
| 22 | <fw:InterfaceType Value="Wireless" /> | ||
| 23 | </fw:FirewallException> | ||
| 24 | </File> | ||
| 25 | |||
| 26 | <fw:FirewallException Id="FirewallException29" | ||
| 27 | Description="WiX Toolset firewall exception rule integration test - one interface" | ||
| 28 | Name="WiXToolset500 Test - 0029" Scope="any" Port="29292" Interface="[INTERFACE1]" InterfaceType="[INTERFACETYPE]" > | ||
| 29 | </fw:FirewallException> | ||
| 30 | </Component> | ||
| 31 | </Fragment> | ||
| 32 | </Wix> | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesProperties/FirewallRulesProperties.wixproj b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesProperties/FirewallRulesProperties.wixproj new file mode 100644 index 00000000..38d94265 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesProperties/FirewallRulesProperties.wixproj | |||
| @@ -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>{DC2C3CDC-112F-40A8-A7B4-2C7B758F4F94}</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 | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesProperties/product.wxs b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesProperties/product.wxs new file mode 100644 index 00000000..1f9935d5 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/FirewallRulesProperties/product.wxs | |||
| @@ -0,0 +1,57 @@ | |||
| 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 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall"> | ||
| 5 | <Fragment> | ||
| 6 | <ComponentGroup Id="ProductComponents"> | ||
| 7 | <ComponentRef Id="FirewallComponent1"/> | ||
| 8 | </ComponentGroup> | ||
| 9 | </Fragment> | ||
| 10 | |||
| 11 | <Fragment> | ||
| 12 | <Component Id="FirewallComponent1" Guid="A1553D10-BEB7-4E60-A0DC-6F1EEE5A1719" Directory="INSTALLFOLDER"> | ||
| 13 | <fw:FirewallException | ||
| 14 | Name="WiXToolset Test - 0028" OnUpdate="EnableOnly" | ||
| 15 | Port="[LOCALPORT]" | ||
| 16 | Protocol="[PROTOCOL]" | ||
| 17 | Program="[PROGRAM]" | ||
| 18 | Profile="[PROFILE]" | ||
| 19 | Description="[DESCRIPTION]" | ||
| 20 | Scope="[REMOTESCOPE]" | ||
| 21 | EdgeTraversal="[EDGETRAVERSAL]" | ||
| 22 | Enabled="[ENABLED]" | ||
| 23 | Grouping="[GROUPING]" | ||
| 24 | IcmpTypesAndCodes="[ICMPTYPES]" | ||
| 25 | Interface="[INTERFACE]" | ||
| 26 | InterfaceType="[INTERFACETYPE]" | ||
| 27 | LocalScope="[LOCALSCOPE]" | ||
| 28 | RemotePort="[REMOTEPORT]" | ||
| 29 | Service="[SERVICE]" | ||
| 30 | LocalAppPackageId="[PACKAGEID]" | ||
| 31 | LocalUserAuthorizedList="[LOCALUSERS]" | ||
| 32 | LocalUserOwner="[LOCALOWNER]" | ||
| 33 | RemoteMachineAuthorizedList="[REMOTEMACHINES]" | ||
| 34 | RemoteUserAuthorizedList="[REMOTEUSERS]" | ||
| 35 | IPSecSecureFlags="[SECUREFLAGS]" | ||
| 36 | /> | ||
| 37 | |||
| 38 | <fw:FirewallException Name="WiXToolset Test - 0029" OnUpdate="DoNothing" > | ||
| 39 | <fw:RemoteAddress Value="[REMOTEADDRESS]" /> | ||
| 40 | <fw:LocalAddress Value="[LOCALADDRESS]" /> | ||
| 41 | <fw:InterfaceType Value="[INTERFACETYPE]" /> | ||
| 42 | <fw:Interface Name="[INTERFACE]" /> | ||
| 43 | </fw:FirewallException> | ||
| 44 | |||
| 45 | <fw:FirewallException Name="WiXToolset Test - 0030" > | ||
| 46 | <fw:RemoteAddress Value="[REMOTEADDRESS1]" /> | ||
| 47 | <fw:RemoteAddress Value="[REMOTEADDRESS2]" /> | ||
| 48 | <fw:LocalAddress Value="[LOCALADDRESS1]" /> | ||
| 49 | <fw:LocalAddress Value="[LOCALADDRESS2]" /> | ||
| 50 | <fw:InterfaceType Value="[INTERFACETYPE1]" /> | ||
| 51 | <fw:InterfaceType Value="[INTERFACETYPE2]" /> | ||
| 52 | <fw:Interface Name="[INTERFACE1]" /> | ||
| 53 | <fw:Interface Name="[INTERFACE2]" /> | ||
| 54 | </fw:FirewallException> | ||
| 55 | </Component> | ||
| 56 | </Fragment> | ||
| 57 | </Wix> | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/Module401/Module401.wixproj b/src/test/msi/TestData/FirewallExtensionTests/Module401/Module401.wixproj new file mode 100644 index 00000000..5f65e657 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/Module401/Module401.wixproj | |||
| @@ -0,0 +1,10 @@ | |||
| 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 | <OutputType>Module</OutputType> | ||
| 5 | <SuppressSpecificWarnings>1072</SuppressSpecificWarnings> | ||
| 6 | </PropertyGroup> | ||
| 7 | <ItemGroup> | ||
| 8 | <PackageReference Include="WixToolset.Firewall.wixext"/><!--VersionOverride="4.0.1"--> | ||
| 9 | </ItemGroup> | ||
| 10 | </Project> \ No newline at end of file | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/Module401/data/test.txt b/src/test/msi/TestData/FirewallExtensionTests/Module401/data/test.txt new file mode 100644 index 00000000..cd0db0e1 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/Module401/data/test.txt | |||
| @@ -0,0 +1 @@ | |||
| This is test.txt. \ No newline at end of file | |||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/Module401/module.wxs b/src/test/msi/TestData/FirewallExtensionTests/Module401/module.wxs new file mode 100644 index 00000000..872743c7 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/Module401/module.wxs | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall" > | ||
| 2 | <Module Id="MergeModule1" Language="1033" Version="1.0.0.0" Guid="4B2C61BF-59F5-453B-98E3-3389F681EA00"> | ||
| 3 | <SummaryInformation Manufacturer="Module 4.0.1 Manufacturer" /> | ||
| 4 | |||
| 5 | <Property Id="MODULE401PORT1" Value="40101" /> | ||
| 6 | <Property Id="MODULE401PORT2" Value="40102" /> | ||
| 7 | <Property Id="MODULE401PORT3" Value="40103" /> | ||
| 8 | <Property Id="MODULE401PORT4" Value="40104" /> | ||
| 9 | |||
| 10 | <Directory Id="MergeRedirectFolder"> | ||
| 11 | <Component Id="ModuleComponent1" Guid="257F9283-1334-423C-A7E7-FEE848BCD37F"> | ||
| 12 | <File Id="File1" Name="file1.txt" Source="data/test.txt"> | ||
| 13 | <fw:FirewallException Id="FirewallException1" | ||
| 14 | Description="WiX Toolset firewall exception rule integration test - module 401 MergeRedirectFolder - app" | ||
| 15 | Name="WiXToolset401 Test - 0018" Scope="any" Port="[MODULE401PORT1]" /> | ||
| 16 | </File> | ||
| 17 | <fw:FirewallException Id="FirewallException2" | ||
| 18 | Description="WiX Toolset firewall exception rule integration test - module 401 MergeRedirectFolder - port" | ||
| 19 | Name="WiXToolset401 Test - 0019" Scope="any" Port="[MODULE401PORT2]" /> | ||
| 20 | </Component> | ||
| 21 | </Directory> | ||
| 22 | |||
| 23 | <Directory Id="NotTheMergeRedirectFolder"> | ||
| 24 | <Component Id="ModuleComponent2" Guid="48A2D573-0ADB-4010-84E3-96C3D6803E90"> | ||
| 25 | <File Id="File2" Name="file2.txt" Source="data/test.txt"> | ||
| 26 | <fw:FirewallException Id="FirewallException3" | ||
| 27 | Description="WiX Toolset firewall exception rule integration test - module 401 NotTheMergeRedirectFolder - app" | ||
| 28 | Name="WiXToolset401 Test - 0020" Scope="any" Port="[MODULE401PORT3]" /> | ||
| 29 | </File> | ||
| 30 | <fw:FirewallException Id="FirewallException4" | ||
| 31 | Description="WiX Toolset firewall exception rule integration test - module 401 NotTheMergeRedirectFolder - port" | ||
| 32 | Name="WiXToolset401 Test - 0021" Scope="any" Port="[MODULE401PORT4]" /> | ||
| 33 | </Component> | ||
| 34 | </Directory> | ||
| 35 | </Module> | ||
| 36 | </Wix> | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/ModuleCurrent.wixproj b/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/ModuleCurrent.wixproj new file mode 100644 index 00000000..8a84280c --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/ModuleCurrent.wixproj | |||
| @@ -0,0 +1,10 @@ | |||
| 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 | <OutputType>Module</OutputType> | ||
| 5 | <SuppressSpecificWarnings>1072</SuppressSpecificWarnings> | ||
| 6 | </PropertyGroup> | ||
| 7 | <ItemGroup> | ||
| 8 | <PackageReference Include="WixToolset.Firewall.wixext" /> | ||
| 9 | </ItemGroup> | ||
| 10 | </Project> \ No newline at end of file | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/data/test.txt b/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/data/test.txt new file mode 100644 index 00000000..cd0db0e1 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/data/test.txt | |||
| @@ -0,0 +1 @@ | |||
| This is test.txt. \ No newline at end of file | |||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/module.wxs b/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/module.wxs new file mode 100644 index 00000000..53097acd --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/ModuleCurrent/module.wxs | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall" > | ||
| 2 | <Module Id="MergeModule1" Language="1033" Version="1.0.0.0" Guid="44FA5DBE-2413-436E-99B3-A0751D6EB420"> | ||
| 3 | <SummaryInformation Manufacturer="Example Company - Module Current" /> | ||
| 4 | |||
| 5 | <Property Id="MODULECURRENTPORT1" Value="50001" /> | ||
| 6 | <Property Id="MODULECURRENTPORT2" Value="50002" /> | ||
| 7 | <Property Id="MODULECURRENTPORT3" Value="50003" /> | ||
| 8 | <Property Id="MODULECURRENTPORT4" Value="50004" /> | ||
| 9 | |||
| 10 | <Directory Id="MergeRedirectFolder"> | ||
| 11 | <Component Id="ModuleComponent1" Guid="EB7B8A63-85C4-4ABB-B9DA-33AECAFE38F7"> | ||
| 12 | <File Id="File1" Name="file1.txt" Source="data/test.txt"> | ||
| 13 | <fw:FirewallException Id="FirewallException1" | ||
| 14 | Description="WiX Toolset firewall exception rule integration test - module MergeRedirectFolder - app" | ||
| 15 | Name="WiXToolset Test - 0022" Scope="any" Port="[MODULECURRENTPORT1]" /> | ||
| 16 | </File> | ||
| 17 | <fw:FirewallException Id="FirewallException2" | ||
| 18 | Description="WiX Toolset firewall exception rule integration test - module MergeRedirectFolder - port" | ||
| 19 | Name="WiXToolset Test - 0023" Scope="any" Port="[MODULECURRENTPORT2]" /> | ||
| 20 | </Component> | ||
| 21 | </Directory> | ||
| 22 | |||
| 23 | <Directory Id="NotTheMergeRedirectFolder"> | ||
| 24 | <Component Id="ModuleComponent2" Guid="0C9DD4FC-5A54-4E96-830D-DDE27B3017B5"> | ||
| 25 | <File Id="File2" Name="file2.txt" Source="data/test.txt"> | ||
| 26 | <fw:FirewallException Id="FirewallException3" | ||
| 27 | Description="WiX Toolset firewall exception rule integration test - module NotTheMergeRedirectFolder - app" | ||
| 28 | Name="WiXToolset Test - 0024" Scope="any" Port="[MODULECURRENTPORT3]" /> | ||
| 29 | </File> | ||
| 30 | <fw:FirewallException Id="FirewallException4" | ||
| 31 | Description="WiX Toolset firewall exception rule integration test - module NotTheMergeRedirectFolder - port" | ||
| 32 | Name="WiXToolset Test - 0025" Scope="any" Port="[MODULECURRENTPORT4]" /> | ||
| 33 | </Component> | ||
| 34 | </Directory> | ||
| 35 | </Module> | ||
| 36 | </Wix> | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/NestedService/NestedService.wixproj b/src/test/msi/TestData/FirewallExtensionTests/NestedService/NestedService.wixproj new file mode 100644 index 00000000..4a9c9dbd --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/NestedService/NestedService.wixproj | |||
| @@ -0,0 +1,14 @@ | |||
| 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>{80635798-F904-4C4E-81D8-27A5106F3998}</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 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 13 | </ItemGroup> | ||
| 14 | </Project> \ No newline at end of file | ||
diff --git a/src/test/msi/TestData/FirewallExtensionTests/NestedService/product.wxs b/src/test/msi/TestData/FirewallExtensionTests/NestedService/product.wxs new file mode 100644 index 00000000..24559a33 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/NestedService/product.wxs | |||
| @@ -0,0 +1,25 @@ | |||
| 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 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" > | ||
| 5 | <Fragment> | ||
| 6 | <ComponentGroup Id="ProductComponents"> | ||
| 7 | <ComponentRef Id="FirewallComponent1"/> | ||
| 8 | </ComponentGroup> | ||
| 9 | </Fragment> | ||
| 10 | |||
| 11 | <Fragment> | ||
| 12 | <Component Id="FirewallComponent1" Guid="FD6E696A-8C42-49BF-B686-0DA5CD4B2C5A" Directory="INSTALLFOLDER" > | ||
| 13 | <fw:FirewallException Id="FirewallException1" Description="WiX Toolset firewall exception rule integration test - service property" | ||
| 14 | Name="WiXToolset Test - 0031" Service="Spooler"/> | ||
| 15 | <util:ServiceConfig ServiceName="Spooler" FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="none" > | ||
| 16 | <fw:FirewallException Id="FirewallException2" Description="WiX Toolset firewall exception rule integration test - ServiceConfig" | ||
| 17 | Name="WiXToolset Test - 0032" /> | ||
| 18 | </util:ServiceConfig> | ||
| 19 | <ServiceInstall Name="WixTestFirewallSrv" Type="ownProcess" Start="disabled" ErrorControl="ignore" Vital="no" Arguments="%WINDIR%\System32\spoolsv.exe" > | ||
| 20 | <fw:FirewallException Id="FirewallException3" Description="WiX Toolset firewall exception rule integration test - ServiceInstall" | ||
| 21 | Name="WiXToolset Test - 0033" /> | ||
| 22 | </ServiceInstall> | ||
| 23 | </Component> | ||
| 24 | </Fragment> | ||
| 25 | </Wix> | ||
diff --git a/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs b/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs index ce55aa14..380e6f4c 100644 --- a/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs +++ b/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs | |||
| @@ -4,6 +4,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 4 | { | 4 | { |
| 5 | using System; | 5 | using System; |
| 6 | using System.IO; | 6 | using System.IO; |
| 7 | using System.Linq; | ||
| 8 | using System.Net.NetworkInformation; | ||
| 7 | using NetFwTypeLib; | 9 | using NetFwTypeLib; |
| 8 | using WixTestTools; | 10 | using WixTestTools; |
| 9 | using WixTestTools.Firewall; | 11 | using WixTestTools.Firewall; |
| @@ -37,8 +39,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 37 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRules", "product.wxs")), | 39 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRules", "product.wxs")), |
| 38 | Description = "WiX Toolset firewall exception rule integration test - minimal app properties", | 40 | Description = "WiX Toolset firewall exception rule integration test - minimal app properties", |
| 39 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | 41 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, |
| 40 | EdgeTraversal = true, | 42 | EdgeTraversal = false, |
| 41 | EdgeTraversalOptions = 1, | 43 | EdgeTraversalOptions = 0, |
| 42 | Enabled = true, | 44 | Enabled = true, |
| 43 | InterfaceTypes = "All", | 45 | InterfaceTypes = "All", |
| 44 | LocalAddresses = "*", | 46 | LocalAddresses = "*", |
| @@ -124,8 +126,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 124 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRules", "product.wxs")), | 126 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRules", "product.wxs")), |
| 125 | Description = "WiX Toolset firewall exception rule integration test - minimal app properties", | 127 | Description = "WiX Toolset firewall exception rule integration test - minimal app properties", |
| 126 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | 128 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, |
| 127 | EdgeTraversal = true, | 129 | EdgeTraversal = false, |
| 128 | EdgeTraversalOptions = 1, | 130 | EdgeTraversalOptions = 0, |
| 129 | Enabled = true, | 131 | Enabled = true, |
| 130 | InterfaceTypes = "All", | 132 | InterfaceTypes = "All", |
| 131 | LocalAddresses = "*", | 133 | LocalAddresses = "*", |
| @@ -187,8 +189,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 187 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRules", "product.wxs")), | 189 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRules", "product.wxs")), |
| 188 | Description = "WiX Toolset firewall exception rule integration test - minimal app properties", | 190 | Description = "WiX Toolset firewall exception rule integration test - minimal app properties", |
| 189 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | 191 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, |
| 190 | EdgeTraversal = true, | 192 | EdgeTraversal = false, |
| 191 | EdgeTraversalOptions = 1, | 193 | EdgeTraversalOptions = 0, |
| 192 | Enabled = true, | 194 | Enabled = true, |
| 193 | InterfaceTypes = "All", | 195 | InterfaceTypes = "All", |
| 194 | LocalAddresses = "*", | 196 | LocalAddresses = "*", |
| @@ -213,8 +215,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 213 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("DynamicFirewallRules", "product.wxs")), | 215 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("DynamicFirewallRules", "product.wxs")), |
| 214 | Description = "WiX Toolset firewall exception rule integration test - dynamic app description 9999", | 216 | Description = "WiX Toolset firewall exception rule integration test - dynamic app description 9999", |
| 215 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | 217 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, |
| 216 | EdgeTraversal = true, | 218 | EdgeTraversal = false, |
| 217 | EdgeTraversalOptions = 1, | 219 | EdgeTraversalOptions = 0, |
| 218 | Enabled = true, | 220 | Enabled = true, |
| 219 | InterfaceTypes = "All", | 221 | InterfaceTypes = "All", |
| 220 | LocalAddresses = "*", | 222 | LocalAddresses = "*", |
| @@ -255,8 +257,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 255 | ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("windir"), "system32", "9999.exe"), | 257 | ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("windir"), "system32", "9999.exe"), |
| 256 | Description = "WiX Toolset firewall exception rule integration test - dynamic Name 9999", | 258 | Description = "WiX Toolset firewall exception rule integration test - dynamic Name 9999", |
| 257 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | 259 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, |
| 258 | EdgeTraversal = true, | 260 | EdgeTraversal = false, |
| 259 | EdgeTraversalOptions = 1, | 261 | EdgeTraversalOptions = 0, |
| 260 | Enabled = true, | 262 | Enabled = true, |
| 261 | InterfaceTypes = "All", | 263 | InterfaceTypes = "All", |
| 262 | LocalAddresses = "*", | 264 | LocalAddresses = "*", |
| @@ -285,10 +287,10 @@ namespace WixToolsetTest.MsiE2E | |||
| 285 | var log1 = product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | 287 | var log1 = product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); |
| 286 | 288 | ||
| 287 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0006 pipe")); | 289 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0006 pipe")); |
| 288 | Assert.True(LogVerifier.MessageInLogFile(log1, "failed to add app to the authorized apps list")); | 290 | Assert.True(LogVerifier.MessageInLogFile(log1, "failed to add firewall exception 'WiXToolset401 Test - 0006 pipe' to the list")); |
| 289 | 291 | ||
| 290 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0007 pipe")); | 292 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0007 pipe")); |
| 291 | Assert.True(LogVerifier.MessageInLogFile(log1, "failed to add app to the authorized ports list")); | 293 | Assert.True(LogVerifier.MessageInLogFile(log1, "failed to add firewall exception 'WiXToolset401 Test - 0007 pipe' to the list")); |
| 292 | 294 | ||
| 293 | var expected = new RuleDetails("WiXToolset401 Test - 0008 removal") | 295 | var expected = new RuleDetails("WiXToolset401 Test - 0008 removal") |
| 294 | { | 296 | { |
| @@ -296,8 +298,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 296 | ApplicationName = "test.exe", | 298 | ApplicationName = "test.exe", |
| 297 | Description = "WiX Toolset firewall exception rule integration test - removal test", | 299 | Description = "WiX Toolset firewall exception rule integration test - removal test", |
| 298 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | 300 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, |
| 299 | EdgeTraversal = true, | 301 | EdgeTraversal = false, |
| 300 | EdgeTraversalOptions = 1, | 302 | EdgeTraversalOptions = 0, |
| 301 | Enabled = true, | 303 | Enabled = true, |
| 302 | InterfaceTypes = "All", | 304 | InterfaceTypes = "All", |
| 303 | LocalPorts = "52390", | 305 | LocalPorts = "52390", |
| @@ -313,7 +315,7 @@ namespace WixToolsetTest.MsiE2E | |||
| 313 | Verifier.RemoveFirewallRuleByName("WiXToolset401 Test - 0008 removal"); | 315 | Verifier.RemoveFirewallRuleByName("WiXToolset401 Test - 0008 removal"); |
| 314 | 316 | ||
| 315 | var log2 = product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS, "NORULENAME=1"); | 317 | var log2 = product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS, "NORULENAME=1"); |
| 316 | Assert.True(LogVerifier.MessageInLogFile(log2, "failed to remove firewall rule")); | 318 | Assert.True(LogVerifier.MessageInLogFile(log2, "failed to remove firewall exception for name")); |
| 317 | } | 319 | } |
| 318 | 320 | ||
| 319 | [RuntimeFact] | 321 | [RuntimeFact] |
| @@ -370,8 +372,8 @@ namespace WixToolsetTest.MsiE2E | |||
| 370 | ApplicationName = "test.exe", | 372 | ApplicationName = "test.exe", |
| 371 | Description = "WiX Toolset firewall exception rule integration test - ports can only be specified if protocol is TCP or UDP", | 373 | Description = "WiX Toolset firewall exception rule integration test - ports can only be specified if protocol is TCP or UDP", |
| 372 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | 374 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, |
| 373 | EdgeTraversal = true, | 375 | EdgeTraversal = false, |
| 374 | EdgeTraversalOptions = 1, | 376 | EdgeTraversalOptions = 0, |
| 375 | Enabled = true, | 377 | Enabled = true, |
| 376 | InterfaceTypes = "All", | 378 | InterfaceTypes = "All", |
| 377 | LocalAddresses = "*", | 379 | LocalAddresses = "*", |
| @@ -532,5 +534,609 @@ namespace WixToolsetTest.MsiE2E | |||
| 532 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0016")); | 534 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0016")); |
| 533 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0017")); | 535 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0017")); |
| 534 | } | 536 | } |
| 537 | |||
| 538 | [RuntimeFact] | ||
| 539 | public void CanInstallAndUninstallFirewallRulesWithInterfaces() | ||
| 540 | { | ||
| 541 | var names = NetworkInterface.GetAllNetworkInterfaces() | ||
| 542 | .Take(3) | ||
| 543 | .Select(ni => ni.Name); | ||
| 544 | |||
| 545 | var props = names.Select((name, idx) => $"INTERFACE{idx + 1}=\"{name}\"") | ||
| 546 | .Concat(new[] { "INTERFACETYPE=Lan" }).ToArray(); | ||
| 547 | |||
| 548 | var product = this.CreatePackageInstaller("FirewallRulesInterfaces"); | ||
| 549 | product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS, props); | ||
| 550 | |||
| 551 | var expected1 = new RuleDetails("WiXToolset500 Test - 0028") | ||
| 552 | { | ||
| 553 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 554 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRulesInterfaces", "product.wxs")), | ||
| 555 | Description = "WiX Toolset firewall exception rule integration test - three interfaces", | ||
| 556 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 557 | EdgeTraversal = false, | ||
| 558 | EdgeTraversalOptions = 0, | ||
| 559 | Enabled = true, | ||
| 560 | InterfaceTypes = "Lan,Wireless,RemoteAccess", | ||
| 561 | Interfaces = names.ToArray<object>(), | ||
| 562 | LocalAddresses = "*", | ||
| 563 | Profiles = Int32.MaxValue, | ||
| 564 | Protocol = 256, | ||
| 565 | RemoteAddresses = "*", | ||
| 566 | SecureFlags = 0, | ||
| 567 | }; | ||
| 568 | |||
| 569 | Verifier.VerifyFirewallRule("WiXToolset500 Test - 0028", expected1); | ||
| 570 | |||
| 571 | var expected2 = new RuleDetails("WiXToolset500 Test - 0029") | ||
| 572 | { | ||
| 573 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 574 | Description = "WiX Toolset firewall exception rule integration test - one interface", | ||
| 575 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 576 | EdgeTraversal = false, | ||
| 577 | EdgeTraversalOptions = 0, | ||
| 578 | Enabled = true, | ||
| 579 | InterfaceTypes = "Lan", | ||
| 580 | Interfaces = names.Take(1).ToArray<object>(), | ||
| 581 | LocalAddresses = "*", | ||
| 582 | LocalPorts = "29292", | ||
| 583 | Profiles = Int32.MaxValue, | ||
| 584 | Protocol = 6, | ||
| 585 | RemoteAddresses = "*", | ||
| 586 | RemotePorts = "*", | ||
| 587 | SecureFlags = 0, | ||
| 588 | }; | ||
| 589 | |||
| 590 | Verifier.VerifyFirewallRule("WiXToolset500 Test - 0029", expected2); | ||
| 591 | |||
| 592 | props = names.Take(1).Select((name, idx) => $"INTERFACE{idx + 2}=\"{name}\"").ToArray(); | ||
| 593 | |||
| 594 | product.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS, props); | ||
| 595 | |||
| 596 | var expected3 = new RuleDetails("WiXToolset500 Test - 0028") | ||
| 597 | { | ||
| 598 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 599 | ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("FirewallRulesInterfaces", "product.wxs")), | ||
| 600 | Description = "WiX Toolset firewall exception rule integration test - three interfaces", | ||
| 601 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 602 | EdgeTraversal = false, | ||
| 603 | EdgeTraversalOptions = 0, | ||
| 604 | Enabled = true, | ||
| 605 | InterfaceTypes = "Lan,Wireless,RemoteAccess", | ||
| 606 | Interfaces = names.Take(1).ToArray<object>(), | ||
| 607 | LocalAddresses = "*", | ||
| 608 | Profiles = Int32.MaxValue, | ||
| 609 | Protocol = 256, | ||
| 610 | RemoteAddresses = "*", | ||
| 611 | SecureFlags = 0, | ||
| 612 | }; | ||
| 613 | |||
| 614 | Verifier.VerifyFirewallRule("WiXToolset500 Test - 0028", expected3); | ||
| 615 | |||
| 616 | var expected4 = new RuleDetails("WiXToolset500 Test - 0029") | ||
| 617 | { | ||
| 618 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 619 | Description = "WiX Toolset firewall exception rule integration test - one interface", | ||
| 620 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 621 | EdgeTraversal = false, | ||
| 622 | EdgeTraversalOptions = 0, | ||
| 623 | Enabled = true, | ||
| 624 | InterfaceTypes = "All", | ||
| 625 | LocalAddresses = "*", | ||
| 626 | LocalPorts = "29292", | ||
| 627 | Profiles = Int32.MaxValue, | ||
| 628 | Protocol = 6, | ||
| 629 | RemoteAddresses = "*", | ||
| 630 | RemotePorts = "*", | ||
| 631 | SecureFlags = 0, | ||
| 632 | }; | ||
| 633 | |||
| 634 | Verifier.VerifyFirewallRule("WiXToolset500 Test - 0029", expected4); | ||
| 635 | |||
| 636 | product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 637 | |||
| 638 | // verify the firewall exceptions have been removed. | ||
| 639 | Assert.False(Verifier.FirewallRuleExists("WiXToolset500 Test - 0028")); | ||
| 640 | Assert.False(Verifier.FirewallRuleExists("WiXToolset500 Test - 0029")); | ||
| 641 | } | ||
| 642 | |||
| 643 | [RuntimeFact] | ||
| 644 | public void CanInstallAndUninstallFirewallRulesPackagedByDifferentModules() | ||
| 645 | { | ||
| 646 | var product = this.CreatePackageInstaller("CrossVersionMerge"); | ||
| 647 | product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 648 | |||
| 649 | // Validate new firewall exception details. | ||
| 650 | var expected1 = new RuleDetails("WiXToolset401 Test - 0018") | ||
| 651 | { | ||
| 652 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 653 | ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), "MsiPackage", "file1.txt"), | ||
| 654 | Description = "WiX Toolset firewall exception rule integration test - module 401 MergeRedirectFolder - app", | ||
| 655 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 656 | EdgeTraversal = true, | ||
| 657 | EdgeTraversalOptions = 1, | ||
| 658 | Enabled = true, | ||
| 659 | InterfaceTypes = "All", | ||
| 660 | LocalAddresses = "*", | ||
| 661 | LocalPorts = "40101", | ||
| 662 | Profiles = Int32.MaxValue, | ||
| 663 | Protocol = 6, | ||
| 664 | RemoteAddresses = "*", | ||
| 665 | RemotePorts = "*", | ||
| 666 | SecureFlags = 0, | ||
| 667 | }; | ||
| 668 | |||
| 669 | Verifier.VerifyFirewallRule("WiXToolset401 Test - 0018", expected1); | ||
| 670 | |||
| 671 | var expected2 = new RuleDetails("WiXToolset401 Test - 0019") | ||
| 672 | { | ||
| 673 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 674 | Description = "WiX Toolset firewall exception rule integration test - module 401 MergeRedirectFolder - port", | ||
| 675 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 676 | EdgeTraversal = false, | ||
| 677 | EdgeTraversalOptions = 0, | ||
| 678 | Enabled = true, | ||
| 679 | InterfaceTypes = "All", | ||
| 680 | LocalAddresses = "*", | ||
| 681 | LocalPorts = "40102", | ||
| 682 | Profiles = Int32.MaxValue, | ||
| 683 | Protocol = 6, | ||
| 684 | RemoteAddresses = "*", | ||
| 685 | RemotePorts = "*", | ||
| 686 | SecureFlags = 0, | ||
| 687 | }; | ||
| 688 | |||
| 689 | Verifier.VerifyFirewallRule("WiXToolset401 Test - 0019", expected2); | ||
| 690 | |||
| 691 | var expected3 = new RuleDetails("WiXToolset401 Test - 0020") | ||
| 692 | { | ||
| 693 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 694 | ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), "MsiPackage", "file2.txt"), | ||
| 695 | Description = "WiX Toolset firewall exception rule integration test - module 401 NotTheMergeRedirectFolder - app", | ||
| 696 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 697 | EdgeTraversal = true, | ||
| 698 | EdgeTraversalOptions = 1, | ||
| 699 | Enabled = true, | ||
| 700 | InterfaceTypes = "All", | ||
| 701 | LocalAddresses = "*", | ||
| 702 | LocalPorts = "40103", | ||
| 703 | Profiles = Int32.MaxValue, | ||
| 704 | Protocol = 6, | ||
| 705 | RemoteAddresses = "*", | ||
| 706 | RemotePorts = "*", | ||
| 707 | SecureFlags = 0, | ||
| 708 | }; | ||
| 709 | |||
| 710 | Verifier.VerifyFirewallRule("WiXToolset401 Test - 0020", expected3); | ||
| 711 | |||
| 712 | var expected4 = new RuleDetails("WiXToolset401 Test - 0021") | ||
| 713 | { | ||
| 714 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 715 | Description = "WiX Toolset firewall exception rule integration test - module 401 NotTheMergeRedirectFolder - port", | ||
| 716 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 717 | EdgeTraversal = false, | ||
| 718 | EdgeTraversalOptions = 0, | ||
| 719 | Enabled = true, | ||
| 720 | InterfaceTypes = "All", | ||
| 721 | LocalAddresses = "*", | ||
| 722 | LocalPorts = "40104", | ||
| 723 | Profiles = Int32.MaxValue, | ||
| 724 | Protocol = 6, | ||
| 725 | RemoteAddresses = "*", | ||
| 726 | RemotePorts = "*", | ||
| 727 | SecureFlags = 0, | ||
| 728 | }; | ||
| 729 | |||
| 730 | Verifier.VerifyFirewallRule("WiXToolset401 Test - 0021", expected4); | ||
| 731 | |||
| 732 | var expected5 = new RuleDetails("WiXToolset Test - 0022") | ||
| 733 | { | ||
| 734 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 735 | ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), "MsiPackage", "file1.txt"), | ||
| 736 | Description = "WiX Toolset firewall exception rule integration test - module MergeRedirectFolder - app", | ||
| 737 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 738 | EdgeTraversal = false, | ||
| 739 | EdgeTraversalOptions = 0, | ||
| 740 | Enabled = true, | ||
| 741 | InterfaceTypes = "All", | ||
| 742 | LocalAddresses = "*", | ||
| 743 | LocalPorts = "50001", | ||
| 744 | Profiles = Int32.MaxValue, | ||
| 745 | Protocol = 6, | ||
| 746 | RemoteAddresses = "*", | ||
| 747 | RemotePorts = "*", | ||
| 748 | SecureFlags = 0, | ||
| 749 | }; | ||
| 750 | |||
| 751 | Verifier.VerifyFirewallRule("WiXToolset Test - 0022", expected5); | ||
| 752 | |||
| 753 | var expected6 = new RuleDetails("WiXToolset Test - 0023") | ||
| 754 | { | ||
| 755 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 756 | Description = "WiX Toolset firewall exception rule integration test - module MergeRedirectFolder - port", | ||
| 757 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 758 | EdgeTraversal = false, | ||
| 759 | EdgeTraversalOptions = 0, | ||
| 760 | Enabled = true, | ||
| 761 | InterfaceTypes = "All", | ||
| 762 | LocalAddresses = "*", | ||
| 763 | LocalPorts = "50002", | ||
| 764 | Profiles = Int32.MaxValue, | ||
| 765 | Protocol = 6, | ||
| 766 | RemoteAddresses = "*", | ||
| 767 | RemotePorts = "*", | ||
| 768 | SecureFlags = 0, | ||
| 769 | }; | ||
| 770 | |||
| 771 | Verifier.VerifyFirewallRule("WiXToolset Test - 0023", expected6); | ||
| 772 | |||
| 773 | var expected7 = new RuleDetails("WiXToolset Test - 0024") | ||
| 774 | { | ||
| 775 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 776 | ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), "MsiPackage", "file2.txt"), | ||
| 777 | Description = "WiX Toolset firewall exception rule integration test - module NotTheMergeRedirectFolder - app", | ||
| 778 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 779 | EdgeTraversal = false, | ||
| 780 | EdgeTraversalOptions = 0, | ||
| 781 | Enabled = true, | ||
| 782 | InterfaceTypes = "All", | ||
| 783 | LocalAddresses = "*", | ||
| 784 | LocalPorts = "50003", | ||
| 785 | Profiles = Int32.MaxValue, | ||
| 786 | Protocol = 6, | ||
| 787 | RemoteAddresses = "*", | ||
| 788 | RemotePorts = "*", | ||
| 789 | SecureFlags = 0, | ||
| 790 | }; | ||
| 791 | |||
| 792 | Verifier.VerifyFirewallRule("WiXToolset Test - 0024", expected7); | ||
| 793 | |||
| 794 | var expected8 = new RuleDetails("WiXToolset Test - 0025") | ||
| 795 | { | ||
| 796 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 797 | Description = "WiX Toolset firewall exception rule integration test - module NotTheMergeRedirectFolder - port", | ||
| 798 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 799 | EdgeTraversal = false, | ||
| 800 | EdgeTraversalOptions = 0, | ||
| 801 | Enabled = true, | ||
| 802 | InterfaceTypes = "All", | ||
| 803 | LocalAddresses = "*", | ||
| 804 | LocalPorts = "50004", | ||
| 805 | Profiles = Int32.MaxValue, | ||
| 806 | Protocol = 6, | ||
| 807 | RemoteAddresses = "*", | ||
| 808 | RemotePorts = "*", | ||
| 809 | SecureFlags = 0, | ||
| 810 | }; | ||
| 811 | |||
| 812 | Verifier.VerifyFirewallRule("WiXToolset Test - 0025", expected8); | ||
| 813 | |||
| 814 | var expected9 = new RuleDetails("WiXToolset Test - 0026") | ||
| 815 | { | ||
| 816 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 817 | ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), "MsiPackage", "package.wxs"), | ||
| 818 | Description = "WiX Toolset firewall exception rule integration test - package app", | ||
| 819 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 820 | EdgeTraversal = false, | ||
| 821 | EdgeTraversalOptions = 0, | ||
| 822 | Enabled = true, | ||
| 823 | InterfaceTypes = "All", | ||
| 824 | LocalAddresses = "*", | ||
| 825 | LocalPorts = "20001", | ||
| 826 | Profiles = Int32.MaxValue, | ||
| 827 | Protocol = 6, | ||
| 828 | RemoteAddresses = "*", | ||
| 829 | RemotePorts = "*", | ||
| 830 | SecureFlags = 0, | ||
| 831 | }; | ||
| 832 | |||
| 833 | Verifier.VerifyFirewallRule("WiXToolset Test - 0026", expected9); | ||
| 834 | |||
| 835 | var expected10 = new RuleDetails("WiXToolset Test - 0027") | ||
| 836 | { | ||
| 837 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 838 | Description = "WiX Toolset firewall exception rule integration test - package port", | ||
| 839 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 840 | EdgeTraversal = false, | ||
| 841 | EdgeTraversalOptions = 0, | ||
| 842 | Enabled = true, | ||
| 843 | InterfaceTypes = "All", | ||
| 844 | LocalAddresses = "*", | ||
| 845 | LocalPorts = "20002", | ||
| 846 | Profiles = Int32.MaxValue, | ||
| 847 | Protocol = 6, | ||
| 848 | RemoteAddresses = "*", | ||
| 849 | RemotePorts = "*", | ||
| 850 | SecureFlags = 0, | ||
| 851 | }; | ||
| 852 | |||
| 853 | Verifier.VerifyFirewallRule("WiXToolset Test - 0027", expected10); | ||
| 854 | |||
| 855 | product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 856 | |||
| 857 | // verify the firewall exceptions have been removed. | ||
| 858 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0018")); | ||
| 859 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0019")); | ||
| 860 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0020")); | ||
| 861 | Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0021")); | ||
| 862 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0022")); | ||
| 863 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0023")); | ||
| 864 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0024")); | ||
| 865 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0025")); | ||
| 866 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0026")); | ||
| 867 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0027")); | ||
| 868 | } | ||
| 869 | |||
| 870 | [RuntimeFact] | ||
| 871 | public void ServiceNameIsPassedIntoNestedRules() | ||
| 872 | { | ||
| 873 | var product = this.CreatePackageInstaller("NestedService"); | ||
| 874 | product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 875 | |||
| 876 | var expected1 = new RuleDetails("WiXToolset Test - 0031") | ||
| 877 | { | ||
| 878 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 879 | Protocol = 256, | ||
| 880 | LocalAddresses = "*", | ||
| 881 | RemoteAddresses = "*", | ||
| 882 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 883 | Description = "WiX Toolset firewall exception rule integration test - service property", | ||
| 884 | EdgeTraversal = false, | ||
| 885 | EdgeTraversalOptions = 0, | ||
| 886 | Enabled = true, | ||
| 887 | InterfaceTypes = "All", | ||
| 888 | Profiles = Int32.MaxValue, | ||
| 889 | SecureFlags = 0, | ||
| 890 | ServiceName = "Spooler", | ||
| 891 | }; | ||
| 892 | |||
| 893 | Verifier.VerifyFirewallRule("WiXToolset Test - 0031", expected1); | ||
| 894 | |||
| 895 | var expected2 = new RuleDetails("WiXToolset Test - 0032") | ||
| 896 | { | ||
| 897 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 898 | Protocol = 256, | ||
| 899 | LocalAddresses = "*", | ||
| 900 | RemoteAddresses = "*", | ||
| 901 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 902 | Description = "WiX Toolset firewall exception rule integration test - ServiceConfig", | ||
| 903 | EdgeTraversal = false, | ||
| 904 | EdgeTraversalOptions = 0, | ||
| 905 | Enabled = true, | ||
| 906 | InterfaceTypes = "All", | ||
| 907 | Profiles = Int32.MaxValue, | ||
| 908 | SecureFlags = 0, | ||
| 909 | ServiceName = "Spooler", | ||
| 910 | }; | ||
| 911 | |||
| 912 | Verifier.VerifyFirewallRule("WiXToolset Test - 0032", expected2); | ||
| 913 | |||
| 914 | var expected3 = new RuleDetails("WiXToolset Test - 0033") | ||
| 915 | { | ||
| 916 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 917 | Protocol = 256, | ||
| 918 | LocalAddresses = "*", | ||
| 919 | RemoteAddresses = "*", | ||
| 920 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 921 | Description = "WiX Toolset firewall exception rule integration test - ServiceInstall", | ||
| 922 | EdgeTraversal = false, | ||
| 923 | EdgeTraversalOptions = 0, | ||
| 924 | Enabled = true, | ||
| 925 | InterfaceTypes = "All", | ||
| 926 | Profiles = Int32.MaxValue, | ||
| 927 | SecureFlags = 0, | ||
| 928 | ServiceName = "WixTestFirewallSrv", | ||
| 929 | }; | ||
| 930 | |||
| 931 | Verifier.VerifyFirewallRule("WiXToolset Test - 0033", expected3); | ||
| 932 | |||
| 933 | product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 934 | |||
| 935 | // verify the firewall exceptions have been removed. | ||
| 936 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0031")); | ||
| 937 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0032")); | ||
| 938 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0033")); | ||
| 939 | } | ||
| 940 | |||
| 941 | [RuntimeFact] | ||
| 942 | public void SucceedWhenEnableOnlyFlagIsSet() | ||
| 943 | { | ||
| 944 | var product = this.CreatePackageInstaller("FirewallRulesProperties"); | ||
| 945 | product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 946 | |||
| 947 | var expected1 = new RuleDetails("WiXToolset Test - 0028") | ||
| 948 | { | ||
| 949 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 950 | Protocol = 256, | ||
| 951 | LocalAddresses = "*", | ||
| 952 | RemoteAddresses = "*", | ||
| 953 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 954 | EdgeTraversal = false, | ||
| 955 | EdgeTraversalOptions = 0, | ||
| 956 | Enabled = true, | ||
| 957 | InterfaceTypes = "All", | ||
| 958 | Profiles = Int32.MaxValue, | ||
| 959 | SecureFlags = 0, | ||
| 960 | }; | ||
| 961 | |||
| 962 | Verifier.VerifyFirewallRule("WiXToolset Test - 0028", expected1); | ||
| 963 | |||
| 964 | Verifier.DisableFirewallRule("WiXToolset Test - 0028"); | ||
| 965 | |||
| 966 | var args = new[] | ||
| 967 | { | ||
| 968 | "LOCALPORT=3456", | ||
| 969 | "PROTOCOL=6", | ||
| 970 | "PROGRAM=ShouldBeUnchanged", | ||
| 971 | "PROFILE=2", | ||
| 972 | "DESCRIPTION=ShouldBeUnchanged", | ||
| 973 | "REMOTESCOPE=ShouldBeUnchanged", | ||
| 974 | "EDGETRAVERSAL=3", | ||
| 975 | "ENABLED=1", | ||
| 976 | "GROUPING=ShouldBeUnchanged", | ||
| 977 | "ICMPTYPES=ShouldBeUnchanged", | ||
| 978 | "INTERFACE=ShouldBeUnchanged", | ||
| 979 | "INTERFACETYPE=ShouldBeUnchanged", | ||
| 980 | "LOCALSCOPE=ShouldBeUnchanged", | ||
| 981 | "REMOTEPORT=60000", | ||
| 982 | "SERVICE=ShouldBeUnchanged", | ||
| 983 | "PACKAGEID=ShouldBeUnchanged", | ||
| 984 | "LOCALUSERS=ShouldBeUnchanged", | ||
| 985 | "LOCALOWNER=ShouldBeUnchanged", | ||
| 986 | "REMOTEMACHINES=ShouldBeUnchanged", | ||
| 987 | "REMOTEUSERS=ShouldBeUnchanged", | ||
| 988 | "SECUREFLAGS=15", | ||
| 989 | "REMOTEADDRESS=ShouldBeUnchanged", | ||
| 990 | "LOCALADDRESS=ShouldBeUnchanged", | ||
| 991 | }; | ||
| 992 | |||
| 993 | product.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS, args); | ||
| 994 | |||
| 995 | var expected2 = new RuleDetails("WiXToolset Test - 0028") | ||
| 996 | { | ||
| 997 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 998 | Protocol = 256, | ||
| 999 | LocalAddresses = "*", | ||
| 1000 | RemoteAddresses = "*", | ||
| 1001 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 1002 | EdgeTraversal = false, | ||
| 1003 | EdgeTraversalOptions = 0, | ||
| 1004 | Enabled = true, | ||
| 1005 | InterfaceTypes = "All", | ||
| 1006 | Profiles = Int32.MaxValue, | ||
| 1007 | SecureFlags = 0, | ||
| 1008 | }; | ||
| 1009 | |||
| 1010 | Verifier.VerifyFirewallRule("WiXToolset Test - 0028", expected2); | ||
| 1011 | |||
| 1012 | product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 1013 | |||
| 1014 | // verify the firewall exceptions have been removed. | ||
| 1015 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0028")); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | [RuntimeFact] | ||
| 1019 | public void SucceedWhenDoNothingFlagIsSet() | ||
| 1020 | { | ||
| 1021 | var product = this.CreatePackageInstaller("FirewallRulesProperties"); | ||
| 1022 | product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 1023 | |||
| 1024 | var expected1 = new RuleDetails("WiXToolset Test - 0029") | ||
| 1025 | { | ||
| 1026 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 1027 | Protocol = 256, | ||
| 1028 | LocalAddresses = "*", | ||
| 1029 | RemoteAddresses = "*", | ||
| 1030 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 1031 | EdgeTraversal = false, | ||
| 1032 | EdgeTraversalOptions = 0, | ||
| 1033 | Enabled = true, | ||
| 1034 | InterfaceTypes = "All", | ||
| 1035 | Profiles = Int32.MaxValue, | ||
| 1036 | SecureFlags = 0, | ||
| 1037 | }; | ||
| 1038 | |||
| 1039 | Verifier.VerifyFirewallRule("WiXToolset Test - 0029", expected1); | ||
| 1040 | Verifier.DisableFirewallRule("WiXToolset Test - 0029"); | ||
| 1041 | |||
| 1042 | var args = new[] | ||
| 1043 | { | ||
| 1044 | "INTERFACE=ShouldBeUnchanged", | ||
| 1045 | "INTERFACETYPE=ShouldBeUnchanged", | ||
| 1046 | "REMOTEADDRESS=ShouldBeUnchanged", | ||
| 1047 | "LOCALADDRESS=ShouldBeUnchanged", | ||
| 1048 | }; | ||
| 1049 | |||
| 1050 | product.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS, args); | ||
| 1051 | |||
| 1052 | var expected2 = new RuleDetails("WiXToolset Test - 0029") | ||
| 1053 | { | ||
| 1054 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 1055 | Protocol = 256, | ||
| 1056 | LocalAddresses = "*", | ||
| 1057 | RemoteAddresses = "*", | ||
| 1058 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 1059 | EdgeTraversal = false, | ||
| 1060 | EdgeTraversalOptions = 0, | ||
| 1061 | Enabled = false, // remains as disabled after the repair | ||
| 1062 | InterfaceTypes = "All", | ||
| 1063 | Profiles = Int32.MaxValue, | ||
| 1064 | SecureFlags = 0, | ||
| 1065 | }; | ||
| 1066 | |||
| 1067 | Verifier.VerifyFirewallRule("WiXToolset Test - 0029", expected2); | ||
| 1068 | |||
| 1069 | product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 1070 | |||
| 1071 | // verify the firewall exceptions have been removed. | ||
| 1072 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0029")); | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | [RuntimeFact] | ||
| 1076 | public void SucceedWhenNoFlagIsSet() | ||
| 1077 | { | ||
| 1078 | var product = this.CreatePackageInstaller("FirewallRulesProperties"); | ||
| 1079 | product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 1080 | |||
| 1081 | var expected1 = new RuleDetails("WiXToolset Test - 0030") | ||
| 1082 | { | ||
| 1083 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 1084 | Protocol = 256, | ||
| 1085 | LocalAddresses = "*", | ||
| 1086 | RemoteAddresses = "*", | ||
| 1087 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 1088 | EdgeTraversal = false, | ||
| 1089 | EdgeTraversalOptions = 0, | ||
| 1090 | Enabled = true, | ||
| 1091 | InterfaceTypes = "All", | ||
| 1092 | Profiles = Int32.MaxValue, | ||
| 1093 | SecureFlags = 0, | ||
| 1094 | }; | ||
| 1095 | |||
| 1096 | Verifier.VerifyFirewallRule("WiXToolset Test - 0030", expected1); | ||
| 1097 | Verifier.DisableFirewallRule("WiXToolset Test - 0030"); | ||
| 1098 | |||
| 1099 | var names = NetworkInterface.GetAllNetworkInterfaces() | ||
| 1100 | .Take(2) | ||
| 1101 | .Select(ni => ni.Name); | ||
| 1102 | |||
| 1103 | var args = names.Select((name, idx) => $"INTERFACE{idx + 1}=\"{name}\"") | ||
| 1104 | .Concat(new[] | ||
| 1105 | { | ||
| 1106 | "INTERFACETYPE1=Wireless", | ||
| 1107 | "INTERFACETYPE2=Lan", | ||
| 1108 | "REMOTEADDRESS1=DHCP", | ||
| 1109 | "REMOTEADDRESS2=LocalSubnet", | ||
| 1110 | "LOCALADDRESS1=127.0.0.1", | ||
| 1111 | "LOCALADDRESS2=192.168.1.1", | ||
| 1112 | }) | ||
| 1113 | .ToArray(); | ||
| 1114 | |||
| 1115 | product.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS, args); | ||
| 1116 | |||
| 1117 | var expected2 = new RuleDetails("WiXToolset Test - 0030") | ||
| 1118 | { | ||
| 1119 | Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, | ||
| 1120 | Protocol = 256, | ||
| 1121 | LocalAddresses = "127.0.0.1/255.255.255.255,192.168.1.1/255.255.255.255", | ||
| 1122 | RemoteAddresses = "LocalSubnet,DHCP", | ||
| 1123 | Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, | ||
| 1124 | Description = "", | ||
| 1125 | EdgeTraversal = false, | ||
| 1126 | EdgeTraversalOptions = 0, | ||
| 1127 | Enabled = true, | ||
| 1128 | Interfaces = names.ToArray(), | ||
| 1129 | InterfaceTypes = "Lan,Wireless", | ||
| 1130 | Profiles = Int32.MaxValue, | ||
| 1131 | SecureFlags = 0, | ||
| 1132 | }; | ||
| 1133 | |||
| 1134 | Verifier.VerifyFirewallRule("WiXToolset Test - 0030", expected2); | ||
| 1135 | |||
| 1136 | product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); | ||
| 1137 | |||
| 1138 | // verify the firewall exceptions have been removed. | ||
| 1139 | Assert.False(Verifier.FirewallRuleExists("WiXToolset Test - 0030")); | ||
| 1140 | } | ||
| 535 | } | 1141 | } |
| 536 | } | 1142 | } |
diff --git a/src/test/msi/WixToolsetTest.MsiE2E/WixToolsetTest.MsiE2E.csproj b/src/test/msi/WixToolsetTest.MsiE2E/WixToolsetTest.MsiE2E.csproj index a5536de4..7d4695d3 100644 --- a/src/test/msi/WixToolsetTest.MsiE2E/WixToolsetTest.MsiE2E.csproj +++ b/src/test/msi/WixToolsetTest.MsiE2E/WixToolsetTest.MsiE2E.csproj | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | <ItemGroup> | 30 | <ItemGroup> |
| 31 | <PackageReference Include="Microsoft.Win32.Registry" /> | 31 | <PackageReference Include="Microsoft.Win32.Registry" /> |
| 32 | <PackageReference Include="System.Net.NetworkInformation" /> | ||
| 32 | <PackageReference Include="System.Security.Principal.Windows" /> | 33 | <PackageReference Include="System.Security.Principal.Windows" /> |
| 33 | <PackageReference Include="WixInternal.TestSupport" /> | 34 | <PackageReference Include="WixInternal.TestSupport" /> |
| 34 | <PackageReference Include="WixToolset.Data" /> | 35 | <PackageReference Include="WixToolset.Data" /> |
