From 59d81d9d24f8bc1fecdab7cd7661f1145fb10066 Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Wed, 14 Jul 2004 07:12:20 +0000 Subject: [PATCH] xp-sp2-icf-20040713 Windows XP SP2 adds a firewall which blocks all incoming ports by default. This patch adds support to the AFS Client Service (but not the AFS Server) to automatically open the firewall to ports in use by the application. One of the new requirements of this functionality is the use of the latest Platform SDK "Microsoft Platform SDK for Windows XP SP2". ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== For the XP SP2 SDK both the Core and Data Access SDKs are required --- README-NT | 3 +- src/WINNT/afsd/NTMakefile | 13 +- src/WINNT/afsd/afsd_init.c | 22 +-- src/WINNT/afsd/afsicf.cpp | 326 ++++++++++++++++++++++++++++++++ src/WINNT/afsd/afsicf.h | 40 ++++ src/WINNT/afsd/lanahelper.cpp | 25 +++ src/WINNT/afsd/lanahelper.h | 25 +++ src/WINNT/bosctlsvc/NTMakefile | 9 +- src/WINNT/bosctlsvc/bosctlsvc.c | 5 +- 9 files changed, 441 insertions(+), 27 deletions(-) create mode 100644 src/WINNT/afsd/afsicf.cpp create mode 100644 src/WINNT/afsd/afsicf.h diff --git a/README-NT b/README-NT index 37895c8a5a..eb7e156139 100644 --- a/README-NT +++ b/README-NT @@ -46,7 +46,8 @@ versions are supported: Microsoft Visual .NET Microsoft Visual .NET 2003 (recommended) - Any version of the Microsoft SDK and Tools released August 2001 or later. + Microsoft Platform SDK for Windows XP SP2 + [Core and Data Access SDKs are required] The NSIS installer requires about 14 MB of storage. The following version is supported. diff --git a/src/WINNT/afsd/NTMakefile b/src/WINNT/afsd/NTMakefile index 22d5f03a7e..de4243b210 100644 --- a/src/WINNT/afsd/NTMakefile +++ b/src/WINNT/afsd/NTMakefile @@ -64,7 +64,8 @@ INCFILES =\ $(INCFILEDIR)\cm_freelance.h \ $(INCFILEDIR)\afsd_eventlog.h \ $(INCFILEDIR)\afsd_eventmessages.h \ - $(INCFILEDIR)\afskfw.h + $(INCFILEDIR)\afskfw.h \ + $(INCFILEDIR)\afsicf.h IDLFILES =\ afsrpc.h $(OUT)\afsrpc_c.obj @@ -116,7 +117,8 @@ AFSDOBJS=\ !ENDIF $(OUT)\cm_freelance.obj \ $(OUT)\afsd_eventlog.obj \ - $(OUT)\afsd_flushvol.obj + $(OUT)\afsd_flushvol.obj \ + $(OUT)\afsicf.obj $(AFSDOBJS): @@ -245,9 +247,10 @@ $(LOG95_DLLFILE): $(LOG95_DLLOBJS) $(LOG95_DLLLIBS) ############################################################################ # Install target; primary makefile target -install_objs: $(OUT)\cm_dns.obj $(OUT)\cm_config.obj $(LANAHELPERLIB) +install_objs: $(OUT)\cm_dns.obj $(OUT)\cm_config.obj $(LANAHELPERLIB) $(OUT)\afsicf.obj $(COPY) $(OUT)\cm_dns.obj $(DESTDIR)\lib $(COPY) $(OUT)\cm_config.obj $(DESTDIR)\lib + $(COPY) $(OUT)\afsicf.obj $(DESTDIR)\lib install_headers: $(IDLFILES) $(INCFILES) @@ -328,7 +331,9 @@ AFSD_SDKLIBS =\ Dbghelp.lib \ strsafe.lib \ mpr.lib \ - secur32.lib + secur32.lib \ + ole32.lib \ + oleaut32.lib AFSD_EXELIBS =\ $(DESTDIR)\lib\libosi.lib \ diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 44ddf9ba37..1588d82e82 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -29,6 +29,7 @@ #include "smb.h" #include "cm_rpc.h" #include "lanahelper.h" +#include "afsicf.h" extern int RXAFSCB_ExecuteRequest(struct rx_call *z_call); extern int RXSTATS_ExecuteRequest(struct rx_call *z_call); @@ -789,26 +790,9 @@ int afsd_InitCM(char **reasonP) } /* Open Microsoft Firewall to allow in port 7001 */ - { - HKEY hk; - DWORD dwDisp; - TCHAR* value = TEXT("7001:UDP:*:Enabled:AFS Cache Manager Callback"); - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\DomainProfile\\GloballyOpenP", - 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS) - { - RegSetValueEx (hk, TEXT("7001:UDP"), 0, REG_SZ, (PBYTE)value, sizeof(TCHAR) * (1+lstrlen(value))); - RegCloseKey (hk); - } - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\StandardProfile\\GloballyOpenP", - 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS) - { - RegSetValueEx (hk, TEXT("7001:UDP"), 0, REG_SZ, (PBYTE)value, sizeof(TCHAR) * (1+lstrlen(value))); - RegCloseKey (hk); - } - } + icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT); + /* Ensure the AFS Netbios Name is registered to allow loopback access */ configureBackConnectionHostNames(); /* initialize RX, and tell it to listen to port 7001, which is used for diff --git a/src/WINNT/afsd/afsicf.cpp b/src/WINNT/afsd/afsicf.cpp new file mode 100644 index 0000000000..08ebec6fc0 --- /dev/null +++ b/src/WINNT/afsd/afsicf.cpp @@ -0,0 +1,326 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +#define _WIN32_DCOM +#include +#include +#include +#include +#include "afsicf.h" + +//#define TESTMAIN + +#ifdef TESTMAIN +#include +#pragma comment(lib,"ole32.lib") +#pragma comment(lib,"oleaut32.lib") +#define DEBUGOUT(x) printf x +#else +#define DEBUGOUT(x) +#endif + +/* an IPv4, enabled port with global scope */ +struct global_afs_port_type { + LPWSTR name; + LONG port; + NET_FW_IP_PROTOCOL protocol; +}; + +typedef struct global_afs_port_type global_afs_port_t; + +global_afs_port_t afs_clientPorts[] = { + { L"AFS CacheManager Callback (UDP)", 7001, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS CacheManager Callback (TCP)", 7001, NET_FW_IP_PROTOCOL_TCP } +}; + +global_afs_port_t afs_serverPorts[] = { + { L"AFS File Server (UDP)", 7000, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS File Server (TCP)", 7000, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS User & Group Database (UDP)", 7002, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS User & Group Database (TCP)", 7002, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS Volume Location Database (UDP)", 7003, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS Volume Location Database (TCP)", 7003, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS/Kerberos Authentication (UDP)", 7004, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS/Kerberos Authentication (TCP)", 7004, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS Volume Mangement (UDP)", 7005, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS Volume Mangement (TCP)", 7005, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS Error Interpretation (UDP)", 7006, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS Error Interpretation (TCP)", 7006, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS Basic Overseer (UDP)", 7007, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS Basic Overseer (TCP)", 7007, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS Server-to-server Updater (UDP)", 7008, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS Server-to-server Updater (TCP)", 7008, NET_FW_IP_PROTOCOL_TCP }, + { L"AFS Remote Cache Manager (UDP)", 7009, NET_FW_IP_PROTOCOL_UDP }, + { L"AFS Remote Cache Manager (TCP)", 7009, NET_FW_IP_PROTOCOL_TCP } +}; + +HRESULT icf_OpenFirewallProfile(INetFwProfile ** fwProfile) { + HRESULT hr = S_OK; + INetFwMgr* fwMgr = NULL; + INetFwPolicy* fwPolicy = NULL; + + *fwProfile = NULL; + + // Create an instance of the firewall settings manager. + hr = CoCreateInstance( + __uuidof(NetFwMgr), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(INetFwMgr), + reinterpret_cast(static_cast(&fwMgr)) + ); + if (FAILED(hr)) + { + DEBUGOUT(("Can't create fwMgr\n")); + goto error; + } + + // Retrieve the local firewall policy. + hr = fwMgr->get_LocalPolicy(&fwPolicy); + if (FAILED(hr)) + { + DEBUGOUT(("Cant get local policy\n")); + goto error; + } + + // Retrieve the firewall profile currently in effect. + hr = fwPolicy->get_CurrentProfile(fwProfile); + if (FAILED(hr)) + { + DEBUGOUT(("Can't get current profile\n")); + goto error; + } + +error: + + // Release the local firewall policy. + if (fwPolicy != NULL) + { + fwPolicy->Release(); + } + + // Release the firewall settings manager. + if (fwMgr != NULL) + { + fwMgr->Release(); + } + + return hr; +} + +HRESULT icf_CheckAndAddPorts(INetFwProfile * fwProfile, global_afs_port_t * ports, int nPorts) { + INetFwOpenPorts * fwPorts = NULL; + INetFwOpenPort * fwPort = NULL; + HRESULT hr; + HRESULT rhr = S_OK; /* return value */ + + hr = fwProfile->get_GloballyOpenPorts(&fwPorts); + if (FAILED(hr)) { + // Abort! + DEBUGOUT(("Can't get globallyOpenPorts\n")); + rhr = hr; + goto cleanup; + } + + // go through the supplied ports + for (int i=0; iItem(ports[i].port, ports[i].protocol, &fwPort); + if (SUCCEEDED(hr)) { + DEBUGOUT(("Found port for %S\n",ports[i].name)); + hr = fwPort->get_Enabled(&vbEnabled); + if (SUCCEEDED(hr)) { + if ( vbEnabled == VARIANT_FALSE ) { + hr = fwPort->put_Enabled(VARIANT_TRUE); + if (FAILED(hr)) { + // failed. Mark as failure. Don't try to create the port either. + rhr = hr; + } + } // else we are fine + } else { + // Something is wrong with the port. + // We try to create a new one thus overriding this faulty one. + bCreate = TRUE; + } + fwPort->Release(); + fwPort = NULL; + } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { + DEBUGOUT(("Port not found for %S\n", ports[i].name)); + bCreate = TRUE; + } + + if (bCreate) { + DEBUGOUT(("Trying to create port %S\n",ports[i].name)); + hr = CoCreateInstance( + __uuidof(NetFwOpenPort), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(INetFwOpenPort), + reinterpret_cast + (static_cast(&fwPort)) + ); + + if (FAILED(hr)) { + DEBUGOUT(("Can't create port\n")); + rhr = hr; + } else { + DEBUGOUT(("Created port\n")); + hr = fwPort->put_IpVersion( NET_FW_IP_VERSION_ANY ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set IpVersion\n")); + rhr = hr; + goto abandon_port; + } + + hr = fwPort->put_Port( ports[i].port ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Port\n")); + rhr = hr; + goto abandon_port; + } + + hr = fwPort->put_Protocol( ports[i].protocol ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Protocol\n")); + rhr = hr; + goto abandon_port; + } + + hr = fwPort->put_Scope( NET_FW_SCOPE_ALL ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Scope\n")); + rhr = hr; + goto abandon_port; + } + + bstName = SysAllocString( ports[i].name ); + + if (SysStringLen(bstName) == 0) { + rhr = E_OUTOFMEMORY; + } else { + hr = fwPort->put_Name( bstName ); + if (FAILED(hr)) { + DEBUGOUT(("Can't set Name\n")); + rhr = hr; + SysFreeString( bstName ); + goto abandon_port; + } + } + + SysFreeString( bstName ); + + hr = fwPorts->Add( fwPort ); + if (FAILED(hr)) { + DEBUGOUT(("Can't add port\n")); + rhr = hr; + } else + DEBUGOUT(("Added port\n")); + +abandon_port: + fwPort->Release(); + } + } + } // loop through ports + + fwPorts->Release(); + +cleanup: + + if (fwPorts != NULL) + fwPorts->Release(); + + return rhr; +} + +long icf_CheckAndAddAFSPorts(int portset) { + HRESULT hr; + BOOL coInitialized = FALSE; + INetFwProfile * fwProfile = NULL; + global_afs_port_t * ports; + int nports; + long code = 0; + + if (portset == AFS_PORTSET_CLIENT) { + ports = afs_clientPorts; + nports = sizeof(afs_clientPorts) / sizeof(*afs_clientPorts); + } else if (portset == AFS_PORTSET_SERVER) { + ports = afs_serverPorts; + nports = sizeof(afs_serverPorts) / sizeof(*afs_serverPorts); + } else + return 1; /* Invalid port set */ + + hr = CoInitializeEx( + NULL, + COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE + ); + + if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr) + { + coInitialized = TRUE; + } + // not necessarily catastrophic if the call failed. We'll try to + // continue as if it succeeded. + + hr = icf_OpenFirewallProfile(&fwProfile); + if (FAILED(hr)) { + // Ok. That didn't work. This could be because the machine we + // are running on doesn't have Windows Firewall. We'll return + // a failure to the caller, which shouldn't be taken to mean + // it's catastrophic. + DEBUGOUT(("Can't open Firewall profile\n")); + code = 1; + goto cleanup; + } + + // Now that we have a firewall profile, we can start checking + // and adding the ports that we want. + hr = icf_CheckAndAddPorts(fwProfile, ports, nports); + if (FAILED(hr)) + code = 1; + +cleanup: + if (coInitialized) { + CoUninitialize(); + } + + return code; +} + + +#ifdef TESTMAIN +int main(int argc, char **argv) { + printf("Starting...\n"); + if (icf_CheckAndAddAFSPorts(AFS_PORTSET_CLIENT)) + printf("Failed\n"); + else + printf("Succeeded\n"); + printf("Done\n"); + return 0; +} +#endif \ No newline at end of file diff --git a/src/WINNT/afsd/afsicf.h b/src/WINNT/afsd/afsicf.h new file mode 100644 index 0000000000..05adc99a05 --- /dev/null +++ b/src/WINNT/afsd/afsicf.h @@ -0,0 +1,40 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +long icf_CheckAndAddAFSPorts(int portset); + +#ifdef __cplusplus +} +#endif + +#define AFS_PORTSET_CLIENT 1 +#define AFS_PORTSET_SERVER 2 + diff --git a/src/WINNT/afsd/lanahelper.cpp b/src/WINNT/afsd/lanahelper.cpp index 6251027303..d704adac67 100644 --- a/src/WINNT/afsd/lanahelper.cpp +++ b/src/WINNT/afsd/lanahelper.cpp @@ -1,3 +1,28 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + #include #include #include diff --git a/src/WINNT/afsd/lanahelper.h b/src/WINNT/afsd/lanahelper.h index 6a44a7263e..d6ba0ed85f 100644 --- a/src/WINNT/afsd/lanahelper.h +++ b/src/WINNT/afsd/lanahelper.h @@ -1,3 +1,28 @@ +/* + +Copyright 2004 by the Massachusetts Institute of Technology + +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the Massachusetts +Institute of Technology (M.I.T.) not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +*/ + #ifndef __LANAHELPER_H__ #define __LANAHELPER_H__ diff --git a/src/WINNT/bosctlsvc/NTMakefile b/src/WINNT/bosctlsvc/NTMakefile index fa75d211eb..1d0197fa65 100644 --- a/src/WINNT/bosctlsvc/NTMakefile +++ b/src/WINNT/bosctlsvc/NTMakefile @@ -22,10 +22,15 @@ EXELIBS =\ $(DESTDIR)\lib\afs\afsutil.lib \ $(DESTDIR)\lib\afs\afseventlog.lib \ $(DESTDIR)\lib\afs\afsreg.lib \ - $(DESTDIR)\lib\afs\afsprocmgmt.lib + $(DESTDIR)\lib\afs\afsprocmgmt.lib \ + $(DESTDIR)\lib\afsicf.obj + +EXESDKLIBS=\ + ole32.lib \ + oleaut32.lib $(EXEFILE): $(EXEOBJS) $(EXELIBS) - $(EXECONLINK) + $(EXECONLINK) $(EXESDKLIBS) $(EXEPREP) ############################################################################ diff --git a/src/WINNT/bosctlsvc/bosctlsvc.c b/src/WINNT/bosctlsvc/bosctlsvc.c index d2fd605e58..583dd5964d 100644 --- a/src/WINNT/bosctlsvc/bosctlsvc.c +++ b/src/WINNT/bosctlsvc/bosctlsvc.c @@ -30,7 +30,7 @@ #include #include #include - +#include /* Define globals */ @@ -273,6 +273,9 @@ BosCtlMain(DWORD argc, LPTSTR *argv) return; } + /* For XP SP2 and above, open required ports */ + icf_CheckAndAddAFSPorts(AFS_PORTSET_SERVER); + /* Initialize the dirpath package so can access local bosserver binary */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { /* sw install directory probably not in registry; can not continue */