1 /*
2 liteFirewall is based on nsisFirewall.
3 Modified by Liang Sun on 19, July, 2011
4 http://liangsun.info/portfolio/nsis-plugin-litefirewall/
5 http://nsis.sourceforge.net/LiteFirewall_Plugin
6 http://www.msnlite.org
7 */
8
9 /*
10 nsisFirewall -- Small NSIS plugin for simple tasks with Windows Firewall
11 Web site: http://wiz0u.free.fr/prog/nsisFirewall
12
13 Copyright (c) 2007-2009 Olivier Marcoux
14
15 This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
16
17 Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
18
19 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
20
21 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
22
23 3. This notice may not be removed or altered from any source distribution.
24 */
25 #include <windows.h>
26 #include <tchar.h>
27 #include <shlwapi.h>
28 //#include <stdio.h>
29
30 #ifdef NSIS
31 #include "exdll.h"
32 #endif
33
34 //#import "libid:58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08"
35 #import "netfw.tlb"
36 #include <netfw.h>
37 using namespace NetFwTypeLib;
38
39
40 #pragma comment( lib, "ole32.lib" )
41 #pragma comment( lib, "oleaut32.lib" )
42 // Forward declarations
43
44 #ifdef NSIS
45 HINSTANCE g_hInstance;
46 #endif
47
48 HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2);
49
AddRule(LPCTSTR ExceptionName,LPCTSTR ProcessPath)50 HRESULT AddRule(LPCTSTR ExceptionName, LPCTSTR ProcessPath)
51 {
52 HRESULT result = CoInitialize(NULL);
53 if (FAILED(result))
54 return result;
55 result = REGDB_E_CLASSNOTREG;
56
57 HRESULT hrComInit = S_OK;
58 HRESULT hr = S_OK;
59
60 INetFwPolicy2 *pNetFwPolicy2 = NULL;
61 INetFwRules *pFwRules = NULL;
62 INetFwRule *pFwRule = NULL;
63 /* Start Mozilla modification */
64 INetFwRule *pFwRuleExisting = NULL;
65
66 // long CurrentProfilesBitMask = 0;
67 /* End Mozilla modification */
68
69 BSTR bstrRuleName = SysAllocString(ExceptionName);
70 BSTR bstrApplicationName = SysAllocString(ProcessPath);
71 BSTR bstrRuleInterfaceType = SysAllocString(L"All");
72
73 // Initialize COM.
74 hrComInit = CoInitializeEx(
75 0,
76 COINIT_APARTMENTTHREADED
77 );
78
79 // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
80 // initialized with a different mode. Since we don't care what the mode is,
81 // we'll just use the existing mode.
82 if (hrComInit != RPC_E_CHANGED_MODE)
83 {
84 if (FAILED(hrComInit))
85 {
86 printf("CoInitializeEx failed: 0x%08lx\n", hrComInit);
87 goto Cleanup;
88 }
89 }
90
91 // Retrieve INetFwPolicy2
92 hr = WFCOMInitialize(&pNetFwPolicy2);
93 if (FAILED(hr))
94 {
95 try
96 {
97 INetFwMgrPtr fwMgr(L"HNetCfg.FwMgr");
98 if (fwMgr)
99 {
100 INetFwAuthorizedApplicationPtr app(L"HNetCfg.FwAuthorizedApplication");
101 if (app)
102 {
103 app->ProcessImageFileName = ProcessPath;
104 app->Name = ExceptionName;
105 app->Scope = NetFwTypeLib::NET_FW_SCOPE_ALL;
106 app->IpVersion = NetFwTypeLib::NET_FW_IP_VERSION_ANY;
107 app->Enabled = VARIANT_TRUE;
108 fwMgr->LocalPolicy->CurrentProfile->AuthorizedApplications->Add(app);
109 }
110 }
111 }
112 catch (_com_error& e)
113 {
114 printf("%s", e.Error());
115 }
116 goto Cleanup;
117 }
118
119 // Retrieve INetFwRules
120 hr = pNetFwPolicy2->get_Rules(&pFwRules);
121 if (FAILED(hr))
122 {
123 printf("get_Rules failed: 0x%08lx\n", hr);
124 goto Cleanup;
125 }
126
127 /* Start Mozilla modification */
128 // Don't add a new rule if there is an existing rule with the same name.
129 hr = pFwRules->Item(bstrRuleName, &pFwRuleExisting);
130 // Release the INetFwRule object
131 if (pFwRuleExisting != NULL)
132 {
133 pFwRuleExisting->Release();
134 }
135 if (SUCCEEDED(hr))
136 {
137 printf("Firewall profile already exists\n");
138 goto Cleanup;
139 }
140
141 // Retrieve Current Profiles bitmask
142 // hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask);
143 // if (FAILED(hr))
144 // {
145 // printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr);
146 // goto Cleanup;
147 // }
148
149 // When possible we avoid adding firewall rules to the \ profile.
150 // If Public is currently active and it is not the only active profile, we remove it from the bitmask
151 // if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) &&
152 // (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC))
153 // {
154 // CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC;
155 // }
156
157 // Create a new Firewall Rule object.
158 hr = CoCreateInstance(
159 __uuidof(NetFwRule),
160 NULL,
161 CLSCTX_INPROC_SERVER,
162 __uuidof(INetFwRule),
163 (void**)&pFwRule);
164 if (FAILED(hr))
165 {
166 printf("CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr);
167 goto Cleanup;
168 }
169
170 // Populate the Firewall Rule object
171 pFwRule->put_Name(bstrRuleName);
172 pFwRule->put_Protocol(NetFwTypeLib::NET_FW_IP_PROTOCOL_TCP);
173 pFwRule->put_InterfaceTypes(bstrRuleInterfaceType);
174 pFwRule->put_Profiles(NET_FW_PROFILE2_PRIVATE);
175 pFwRule->put_Action(NET_FW_ACTION_ALLOW);
176 pFwRule->put_Enabled(VARIANT_TRUE);
177
178 pFwRule->put_ApplicationName(bstrApplicationName);
179 // Add the Firewall Rule
180 hr = pFwRules->Add(pFwRule);
181 if (FAILED(hr))
182 {
183 printf("Firewall Rule Add failed: 0x%08lx\n", hr);
184 goto Cleanup;
185 }
186
187 pFwRule->Release();
188 /* End Mozilla modification */
189
190 // Create a new Firewall Rule object.
191 hr = CoCreateInstance(
192 __uuidof(NetFwRule),
193 NULL,
194 CLSCTX_INPROC_SERVER,
195 __uuidof(INetFwRule),
196 (void**)&pFwRule);
197 if (FAILED(hr))
198 {
199 printf("CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr);
200 goto Cleanup;
201 }
202
203 // Populate the Firewall Rule object
204 pFwRule->put_Name(bstrRuleName);
205 /* Start Mozilla modification */
206 // pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY);
207 pFwRule->put_Protocol(NetFwTypeLib::NET_FW_IP_PROTOCOL_UDP);
208 /* End Mozilla modification */
209 pFwRule->put_InterfaceTypes(bstrRuleInterfaceType);
210 /* Start Mozilla modification */
211 // pFwRule->put_Profiles(CurrentProfilesBitMask);
212 pFwRule->put_Profiles(NET_FW_PROFILE2_PRIVATE);
213 /* End Mozilla modification */
214 pFwRule->put_Action(NET_FW_ACTION_ALLOW);
215 pFwRule->put_Enabled(VARIANT_TRUE);
216
217 pFwRule->put_ApplicationName(bstrApplicationName);
218 // Add the Firewall Rule
219 hr = pFwRules->Add(pFwRule);
220 if (FAILED(hr))
221 {
222 printf("Firewall Rule Add failed: 0x%08lx\n", hr);
223 goto Cleanup;
224 }
225
226 Cleanup:
227
228 // Free BSTR's
229 SysFreeString(bstrRuleName);
230 SysFreeString(bstrApplicationName);
231 SysFreeString(bstrRuleInterfaceType);
232
233 // Release the INetFwRule object
234 if (pFwRule != NULL)
235 {
236 pFwRule->Release();
237 }
238
239 // Release the INetFwRules object
240 if (pFwRules != NULL)
241 {
242 pFwRules->Release();
243 }
244
245 // Release the INetFwPolicy2 object
246 if (pNetFwPolicy2 != NULL)
247 {
248 pNetFwPolicy2->Release();
249 }
250
251 CoUninitialize();
252 return 0;
253 }
254
RemoveRule(LPCTSTR ExceptionName,LPCTSTR ProcessPath)255 HRESULT RemoveRule(LPCTSTR ExceptionName, LPCTSTR ProcessPath)
256 {
257 HRESULT result = CoInitialize(NULL);
258 if (FAILED(result))
259 return result;
260 try
261 {
262 INetFwMgrPtr fwMgr(L"HNetCfg.FwMgr");
263 if (fwMgr)
264 {
265 fwMgr->LocalPolicy->CurrentProfile->AuthorizedApplications->Remove(ProcessPath);
266 result = S_OK;
267 }
268 }
269 catch (_com_error& e)
270 {
271 e;
272 }
273 HRESULT hrComInit = S_OK;
274 HRESULT hr = S_OK;
275
276 INetFwPolicy2 *pNetFwPolicy2 = NULL;
277 INetFwRules *pFwRules = NULL;
278
279 /* Start Mozilla modification */
280 // long CurrentProfilesBitMask = 0;
281 /* End Mozilla modification */
282
283 BSTR bstrRuleName = SysAllocString(ExceptionName);
284
285 // Retrieve INetFwPolicy2
286 hr = WFCOMInitialize(&pNetFwPolicy2);
287 if (FAILED(hr))
288 {
289 goto Cleanup;
290 }
291
292 // Retrieve INetFwRules
293 hr = pNetFwPolicy2->get_Rules(&pFwRules);
294 if (FAILED(hr))
295 {
296 printf("get_Rules failed: 0x%08lx\n", hr);
297 goto Cleanup;
298 }
299
300 /* Start Mozilla modification */
301 // Retrieve Current Profiles bitmask
302 // hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask);
303 // if (FAILED(hr))
304 // {
305 // printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr);
306 // goto Cleanup;
307 // }
308
309 // When possible we avoid adding firewall rules to the Public profile.
310 // If Public is currently active and it is not the only active profile, we remove it from the bitmask
311 // if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) &&
312 // (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC))
313 // {
314 // CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC;
315 // }
316 /* End Mozilla modification */
317
318 // Remove the Firewall Rule
319 hr = pFwRules->Remove(bstrRuleName);
320 if (FAILED(hr))
321 {
322 printf("Firewall Rule Remove failed: 0x%08lx\n", hr);
323 goto Cleanup;
324 }
325
326 Cleanup:
327
328 // Free BSTR's
329 SysFreeString(bstrRuleName);
330
331 // Release the INetFwRules object
332 if (pFwRules != NULL)
333 {
334 pFwRules->Release();
335 }
336
337 // Release the INetFwPolicy2 object
338 if (pNetFwPolicy2 != NULL)
339 {
340 pNetFwPolicy2->Release();
341 }
342
343 CoUninitialize();
344 return 0;
345 }
346
347
348 #ifdef NSIS
AddRule(HWND hwndParent,int string_size,TCHAR * variables,stack_t ** stacktop)349 extern "C" void __declspec(dllexport) AddRule(HWND hwndParent, int string_size,
350 TCHAR *variables, stack_t **stacktop)
351 {
352 EXDLL_INIT();
353
354 TCHAR ExceptionName[256], ProcessPath[MAX_PATH];
355 popstring(ProcessPath);
356 popstring(ExceptionName);
357 HRESULT result = AddRule(ExceptionName, ProcessPath);
358 // push the result back to NSIS
359 TCHAR intBuffer[16];
360 wsprintf(intBuffer, _T("%d"), result);
361 pushstring(intBuffer);
362 }
363
RemoveRule(HWND hwndParent,int string_size,TCHAR * variables,stack_t ** stacktop)364 extern "C" void __declspec(dllexport) RemoveRule(HWND hwndParent, int string_size,
365 TCHAR *variables, stack_t **stacktop)
366 {
367 EXDLL_INIT();
368
369 TCHAR ExceptionName[256], ProcessPath[MAX_PATH];
370 popstring(ProcessPath);
371 popstring(ExceptionName);
372 HRESULT result = RemoveRule(ExceptionName, ProcessPath);
373 // push the result back to NSIS
374 TCHAR intBuffer[16];
375 wsprintf(intBuffer, _T("%d"), result);
376 pushstring(intBuffer);
377 }
378
DllMain(HINSTANCE hInstance,DWORD,LPVOID)379 extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD, LPVOID)
380 {
381 g_hInstance = hInstance;
382 return TRUE;
383 }
384 #endif
385
386
387 // Instantiate INetFwPolicy2
388
WFCOMInitialize(INetFwPolicy2 ** ppNetFwPolicy2)389 HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2)
390 {
391 HRESULT hr = S_OK;
392
393 hr = CoCreateInstance(
394 __uuidof(NetFwPolicy2),
395 NULL,
396 CLSCTX_INPROC_SERVER,
397 __uuidof(INetFwPolicy2),
398 (void**)ppNetFwPolicy2);
399
400 if (FAILED(hr))
401 {
402 printf("CoCreateInstance for INetFwPolicy2 failed: 0x%08lx\n", hr);
403 goto Cleanup;
404 }
405
406 Cleanup:
407 return hr;
408 }
409