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