diff options
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | RELEASE-NOTES | 1 | ||||
-rw-r--r-- | lib/easy.c | 24 | ||||
-rw-r--r-- | lib/http_ntlm.c | 80 | ||||
-rw-r--r-- | lib/http_ntlm.h | 6 |
5 files changed, 78 insertions, 39 deletions
@@ -8,6 +8,12 @@ Daniel Stenberg (11 Aug 2008) +- Constantine Sapuntzakis filed bug report #2042430 + (http://curl.haxx.se/bug/view.cgi?id=2042430) with a patch. "NTLM Windows + SSPI code is not thread safe". This was due to libcurl using static + variables to tell wether to load the necessary SSPI DLL, but now the loading + has been moved to the more suitable curl_global_init() call. + - Constantine Sapuntzakis filed bug report #2042440 (http://curl.haxx.se/bug/view.cgi?id=2042440) with a patch. He identified a problem when using NTLM over a proxy but the end-point does Basic, and then diff --git a/RELEASE-NOTES b/RELEASE-NOTES index d105b61ba..b5ade6f3c 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -50,6 +50,7 @@ This release includes the following bugfixes: o HTTP PUT or POST with redirect could lead to hang o re-use of connections with failed SSL connects in the multi interface o NTLM over proxy state was wrongly cleared when host connection was closed + o Windows SSPI DLL loading is now done in curl_global_init() This release includes the following known bugs: diff --git a/lib/easy.c b/lib/easy.c index 216dfe7bf..9d9e948ce 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -83,6 +83,7 @@ #include "easyif.h" #include "select.h" #include "sendf.h" /* for failf function prototype */ +#include "http_ntlm.h" #include "connect.h" /* for Curl_getconnectinfo */ #define _MPRINTF_REPLACE /* use our functions only */ @@ -103,18 +104,23 @@ /* The last #include file should be: */ #include "memdebug.h" -#ifdef USE_WINSOCK /* win32_cleanup() is for win32 socket cleanup functionality, the opposite of win32_init() */ static void win32_cleanup(void) { +#ifdef USE_WINSOCK WSACleanup(); +#endif +#ifdef USE_WINDOWS_SSPI + Curl_ntlm_global_cleanup(); +#endif } /* win32_init() performs win32 socket initialization to properly setup the stack to allow networking */ static CURLcode win32_init(void) { +#ifdef USE_WINSOCK WORD wVersionRequested; WSADATA wsaData; int err; @@ -147,15 +153,19 @@ static CURLcode win32_init(void) return CURLE_FAILED_INIT; } /* The Windows Sockets DLL is acceptable. Proceed. */ - return CURLE_OK; -} +#endif -#else -/* These functions exist merely to prevent compiler warnings */ -static CURLcode win32_init(void) { return CURLE_OK; } -static void win32_cleanup(void) { } +#ifdef USE_WINDOWS_SSPI + { + CURLcode err = Curl_ntlm_global_init(); + if (err != CURLE_OK) + return err; + } #endif + return CURLE_OK; +} + #ifdef USE_LIBIDN /* * Initialise use of IDNA library. diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index 045e8876d..89e5f962c 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -358,7 +358,7 @@ static void lm_resp(unsigned char *keys, * Set up lanmanager hashed password */ static void mk_lm_hash(struct SessionHandle *data, - char *password, + char *password, unsigned char *lmbuffer /* 21 bytes */) { unsigned char pw[14]; @@ -545,32 +545,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, passwdp=(char *)""; #ifdef USE_WINDOWS_SSPI - /* If security interface is not yet initialized try to do this */ - if(s_hSecDll == NULL) { - /* Determine Windows version. Security functions are located in - * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP - * contain both these DLLs (security.dll just forwards calls to - * secur32.dll) - */ - OSVERSIONINFO osver; - osver.dwOSVersionInfoSize = sizeof(osver); - GetVersionEx(&osver); - if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT - && osver.dwMajorVersion == 4) - s_hSecDll = LoadLibrary("security.dll"); - else - s_hSecDll = LoadLibrary("secur32.dll"); - if(s_hSecDll != NULL) { - INIT_SECURITY_INTERFACE pInitSecurityInterface; - pInitSecurityInterface = - (INIT_SECURITY_INTERFACE)GetProcAddress(s_hSecDll, - "InitSecurityInterfaceA"); - if(pInitSecurityInterface != NULL) - s_pSecFn = pInitSecurityInterface(); - } + if (s_hSecDll == NULL) { + /* not thread safe and leaks - use curl_global_init() to avoid */ + CURLcode err = Curl_ntlm_global_init(); + if (s_hSecDll == NULL) + return err; } - if(s_pSecFn == NULL) - return CURLE_RECV_ERROR; #endif switch(ntlm->state) { @@ -1064,7 +1044,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, #ifdef CURL_DOES_CONVERSIONS /* convert domain, user, and host to ASCII but leave the rest as-is */ - if(CURLE_OK != Curl_convert_to_network(conn->data, + if(CURLE_OK != Curl_convert_to_network(conn->data, (char *)&ntlmbuf[domoff], size-domoff)) { return CURLE_CONV_FAILED; @@ -1113,15 +1093,53 @@ Curl_ntlm_cleanup(struct connectdata *conn) #ifdef USE_WINDOWS_SSPI ntlm_sspi_cleanup(&conn->ntlm); ntlm_sspi_cleanup(&conn->proxyntlm); +#else + (void)conn; +#endif +} + +#ifdef USE_WINDOWS_SSPI +CURLcode Curl_ntlm_global_init() +{ + /* If security interface is not yet initialized try to do this */ + if(s_hSecDll == NULL) { + /* Determine Windows version. Security functions are located in + * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP + * contain both these DLLs (security.dll just forwards calls to + * secur32.dll) + */ + OSVERSIONINFO osver; + osver.dwOSVersionInfoSize = sizeof(osver); + GetVersionEx(&osver); + if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT + && osver.dwMajorVersion == 4) + s_hSecDll = LoadLibrary("security.dll"); + else + s_hSecDll = LoadLibrary("secur32.dll"); + if(s_hSecDll != NULL) { + INIT_SECURITY_INTERFACE pInitSecurityInterface; + pInitSecurityInterface = + (INIT_SECURITY_INTERFACE)GetProcAddress(s_hSecDll, + "InitSecurityInterfaceA"); + if(pInitSecurityInterface != NULL) + s_pSecFn = pInitSecurityInterface(); + } + } + if(s_pSecFn == NULL) + return CURLE_RECV_ERROR; + + return CURLE_OK; +} + +void Curl_ntlm_global_cleanup() +{ if(s_hSecDll != NULL) { FreeLibrary(s_hSecDll); s_hSecDll = NULL; s_pSecFn = NULL; } -#else - (void)conn; -#endif } +#endif #endif /* USE_NTLM */ #endif /* !CURL_DISABLE_HTTP */ diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h index 40a0c9b5d..c5e73ede8 100644 --- a/lib/http_ntlm.h +++ b/lib/http_ntlm.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -44,6 +44,10 @@ void Curl_ntlm_cleanup(struct connectdata *conn); #define Curl_ntlm_cleanup(x) #endif +#ifdef USE_WINDOWS_SSPI +CURLcode Curl_ntlm_global_init(); +void Curl_ntlm_global_cleanup(); +#endif /* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */ |