3 Copyright 2004 by the Massachusetts Institute of Technology
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the name of the Massachusetts
12 Institute of Technology (M.I.T.) not be used in advertising or publicity
13 pertaining to distribution of the software without specific, written
16 M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
18 M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
19 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
35 #pragma comment(lib,"ole32.lib")
36 #pragma comment(lib,"oleaut32.lib")
37 #define DEBUGOUT(x) printf(x)
38 #define DEBUGOUTW(x) wprintf(x)
40 #define DEBUGOUT(x) OutputDebugString(x)
41 #define DEBUGOUTW(x) OutputDebugStringW(x)
44 /* an IPv4, enabled port with global scope */
45 struct global_afs_port_type {
48 NET_FW_IP_PROTOCOL protocol;
51 typedef struct global_afs_port_type global_afs_port_t;
53 global_afs_port_t afs_clientPorts[] = {
54 { L"AFS CacheManager Callback (UDP)", 7001, NET_FW_IP_PROTOCOL_UDP }
56 , { L"AFS CacheManager Callback (TCP)", 7001, NET_FW_IP_PROTOCOL_TCP }
60 global_afs_port_t afs_serverPorts[] = {
61 { L"AFS File Server (UDP)", 7000, NET_FW_IP_PROTOCOL_UDP },
63 { L"AFS File Server (TCP)", 7000, NET_FW_IP_PROTOCOL_TCP },
65 { L"AFS User & Group Database (UDP)", 7002, NET_FW_IP_PROTOCOL_UDP },
67 { L"AFS User & Group Database (TCP)", 7002, NET_FW_IP_PROTOCOL_TCP },
69 { L"AFS Volume Location Database (UDP)", 7003, NET_FW_IP_PROTOCOL_UDP },
71 { L"AFS Volume Location Database (TCP)", 7003, NET_FW_IP_PROTOCOL_TCP },
73 { L"AFS/Kerberos Authentication (UDP)", 7004, NET_FW_IP_PROTOCOL_UDP },
75 { L"AFS/Kerberos Authentication (TCP)", 7004, NET_FW_IP_PROTOCOL_TCP },
77 { L"AFS Volume Mangement (UDP)", 7005, NET_FW_IP_PROTOCOL_UDP },
79 { L"AFS Volume Mangement (TCP)", 7005, NET_FW_IP_PROTOCOL_TCP },
81 { L"AFS Error Interpretation (UDP)", 7006, NET_FW_IP_PROTOCOL_UDP },
83 { L"AFS Error Interpretation (TCP)", 7006, NET_FW_IP_PROTOCOL_TCP },
85 { L"AFS Basic Overseer (UDP)", 7007, NET_FW_IP_PROTOCOL_UDP },
87 { L"AFS Basic Overseer (TCP)", 7007, NET_FW_IP_PROTOCOL_TCP },
89 { L"AFS Server-to-server Updater (UDP)", 7008, NET_FW_IP_PROTOCOL_UDP },
91 { L"AFS Server-to-server Updater (TCP)", 7008, NET_FW_IP_PROTOCOL_TCP },
93 { L"AFS Remote Cache Manager (UDP)", 7009, NET_FW_IP_PROTOCOL_UDP }
95 , { L"AFS Remote Cache Manager (TCP)", 7009, NET_FW_IP_PROTOCOL_TCP }
99 HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile) {
101 INetFwMgr* fwMgr = NULL;
102 INetFwPolicy* fwPolicy = NULL;
106 // Create an instance of the firewall settings manager.
107 hr = CoCreateInstance(
110 CLSCTX_INPROC_SERVER,
112 reinterpret_cast<void**>(static_cast<INetFwMgr**>(&fwMgr))
116 DEBUGOUT(("Can't create fwMgr\n"));
120 // Retrieve the local firewall policy.
121 hr = fwMgr->get_LocalPolicy(&fwPolicy);
124 DEBUGOUT(("Cant get local policy\n"));
128 // Retrieve the firewall profile currently in effect.
129 hr = fwPolicy->get_CurrentProfile(fwProfile);
132 DEBUGOUT(("Can't get current profile\n"));
138 // Release the local firewall policy.
139 if (fwPolicy != NULL)
144 // Release the firewall settings manager.
153 HRESULT icf_CheckAndAddPorts(INetFwProfile * fwProfile, global_afs_port_t * ports, int nPorts) {
154 INetFwOpenPorts * fwPorts = NULL;
155 INetFwOpenPort * fwPort = NULL;
157 HRESULT rhr = S_OK; /* return value */
160 hr = fwProfile->get_GloballyOpenPorts(&fwPorts);
163 DEBUGOUT(("Can't get globallyOpenPorts\n"));
168 // go through the supplied ports
169 for (i=0; i<nPorts; i++) {
170 VARIANT_BOOL vbEnabled;
172 BOOL bCreate = FALSE;
175 hr = fwPorts->Item(ports[i].port, ports[i].protocol, &fwPort);
177 DEBUGOUTW((L"Found port for %S\n",ports[i].name));
178 hr = fwPort->get_Enabled(&vbEnabled);
180 if ( vbEnabled == VARIANT_FALSE ) {
181 hr = fwPort->put_Enabled(VARIANT_TRUE);
183 // failed. Mark as failure. Don't try to create the port either.
186 } // else we are fine
188 // Something is wrong with the port.
189 // We try to create a new one thus overriding this faulty one.
194 } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
195 DEBUGOUTW((L"Port not found for %S\n", ports[i].name));
200 DEBUGOUTW((L"Trying to create port %S\n",ports[i].name));
201 hr = CoCreateInstance( __uuidof(NetFwOpenPort),
203 CLSCTX_INPROC_SERVER,
204 __uuidof(INetFwOpenPort),
205 reinterpret_cast<void**>
206 (static_cast<INetFwOpenPort**>(&fwPort))
210 DEBUGOUT(("Can't create port\n"));
213 DEBUGOUT(("Created port\n"));
214 hr = fwPort->put_IpVersion( NET_FW_IP_VERSION_ANY );
216 DEBUGOUT(("Can't set IpVersion\n"));
221 hr = fwPort->put_Port( ports[i].port );
223 DEBUGOUT(("Can't set Port\n"));
228 hr = fwPort->put_Protocol( ports[i].protocol );
230 DEBUGOUT(("Can't set Protocol\n"));
235 hr = fwPort->put_Scope( NET_FW_SCOPE_ALL );
237 DEBUGOUT(("Can't set Scope\n"));
242 bstName = SysAllocString( ports[i].name );
244 if (SysStringLen(bstName) == 0) {
247 hr = fwPort->put_Name( bstName );
249 DEBUGOUT(("Can't set Name\n"));
251 SysFreeString( bstName );
256 SysFreeString( bstName );
258 hr = fwPorts->Add( fwPort );
260 DEBUGOUT(("Can't add port\n"));
263 DEBUGOUT(("Added port\n"));
269 } // loop through ports
281 long icf_CheckAndAddAFSPorts(int portset) {
283 BOOL coInitialized = FALSE;
284 INetFwProfile * fwProfile = NULL;
285 global_afs_port_t * ports;
289 if (portset == AFS_PORTSET_CLIENT) {
290 ports = afs_clientPorts;
291 nports = sizeof(afs_clientPorts) / sizeof(*afs_clientPorts);
292 } else if (portset == AFS_PORTSET_SERVER) {
293 ports = afs_serverPorts;
294 nports = sizeof(afs_serverPorts) / sizeof(*afs_serverPorts);
296 return 1; /* Invalid port set */
298 hr = CoInitializeEx( NULL,
299 COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE
302 if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
304 coInitialized = TRUE;
306 // not necessarily catastrophic if the call failed. We'll try to
307 // continue as if it succeeded.
309 hr = icf_OpenFirewallProfile(&fwProfile);
311 // Ok. That didn't work. This could be because the machine we
312 // are running on doesn't have Windows Firewall. We'll return
313 // a failure to the caller, which shouldn't be taken to mean
314 // it's catastrophic.
315 DEBUGOUT(("Can't open Firewall profile\n"));
320 // Now that we have a firewall profile, we can start checking
321 // and adding the ports that we want.
322 hr = icf_CheckAndAddPorts(fwProfile, ports, nports);
336 int main(int argc, char **argv) {
337 printf("Starting...\n");
338 if (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT))
341 printf("Succeeded\n");