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
37 #pragma comment(lib,"ole32.lib")
38 #pragma comment(lib,"oleaut32.lib")
39 #define DEBUGOUT(x) printf 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 },
55 { L"AFS CacheManager Callback (TCP)", 7001, NET_FW_IP_PROTOCOL_TCP }
58 global_afs_port_t afs_serverPorts[] = {
59 { L"AFS File Server (UDP)", 7000, NET_FW_IP_PROTOCOL_UDP },
60 { L"AFS File Server (TCP)", 7000, NET_FW_IP_PROTOCOL_TCP },
61 { L"AFS User & Group Database (UDP)", 7002, NET_FW_IP_PROTOCOL_UDP },
62 { L"AFS User & Group Database (TCP)", 7002, NET_FW_IP_PROTOCOL_TCP },
63 { L"AFS Volume Location Database (UDP)", 7003, NET_FW_IP_PROTOCOL_UDP },
64 { L"AFS Volume Location Database (TCP)", 7003, NET_FW_IP_PROTOCOL_TCP },
65 { L"AFS/Kerberos Authentication (UDP)", 7004, NET_FW_IP_PROTOCOL_UDP },
66 { L"AFS/Kerberos Authentication (TCP)", 7004, NET_FW_IP_PROTOCOL_TCP },
67 { L"AFS Volume Mangement (UDP)", 7005, NET_FW_IP_PROTOCOL_UDP },
68 { L"AFS Volume Mangement (TCP)", 7005, NET_FW_IP_PROTOCOL_TCP },
69 { L"AFS Error Interpretation (UDP)", 7006, NET_FW_IP_PROTOCOL_UDP },
70 { L"AFS Error Interpretation (TCP)", 7006, NET_FW_IP_PROTOCOL_TCP },
71 { L"AFS Basic Overseer (UDP)", 7007, NET_FW_IP_PROTOCOL_UDP },
72 { L"AFS Basic Overseer (TCP)", 7007, NET_FW_IP_PROTOCOL_TCP },
73 { L"AFS Server-to-server Updater (UDP)", 7008, NET_FW_IP_PROTOCOL_UDP },
74 { L"AFS Server-to-server Updater (TCP)", 7008, NET_FW_IP_PROTOCOL_TCP },
75 { L"AFS Remote Cache Manager (UDP)", 7009, NET_FW_IP_PROTOCOL_UDP },
76 { L"AFS Remote Cache Manager (TCP)", 7009, NET_FW_IP_PROTOCOL_TCP }
79 HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile) {
81 INetFwMgr* fwMgr = NULL;
82 INetFwPolicy* fwPolicy = NULL;
86 // Create an instance of the firewall settings manager.
87 hr = CoCreateInstance(
92 reinterpret_cast<void**>(static_cast<INetFwMgr**>(&fwMgr))
96 DEBUGOUT(("Can't create fwMgr\n"));
100 // Retrieve the local firewall policy.
101 hr = fwMgr->get_LocalPolicy(&fwPolicy);
104 DEBUGOUT(("Cant get local policy\n"));
108 // Retrieve the firewall profile currently in effect.
109 hr = fwPolicy->get_CurrentProfile(fwProfile);
112 DEBUGOUT(("Can't get current profile\n"));
118 // Release the local firewall policy.
119 if (fwPolicy != NULL)
124 // Release the firewall settings manager.
133 HRESULT icf_CheckAndAddPorts(INetFwProfile * fwProfile, global_afs_port_t * ports, int nPorts) {
134 INetFwOpenPorts * fwPorts = NULL;
135 INetFwOpenPort * fwPort = NULL;
137 HRESULT rhr = S_OK; /* return value */
140 hr = fwProfile->get_GloballyOpenPorts(&fwPorts);
143 DEBUGOUT(("Can't get globallyOpenPorts\n"));
148 // go through the supplied ports
149 for (i=0; i<nPorts; i++) {
150 VARIANT_BOOL vbEnabled;
152 BOOL bCreate = FALSE;
155 hr = fwPorts->Item(ports[i].port, ports[i].protocol, &fwPort);
157 DEBUGOUT(("Found port for %S\n",ports[i].name));
158 hr = fwPort->get_Enabled(&vbEnabled);
160 if ( vbEnabled == VARIANT_FALSE ) {
161 hr = fwPort->put_Enabled(VARIANT_TRUE);
163 // failed. Mark as failure. Don't try to create the port either.
166 } // else we are fine
168 // Something is wrong with the port.
169 // We try to create a new one thus overriding this faulty one.
174 } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
175 DEBUGOUT(("Port not found for %S\n", ports[i].name));
180 DEBUGOUT(("Trying to create port %S\n",ports[i].name));
181 hr = CoCreateInstance(
182 __uuidof(NetFwOpenPort),
184 CLSCTX_INPROC_SERVER,
185 __uuidof(INetFwOpenPort),
186 reinterpret_cast<void**>
187 (static_cast<INetFwOpenPort**>(&fwPort))
191 DEBUGOUT(("Can't create port\n"));
194 DEBUGOUT(("Created port\n"));
195 hr = fwPort->put_IpVersion( NET_FW_IP_VERSION_ANY );
197 DEBUGOUT(("Can't set IpVersion\n"));
202 hr = fwPort->put_Port( ports[i].port );
204 DEBUGOUT(("Can't set Port\n"));
209 hr = fwPort->put_Protocol( ports[i].protocol );
211 DEBUGOUT(("Can't set Protocol\n"));
216 hr = fwPort->put_Scope( NET_FW_SCOPE_ALL );
218 DEBUGOUT(("Can't set Scope\n"));
223 bstName = SysAllocString( ports[i].name );
225 if (SysStringLen(bstName) == 0) {
228 hr = fwPort->put_Name( bstName );
230 DEBUGOUT(("Can't set Name\n"));
232 SysFreeString( bstName );
237 SysFreeString( bstName );
239 hr = fwPorts->Add( fwPort );
241 DEBUGOUT(("Can't add port\n"));
244 DEBUGOUT(("Added port\n"));
250 } // loop through ports
262 long icf_CheckAndAddAFSPorts(int portset) {
264 BOOL coInitialized = FALSE;
265 INetFwProfile * fwProfile = NULL;
266 global_afs_port_t * ports;
270 if (portset == AFS_PORTSET_CLIENT) {
271 ports = afs_clientPorts;
272 nports = sizeof(afs_clientPorts) / sizeof(*afs_clientPorts);
273 } else if (portset == AFS_PORTSET_SERVER) {
274 ports = afs_serverPorts;
275 nports = sizeof(afs_serverPorts) / sizeof(*afs_serverPorts);
277 return 1; /* Invalid port set */
281 COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE
284 if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
286 coInitialized = TRUE;
288 // not necessarily catastrophic if the call failed. We'll try to
289 // continue as if it succeeded.
291 hr = icf_OpenFirewallProfile(&fwProfile);
293 // Ok. That didn't work. This could be because the machine we
294 // are running on doesn't have Windows Firewall. We'll return
295 // a failure to the caller, which shouldn't be taken to mean
296 // it's catastrophic.
297 DEBUGOUT(("Can't open Firewall profile\n"));
302 // Now that we have a firewall profile, we can start checking
303 // and adding the ports that we want.
304 hr = icf_CheckAndAddPorts(fwProfile, ports, nports);
318 int main(int argc, char **argv) {
319 printf("Starting...\n");
320 if (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT))
323 printf("Succeeded\n");