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 */
139 hr = fwProfile->get_GloballyOpenPorts(&fwPorts);
142 DEBUGOUT(("Can't get globallyOpenPorts\n"));
147 // go through the supplied ports
148 for (int i=0; i<nPorts; i++) {
149 VARIANT_BOOL vbEnabled;
151 BOOL bCreate = FALSE;
154 hr = fwPorts->Item(ports[i].port, ports[i].protocol, &fwPort);
156 DEBUGOUT(("Found port for %S\n",ports[i].name));
157 hr = fwPort->get_Enabled(&vbEnabled);
159 if ( vbEnabled == VARIANT_FALSE ) {
160 hr = fwPort->put_Enabled(VARIANT_TRUE);
162 // failed. Mark as failure. Don't try to create the port either.
165 } // else we are fine
167 // Something is wrong with the port.
168 // We try to create a new one thus overriding this faulty one.
173 } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
174 DEBUGOUT(("Port not found for %S\n", ports[i].name));
179 DEBUGOUT(("Trying to create port %S\n",ports[i].name));
180 hr = CoCreateInstance(
181 __uuidof(NetFwOpenPort),
183 CLSCTX_INPROC_SERVER,
184 __uuidof(INetFwOpenPort),
185 reinterpret_cast<void**>
186 (static_cast<INetFwOpenPort**>(&fwPort))
190 DEBUGOUT(("Can't create port\n"));
193 DEBUGOUT(("Created port\n"));
194 hr = fwPort->put_IpVersion( NET_FW_IP_VERSION_ANY );
196 DEBUGOUT(("Can't set IpVersion\n"));
201 hr = fwPort->put_Port( ports[i].port );
203 DEBUGOUT(("Can't set Port\n"));
208 hr = fwPort->put_Protocol( ports[i].protocol );
210 DEBUGOUT(("Can't set Protocol\n"));
215 hr = fwPort->put_Scope( NET_FW_SCOPE_ALL );
217 DEBUGOUT(("Can't set Scope\n"));
222 bstName = SysAllocString( ports[i].name );
224 if (SysStringLen(bstName) == 0) {
227 hr = fwPort->put_Name( bstName );
229 DEBUGOUT(("Can't set Name\n"));
231 SysFreeString( bstName );
236 SysFreeString( bstName );
238 hr = fwPorts->Add( fwPort );
240 DEBUGOUT(("Can't add port\n"));
243 DEBUGOUT(("Added port\n"));
249 } // loop through ports
261 long icf_CheckAndAddAFSPorts(int portset) {
263 BOOL coInitialized = FALSE;
264 INetFwProfile * fwProfile = NULL;
265 global_afs_port_t * ports;
269 if (portset == AFS_PORTSET_CLIENT) {
270 ports = afs_clientPorts;
271 nports = sizeof(afs_clientPorts) / sizeof(*afs_clientPorts);
272 } else if (portset == AFS_PORTSET_SERVER) {
273 ports = afs_serverPorts;
274 nports = sizeof(afs_serverPorts) / sizeof(*afs_serverPorts);
276 return 1; /* Invalid port set */
280 COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE
283 if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)
285 coInitialized = TRUE;
287 // not necessarily catastrophic if the call failed. We'll try to
288 // continue as if it succeeded.
290 hr = icf_OpenFirewallProfile(&fwProfile);
292 // Ok. That didn't work. This could be because the machine we
293 // are running on doesn't have Windows Firewall. We'll return
294 // a failure to the caller, which shouldn't be taken to mean
295 // it's catastrophic.
296 DEBUGOUT(("Can't open Firewall profile\n"));
301 // Now that we have a firewall profile, we can start checking
302 // and adding the ports that we want.
303 hr = icf_CheckAndAddPorts(fwProfile, ports, nports);
317 int main(int argc, char **argv) {
318 printf("Starting...\n");
319 if (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT))
322 printf("Succeeded\n");