From 0dde216076987b4d7ccdd5df88602125f46e14a9 Mon Sep 17 00:00:00 2001 From: Guido Serassio Date: Mon, 18 May 2009 21:52:40 +0200 Subject: [PATCH] Windows port: Fix improper access permissions to registry and DNS parsing from registry - RegOpenKey() always try to open registry keys in full control mode, even if not needed. This could make Squid to fail when running as a non privileged user. RegOpenKeyEx() allow to specify only the needed priviledge and now is used instead. - When parsing DNS setting into registry, a fixed size loop was used. Now the loop count is dynamic. --- src/WinSvc.cc | 18 ++---- src/dns_internal.cc | 143 ++++++++++++++++++++------------------------ 2 files changed, 70 insertions(+), 91 deletions(-) diff --git a/src/WinSvc.cc b/src/WinSvc.cc index de21be3d6b..f7fc1ab6c4 100644 --- a/src/WinSvc.cc +++ b/src/WinSvc.cc @@ -519,9 +519,7 @@ int WIN32_Subsystem_Init(int * argc, char *** argv) return 1; /* Register the service Handler function */ - svcHandle = - RegisterServiceCtrlHandler(WIN32_Service_name, - WIN32_svcHandler); + svcHandle = RegisterServiceCtrlHandler(WIN32_Service_name, WIN32_svcHandler); if (svcHandle == 0) return 1; @@ -539,17 +537,15 @@ int WIN32_Subsystem_Init(int * argc, char *** argv) safe_free(ConfigFile); /* get config file from Windows Registry */ - if (RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY, &hndKey) == ERROR_SUCCESS) { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_QUERY_VALUE, &hndKey) == ERROR_SUCCESS) { DWORD Type = 0; DWORD Size = 0; LONG Result; - Result = - RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, NULL, &Size); + Result = RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { ConfigFile = static_cast(xmalloc(Size)); - RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, (unsigned char *)ConfigFile, - &Size); + RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, (unsigned char *)ConfigFile, &Size); } else ConfigFile = xstrdup(DefaultConfigFile); @@ -557,13 +553,11 @@ int WIN32_Subsystem_Init(int * argc, char *** argv) Type = 0; - Result = - RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, NULL, &Size); + Result = RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { WIN32_Service_Command_Line = static_cast(xmalloc(Size)); - RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, (unsigned char *)WIN32_Service_Command_Line, - &Size); + RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, (unsigned char *)WIN32_Service_Command_Line, &Size); } else WIN32_Service_Command_Line = xstrdup(""); diff --git a/src/dns_internal.cc b/src/dns_internal.cc index a6ea91e480..fbd7d488a5 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -59,6 +59,9 @@ #ifndef USE_DNSSERVERS #ifdef _SQUID_WIN32_ #include "squid_windows.h" +#define REG_TCPIP_PARA_INTERFACES "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces" +#define REG_TCPIP_PARA "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" +#define REG_VXD_MSTCP "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP" #endif #ifndef _PATH_RESCONF #define _PATH_RESCONF "/etc/resolv.conf" @@ -373,32 +376,24 @@ idnsParseWIN32SearchList(const char * Separator) char *token; HKEY hndKey; - if (RegOpenKey(HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", - &hndKey) == ERROR_SUCCESS) { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_TCPIP_PARA, 0, KEY_QUERY_VALUE, &hndKey) == ERROR_SUCCESS) { DWORD Type = 0; DWORD Size = 0; LONG Result; - Result = - RegQueryValueEx(hndKey, "Domain", NULL, &Type, NULL, - &Size); + Result = RegQueryValueEx(hndKey, "Domain", NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { t = (char *) xmalloc(Size); - RegQueryValueEx(hndKey, "Domain", NULL, &Type, (LPBYTE) t, - &Size); + RegQueryValueEx(hndKey, "Domain", NULL, &Type, (LPBYTE) t, &Size); debugs(78, 1, "Adding domain " << t << " from Registry"); idnsAddPathComponent(t); xfree(t); } - Result = - RegQueryValueEx(hndKey, "SearchList", NULL, &Type, NULL, - &Size); + Result = RegQueryValueEx(hndKey, "SearchList", NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { t = (char *) xmalloc(Size); - RegQueryValueEx(hndKey, "SearchList", NULL, &Type, (LPBYTE) t, - &Size); + RegQueryValueEx(hndKey, "SearchList", NULL, &Type, (LPBYTE) t, &Size); token = strtok(t, Separator); while (token) { @@ -430,20 +425,15 @@ idnsParseWIN32Registry(void) case _WIN_OS_WINNT: /* get nameservers from the Windows NT registry */ - if (RegOpenKey(HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", - &hndKey) == ERROR_SUCCESS) { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_TCPIP_PARA, 0, KEY_QUERY_VALUE, &hndKey) == ERROR_SUCCESS) { DWORD Type = 0; DWORD Size = 0; LONG Result; - Result = - RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, NULL, - &Size); + Result = RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { t = (char *) xmalloc(Size); - RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, (LPBYTE) t, - &Size); + RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, (LPBYTE) t, &Size); token = strtok(t, ", "); while (token) { @@ -454,8 +444,7 @@ idnsParseWIN32Registry(void) xfree(t); } - Result = - RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size); + Result = RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { t = (char *) xmalloc(Size); @@ -489,64 +478,63 @@ idnsParseWIN32Registry(void) /* get nameservers from the Windows 2000 registry */ /* search all interfaces for DNS server addresses */ - if (RegOpenKey(HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", - &hndKey) == ERROR_SUCCESS) { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_TCPIP_PARA_INTERFACES, 0, KEY_READ, &hndKey) == ERROR_SUCCESS) { int i; - char keyname[255]; - - for (i = 0; i < 10; i++) { - if (RegEnumKey(hndKey, i, (char *) &keyname, - 255) == ERROR_SUCCESS) { - char newkeyname[255]; - strcpy(newkeyname, - "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"); - strcat(newkeyname, keyname); - - if (RegOpenKey(HKEY_LOCAL_MACHINE, newkeyname, - &hndKey2) == ERROR_SUCCESS) { - DWORD Type = 0; - DWORD Size = 0; - LONG Result; - Result = - RegQueryValueEx(hndKey2, "DhcpNameServer", NULL, - &Type, NULL, &Size); - - if (Result == ERROR_SUCCESS && Size) { - t = (char *) xmalloc(Size); - RegQueryValueEx(hndKey2, "DhcpNameServer", NULL, - &Type, (LPBYTE) t, &Size); - token = strtok(t, ", "); - - while (token) { - debugs(78, 1, "Adding DHCP nameserver " << token << " from Registry"); - idnsAddNameserver(token); - token = strtok(NULL, ", "); + int MaxSubkeyLen; + DWORD InterfacesCount; + char *keyname; + FILETIME ftLastWriteTime; + + if (RegQueryInfoKey(hndKey, NULL, NULL, NULL, &InterfacesCount, &MaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + keyname = (char *) xmalloc(++MaxSubkeyLen); + for (i = 0; i < (int) InterfacesCount; i++) { + int j; + j = MaxSubkeyLen; + if (RegEnumKeyEx(hndKey, i, keyname, &j, NULL, NULL, NULL, &ftLastWriteTime) == ERROR_SUCCESS) { + char *newkeyname; + newkeyname = (char *) xmalloc(sizeof(REG_TCPIP_PARA_INTERFACES) + j + 2); + strcpy(newkeyname, REG_TCPIP_PARA_INTERFACES); + strcat(newkeyname, "\\"); + strcat(newkeyname, keyname); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newkeyname, 0, KEY_QUERY_VALUE, &hndKey2) == ERROR_SUCCESS) { + DWORD Type = 0; + DWORD Size = 0; + LONG Result; + Result = RegQueryValueEx(hndKey2, "DhcpNameServer", NULL, &Type, NULL, &Size); + if (Result == ERROR_SUCCESS && Size) { + t = (char *) xmalloc(Size); + RegQueryValueEx(hndKey2, "DhcpNameServer", NULL, &Type, t, &Size); + token = strtok(t, ", "); + while (token) { + debugs(78, 1, "Adding DHCP nameserver " << token << " from Registry"); + idnsAddNameserver(token); + token = strtok(NULL, ", "); + } + xfree(t); + } + + Result = RegQueryValueEx(hndKey2, "NameServer", NULL, &Type, NULL, &Size); + if (Result == ERROR_SUCCESS && Size) { + t = (char *) xmalloc(Size); + RegQueryValueEx(hndKey2, "NameServer", NULL, &Type, t, &Size); + token = strtok(t, ", "); + while (token) { + debugs(78, 1, "Adding nameserver " << token << " from Registry"); + idnsAddNameserver(token); + token = strtok(NULL, ", "); + } + + xfree(t); } - xfree(t); - } - - Result = - RegQueryValueEx(hndKey2, "NameServer", NULL, &Type, - NULL, &Size); - - if (Result == ERROR_SUCCESS && Size) { - t = (char *) xmalloc(Size); - RegQueryValueEx(hndKey2, "NameServer", NULL, &Type, - (LPBYTE) t, &Size); - token = strtok(t, ", "); - while (token) { - debugs(78, 1, "Adding nameserver " << token << " from Registry"); - idnsAddNameserver(token); - token = strtok(NULL, ", "); - } - xfree(t); + RegCloseKey(hndKey2); } - RegCloseKey(hndKey2); + xfree(newkeyname); } } + + xfree(keyname); } RegCloseKey(hndKey); @@ -563,14 +551,11 @@ idnsParseWIN32Registry(void) case _WIN_OS_WINME: /* get nameservers from the Windows 9X registry */ - if (RegOpenKey(HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP", - &hndKey) == ERROR_SUCCESS) { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_VXD_MSTCP, 0, KEY_QUERY_VALUE, &hndKey) == ERROR_SUCCESS) { DWORD Type = 0; DWORD Size = 0; LONG Result; - Result = - RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size); + Result = RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { t = (char *) xmalloc(Size); -- 2.47.3