2 * Copyright 2004 by the Massachusetts Institute of Technology
6 * Permission to use, copy, modify, and distribute this software and its
7 * documentation for any purpose and without fee is hereby granted,
8 * provided that the above copyright notice appear in all copies and that
9 * both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of the Massachusetts
11 * Institute of Technology (M.I.T.) not be used in advertising or publicity
12 * pertaining to distribution of the software without specific, written
15 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 * M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 * Copyright 2011 by Your File System, Inc.
38 #pragma comment(lib,"ole32.lib")
39 #pragma comment(lib,"oleaut32.lib")
40 #define DEBUGOUT(x) printf(x)
41 #define DEBUGOUTW(x) wprintf(x)
43 #define DEBUGOUT(x) OutputDebugString(x)
44 #define DEBUGOUTW(x) OutputDebugStringW(x)
47 /* an IPv4, enabled port with global scope */
48 struct global_afs_port_type {
52 NET_FW_IP_PROTOCOL protocol;
55 typedef struct global_afs_port_type global_afs_port_t;
57 global_afs_port_t afs_clientPorts[] = {
58 { L"AFS CacheManager Callback (UDP)", 7001, L"7001", NET_FW_IP_PROTOCOL_UDP }
60 , { L"AFS CacheManager Callback (TCP)", 7001, L"7001", NET_FW_IP_PROTOCOL_TCP }
64 global_afs_port_t afs_serverPorts[] = {
65 { L"AFS File Server (UDP)", 7000, L"7000", NET_FW_IP_PROTOCOL_UDP },
67 { L"AFS File Server (TCP)", 7000, L"7000", NET_FW_IP_PROTOCOL_TCP },
69 { L"AFS User & Group Database (UDP)", 7002, L"7002", NET_FW_IP_PROTOCOL_UDP },
71 { L"AFS User & Group Database (TCP)", 7002, L"7002", NET_FW_IP_PROTOCOL_TCP },
73 { L"AFS Volume Location Database (UDP)", 7003, L"7003", NET_FW_IP_PROTOCOL_UDP },
75 { L"AFS Volume Location Database (TCP)", 7003, L"7003", NET_FW_IP_PROTOCOL_TCP },
77 { L"AFS/Kerberos Authentication (UDP)", 7004, L"7004", NET_FW_IP_PROTOCOL_UDP },
79 { L"AFS/Kerberos Authentication (TCP)", 7004, L"7004", NET_FW_IP_PROTOCOL_TCP },
81 { L"AFS Volume Mangement (UDP)", 7005, L"7005", NET_FW_IP_PROTOCOL_UDP },
83 { L"AFS Volume Mangement (TCP)", 7005, L"7005", NET_FW_IP_PROTOCOL_TCP },
85 { L"AFS Error Interpretation (UDP)", 7006, L"7006", NET_FW_IP_PROTOCOL_UDP },
87 { L"AFS Error Interpretation (TCP)", 7006, L"7006", NET_FW_IP_PROTOCOL_TCP },
89 { L"AFS Basic Overseer (UDP)", 7007, L"7007", NET_FW_IP_PROTOCOL_UDP },
91 { L"AFS Basic Overseer (TCP)", 7007, L"7007", NET_FW_IP_PROTOCOL_TCP },
93 { L"AFS Server-to-server Updater (UDP)", 7008, L"7008", NET_FW_IP_PROTOCOL_UDP },
95 { L"AFS Server-to-server Updater (TCP)", 7008, L"7008", NET_FW_IP_PROTOCOL_TCP },
97 { L"AFS Remote Cache Manager (UDP)", 7009, L"7009", NET_FW_IP_PROTOCOL_UDP }
99 , { L"AFS Remote Cache Manager (TCP)", 7009, L"7009", NET_FW_IP_PROTOCOL_TCP }
103 HRESULT icf_CheckAndAddPorts2(WCHAR * wServiceName, global_afs_port_t * ports, int nPorts)
105 INetFwPolicy2 *pNetFwPolicy2 = NULL;
106 INetFwRules *pFwRules = NULL;
107 INetFwRule *pFwRule = NULL;
108 WCHAR wFilename[1024] = L"C:\\Program Files\\OpenAFS\\Client\\Program\\afsd_service.exe";
110 long CurrentProfilesBitMask = 0;
114 GetModuleFileNameW(NULL, wFilename, 1024);
117 BSTR bstrRuleGroup = SysAllocString(L"OpenAFS Firewall Rules");
118 BSTR bstrRuleApplication = SysAllocString(wFilename);
119 BSTR bstrRuleService = SysAllocString(wServiceName);
120 BSTR bstrInterfaceTypes = SysAllocString(L"all");
122 HRESULT hrComInit = S_OK;
125 // Retrieve INetFwPolicy2
126 hr = CoCreateInstance( __uuidof(NetFwPolicy2),
128 CLSCTX_INPROC_SERVER,
129 __uuidof(INetFwPolicy2),
130 (void**)&pNetFwPolicy2);
133 DEBUGOUT(("Can't create NetFwPolicy2\n"));
137 // Retrieve INetFwRules
138 hr = pNetFwPolicy2->get_Rules(&pFwRules);
141 DEBUGOUT(("get_Rules failed\n"));
146 DEBUGOUT(("No port specified\n"));
148 for ( i=0; i < nPorts; i++)
150 BSTR bstrRuleName = SysAllocString(ports[i].name);
151 BSTR bstrRuleDescription = SysAllocString(ports[i].name);
152 BSTR bstrRuleLPorts = SysAllocString(ports[i].str_port);
154 hr = pFwRules->Item(bstrRuleName, &pFwRule);
157 // Create a new Firewall Rule object.
158 hr = CoCreateInstance( __uuidof(NetFwRule),
160 CLSCTX_INPROC_SERVER,
161 __uuidof(INetFwRule),
165 // Populate the Firewall Rule object
166 pFwRule->put_Name(bstrRuleName);
167 pFwRule->put_Description(bstrRuleDescription);
168 pFwRule->put_ApplicationName(bstrRuleApplication);
170 // Add the Firewall Rule
171 hr = pFwRules->Add(pFwRule);
174 DEBUGOUT(("Advanced Firewall Rule Add failed\n"));
178 DEBUGOUT(("Advanced Firewall Rule Add successful\n"));
181 // Do not assign the service name to the rule.
182 // Only specify the executable name. According to feedback
183 // in openafs-info, the service name filter blocks the rule.
185 pFwRule->put_ServiceName(NULL);
186 pFwRule->put_Protocol(ports[i].protocol);
187 pFwRule->put_LocalPorts(bstrRuleLPorts);
188 pFwRule->put_Grouping(bstrRuleGroup);
189 pFwRule->put_Profiles(NET_FW_PROFILE2_ALL);
190 pFwRule->put_Action(NET_FW_ACTION_ALLOW);
191 pFwRule->put_Enabled(VARIANT_TRUE);
192 pFwRule->put_EdgeTraversal(VARIANT_TRUE);
193 pFwRule->put_InterfaceTypes(bstrInterfaceTypes);
198 DEBUGOUT(("CoCreateInstance INetFwRule failed\n"));
203 DEBUGOUT(("INetFwRule already exists\n"));
205 hr = pFwRule->put_ServiceName(NULL);
208 DEBUGOUT(("INetFwRule Service Name Updated\n"));
211 hr = pFwRule->put_ApplicationName(bstrRuleApplication);
214 DEBUGOUT(("INetFwRule Application Name Updated\n"));
217 hr = pFwRule->put_EdgeTraversal(VARIANT_TRUE);
220 DEBUGOUT(("INetFwRule Edge Traversal Updated\n"));
223 hr = pFwRule->put_InterfaceTypes(bstrInterfaceTypes);
226 DEBUGOUT(("INetFwRule Interface Types Updated\n"));
230 SysFreeString(bstrRuleName);
231 SysFreeString(bstrRuleDescription);
232 SysFreeString(bstrRuleLPorts);
238 SysFreeString(bstrRuleGroup);
239 SysFreeString(bstrRuleApplication);
240 SysFreeString(bstrRuleService);
241 SysFreeString(bstrInterfaceTypes);
243 // Release the INetFwRule object
249 // Release the INetFwRules object
250 if (pFwRules != NULL)
255 // Release the INetFwPolicy2 object
256 if (pNetFwPolicy2 != NULL)
258 pNetFwPolicy2->Release();
262 if (SUCCEEDED(hrComInit))
271 HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile)
274 INetFwMgr* fwMgr = NULL;
275 INetFwPolicy* fwPolicy = NULL;
279 // Create an instance of the firewall settings manager.
280 hr = CoCreateInstance(
283 CLSCTX_INPROC_SERVER,
285 reinterpret_cast<void**>(static_cast<INetFwMgr**>(&fwMgr))
289 DEBUGOUT(("Can't create fwMgr\n"));
293 // Retrieve the local firewall policy.
294 hr = fwMgr->get_LocalPolicy(&fwPolicy);
297 DEBUGOUT(("Cant get local policy\n"));
301 // Retrieve the firewall profile currently in effect.
302 hr = fwPolicy->get_CurrentProfile(fwProfile);
305 DEBUGOUT(("Can't get current profile\n"));
311 // Release the local firewall policy.
312 if (fwPolicy != NULL)
317 // Release the firewall settings manager.
326 HRESULT icf_CheckAndAddPorts(INetFwProfile * fwProfile, global_afs_port_t * ports, int nPorts) {
327 INetFwOpenPorts * fwPorts = NULL;
328 INetFwOpenPort * fwPort = NULL;
330 HRESULT rhr = S_OK; /* return value */
333 hr = fwProfile->get_GloballyOpenPorts(&fwPorts);
336 DEBUGOUT(("Can't get globallyOpenPorts\n"));
341 // go through the supplied ports
342 for (i=0; i<nPorts; i++) {
343 VARIANT_BOOL vbEnabled;
345 BOOL bCreate = FALSE;
348 hr = fwPorts->Item(ports[i].n_port, ports[i].protocol, &fwPort);
350 DEBUGOUTW((L"Found port for %S\n",ports[i].name));
351 hr = fwPort->get_Enabled(&vbEnabled);
353 if ( vbEnabled == VARIANT_FALSE ) {
354 hr = fwPort->put_Enabled(VARIANT_TRUE);
356 // failed. Mark as failure. Don't try to create the port either.
359 } // else we are fine
361 // Something is wrong with the port.
362 // We try to create a new one thus overriding this faulty one.
367 } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
368 DEBUGOUTW((L"Port not found for %S\n", ports[i].name));
373 DEBUGOUTW((L"Trying to create port %S\n",ports[i].name));
374 hr = CoCreateInstance( __uuidof(NetFwOpenPort),
376 CLSCTX_INPROC_SERVER,
377 __uuidof(INetFwOpenPort),
378 reinterpret_cast<void**>
379 (static_cast<INetFwOpenPort**>(&fwPort))
383 DEBUGOUT(("Can't create port\n"));
386 DEBUGOUT(("Created port\n"));
387 hr = fwPort->put_IpVersion( NET_FW_IP_VERSION_ANY );
389 DEBUGOUT(("Can't set IpVersion\n"));
394 hr = fwPort->put_Port( ports[i].n_port );
396 DEBUGOUT(("Can't set Port\n"));
401 hr = fwPort->put_Protocol( ports[i].protocol );
403 DEBUGOUT(("Can't set Protocol\n"));
408 hr = fwPort->put_Scope( NET_FW_SCOPE_ALL );
410 DEBUGOUT(("Can't set Scope\n"));
415 bstName = SysAllocString( ports[i].name );
417 if (SysStringLen(bstName) == 0) {
420 hr = fwPort->put_Name( bstName );
422 DEBUGOUT(("Can't set Name\n"));
424 SysFreeString( bstName );
429 SysFreeString( bstName );
431 hr = fwPorts->Add( fwPort );
433 DEBUGOUT(("Can't add port\n"));
436 DEBUGOUT(("Added port\n"));
442 } // loop through ports
454 long icf_CheckAndAddAFSPorts(int portset) {
456 BOOL coInitialized = FALSE;
457 INetFwProfile * fwProfile = NULL;
458 global_afs_port_t * ports;
459 WCHAR * wServiceName;
463 if (portset == AFS_PORTSET_CLIENT) {
464 ports = afs_clientPorts;
465 nports = sizeof(afs_clientPorts) / sizeof(*afs_clientPorts);
466 wServiceName = L"TransarcAFSDaemon";
467 } else if (portset == AFS_PORTSET_SERVER) {
468 ports = afs_serverPorts;
469 nports = sizeof(afs_serverPorts) / sizeof(*afs_serverPorts);
470 wServiceName = L"TransarcAFSServer";
472 DEBUGOUT(("Invalid port set\n"));
473 return 1; /* Invalid port set */
475 hr = CoInitializeEx( NULL,
476 COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE
479 if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
481 coInitialized = TRUE;
483 // not necessarily catastrophic if the call failed. We'll try to
484 // continue as if it succeeded.
486 hr = icf_CheckAndAddPorts2(wServiceName, ports, nports);
488 DEBUGOUT(("INetFwProfile2 failed, trying INetFwProfile\n"));
489 hr = icf_OpenFirewallProfile(&fwProfile);
491 // Ok. That didn't work. This could be because the machine we
492 // are running on doesn't have Windows Firewall. We'll return
493 // a failure to the caller, which shouldn't be taken to mean
494 // it's catastrophic.
495 DEBUGOUT(("Can't open Firewall profile\n"));
500 // Now that we have a firewall profile, we can start checking
501 // and adding the ports that we want.
502 hr = icf_CheckAndAddPorts(fwProfile, ports, nports);
517 int main(int argc, char **argv) {
518 printf("Starting...\n");
519 if (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT))
522 printf("Succeeded\n");