mirror of
https://github.com/curl/curl.git
synced 2026-08-05 13:46:15 +03:00
windows: reduce/stop loading DLLs at runtime
- replace dynamic `InitSecurityInterface()` call with early binding and link `secur32` system DLL. The library and function are available in all supported curl Windows targets, meaning WinXP or newer. Add small hack for mingw32ce to make it build. - detect and use `if_nametoindex()` on Windows when available. Link `iphlpapi` system DLL. Requires targeting Vista or newer. Replacing the dynamic call and the pre-load optimization for lib3026. Suggested-by: Jay Satiro Closes #17413
This commit is contained in:
parent
c129d0b1a8
commit
0d71b18153
16 changed files with 186 additions and 182 deletions
|
|
@ -37,23 +37,6 @@
|
|||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* We use our own typedef here since some headers might lack these */
|
||||
typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID);
|
||||
|
||||
/* See definition of SECURITY_ENTRYPOINT in sspi.h */
|
||||
#ifdef UNICODE
|
||||
# ifdef UNDER_CE
|
||||
# define SECURITYENTRYPOINT L"InitSecurityInterfaceW"
|
||||
# else
|
||||
# define SECURITYENTRYPOINT "InitSecurityInterfaceW"
|
||||
# endif
|
||||
#else
|
||||
# define SECURITYENTRYPOINT "InitSecurityInterfaceA"
|
||||
#endif
|
||||
|
||||
/* Handle of security.dll or secur32.dll, depending on Windows version */
|
||||
HMODULE Curl_hSecDll = NULL;
|
||||
|
||||
/* Pointer to SSPI dispatch table */
|
||||
PSecurityFunctionTable Curl_pSecFn = NULL;
|
||||
|
||||
|
|
@ -76,31 +59,14 @@ PSecurityFunctionTable Curl_pSecFn = NULL;
|
|||
*/
|
||||
CURLcode Curl_sspi_global_init(void)
|
||||
{
|
||||
INITSECURITYINTERFACE_FN pInitSecurityInterface;
|
||||
|
||||
/* If security interface is not yet initialized try to do this */
|
||||
if(!Curl_hSecDll) {
|
||||
/* Security Service Provider Interface (SSPI) functions are located in
|
||||
* security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
|
||||
* have both these DLLs (security.dll forwards calls to secur32.dll) */
|
||||
|
||||
/* Load SSPI dll into the address space of the calling process */
|
||||
if(curlx_verify_windows_version(4, 0, 0, PLATFORM_WINNT, VERSION_EQUAL))
|
||||
Curl_hSecDll = Curl_load_library(TEXT("security.dll"));
|
||||
else
|
||||
Curl_hSecDll = Curl_load_library(TEXT("secur32.dll"));
|
||||
if(!Curl_hSecDll)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Get address of the InitSecurityInterfaceA function from the SSPI dll */
|
||||
pInitSecurityInterface =
|
||||
CURLX_FUNCTION_CAST(INITSECURITYINTERFACE_FN,
|
||||
(GetProcAddress(Curl_hSecDll, SECURITYENTRYPOINT)));
|
||||
if(!pInitSecurityInterface)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if(!Curl_pSecFn) {
|
||||
/* Get pointer to Security Service Provider Interface dispatch table */
|
||||
Curl_pSecFn = pInitSecurityInterface();
|
||||
#ifdef __MINGW32CE__
|
||||
Curl_pSecFn = InitSecurityInterfaceW();
|
||||
#else
|
||||
Curl_pSecFn = InitSecurityInterface();
|
||||
#endif
|
||||
if(!Curl_pSecFn)
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
|
@ -119,9 +85,7 @@ CURLcode Curl_sspi_global_init(void)
|
|||
*/
|
||||
void Curl_sspi_global_cleanup(void)
|
||||
{
|
||||
if(Curl_hSecDll) {
|
||||
FreeLibrary(Curl_hSecDll);
|
||||
Curl_hSecDll = NULL;
|
||||
if(Curl_pSecFn) {
|
||||
Curl_pSecFn = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
|||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
|
||||
/* Forward-declaration of global variables defined in curl_sspi.c */
|
||||
extern HMODULE Curl_hSecDll;
|
||||
extern PSecurityFunctionTable Curl_pSecFn;
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
|
|
|
|||
|
|
@ -178,10 +178,10 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy)
|
|||
passwdp = "";
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
if(!Curl_hSecDll) {
|
||||
if(!Curl_pSecFn) {
|
||||
/* not thread safe and leaks - use curl_global_init() to avoid */
|
||||
CURLcode err = Curl_sspi_global_init();
|
||||
if(!Curl_hSecDll)
|
||||
if(!Curl_pSecFn)
|
||||
return err;
|
||||
}
|
||||
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
|
||||
|
|
|
|||
|
|
@ -36,12 +36,17 @@
|
|||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef HAVE_IF_NAMETOINDEX
|
||||
/* Handle of iphlpapp.dll */
|
||||
static HMODULE s_hIpHlpApiDll = NULL;
|
||||
|
||||
/* Pointer to the if_nametoindex function */
|
||||
IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL;
|
||||
|
||||
/* This is used to dynamically load DLLs */
|
||||
static HMODULE curl_load_library(LPCTSTR filename);
|
||||
#endif
|
||||
|
||||
/* Curl_win32_init() performs Win32 global initialization */
|
||||
CURLcode Curl_win32_init(long flags)
|
||||
{
|
||||
|
|
@ -90,7 +95,8 @@ CURLcode Curl_win32_init(long flags)
|
|||
}
|
||||
#endif
|
||||
|
||||
s_hIpHlpApiDll = Curl_load_library(TEXT("iphlpapi.dll"));
|
||||
#ifndef HAVE_IF_NAMETOINDEX
|
||||
s_hIpHlpApiDll = curl_load_library(TEXT("iphlpapi.dll"));
|
||||
if(s_hIpHlpApiDll) {
|
||||
/* Get the address of the if_nametoindex function */
|
||||
#ifdef UNDER_CE
|
||||
|
|
@ -106,6 +112,7 @@ CURLcode Curl_win32_init(long flags)
|
|||
if(pIfNameToIndex)
|
||||
Curl_if_nametoindex = pIfNameToIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* curlx_verify_windows_version must be called during init at least once
|
||||
because it has its own initialization routine. */
|
||||
|
|
@ -123,11 +130,13 @@ CURLcode Curl_win32_init(long flags)
|
|||
/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */
|
||||
void Curl_win32_cleanup(long init_flags)
|
||||
{
|
||||
#ifndef HAVE_IF_NAMETOINDEX
|
||||
if(s_hIpHlpApiDll) {
|
||||
FreeLibrary(s_hIpHlpApiDll);
|
||||
s_hIpHlpApiDll = NULL;
|
||||
Curl_if_nametoindex = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
Curl_sspi_global_cleanup();
|
||||
|
|
@ -140,11 +149,13 @@ void Curl_win32_cleanup(long init_flags)
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
|
||||
#ifndef HAVE_IF_NAMETOINDEX
|
||||
|
||||
#ifndef LOAD_WITH_ALTERED_SEARCH_PATH
|
||||
#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008
|
||||
#endif
|
||||
|
||||
#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
|
||||
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#endif
|
||||
|
||||
|
|
@ -163,7 +174,7 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Curl_load_library()
|
||||
* curl_load_library()
|
||||
*
|
||||
* This is used to dynamically load DLLs using the most secure method available
|
||||
* for the version of Windows that we are running on.
|
||||
|
|
@ -176,7 +187,7 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
|
|||
*
|
||||
* Returns the handle of the module on success; otherwise NULL.
|
||||
*/
|
||||
HMODULE Curl_load_library(LPCTSTR filename)
|
||||
static HMODULE curl_load_library(LPCTSTR filename)
|
||||
{
|
||||
#if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
|
||||
HMODULE hModule = NULL;
|
||||
|
|
@ -228,7 +239,6 @@ HMODULE Curl_load_library(LPCTSTR filename)
|
|||
hModule = pLoadLibraryEx ?
|
||||
pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
|
||||
LoadLibrary(path);
|
||||
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
|
|
@ -240,5 +250,6 @@ HMODULE Curl_load_library(LPCTSTR filename)
|
|||
return NULL;
|
||||
#endif
|
||||
}
|
||||
#endif /* !HAVE_IF_NAMETOINDEX */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
|
|
|||
|
|
@ -36,14 +36,13 @@ extern bool Curl_isVistaOrGreater;
|
|||
CURLcode Curl_win32_init(long flags);
|
||||
void Curl_win32_cleanup(long init_flags);
|
||||
|
||||
#ifndef HAVE_IF_NAMETOINDEX
|
||||
/* We use our own typedef here since some headers might lack this */
|
||||
typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *);
|
||||
|
||||
/* This is used instead of if_nametoindex if available on Windows */
|
||||
extern IF_NAMETOINDEX_FN Curl_if_nametoindex;
|
||||
|
||||
/* This is used to dynamically load DLLs */
|
||||
HMODULE Curl_load_library(LPCTSTR filename);
|
||||
#endif
|
||||
#else /* _WIN32 */
|
||||
#define Curl_win32_init(x) CURLE_OK
|
||||
#endif /* !_WIN32 */
|
||||
|
|
|
|||
10
lib/url.c
10
lib/url.c
|
|
@ -59,6 +59,10 @@
|
|||
#error "We cannot compile without socket() support!"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IF_NAMETOINDEX) && defined(_WIN32)
|
||||
#include <iphlpapi.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "doh.h"
|
||||
|
|
@ -1794,10 +1798,10 @@ static void zonefrom_url(CURLU *uh, struct Curl_easy *data,
|
|||
#if defined(HAVE_IF_NAMETOINDEX) || defined(_WIN32)
|
||||
/* Zone identifier is not numeric */
|
||||
unsigned int scopeidx = 0;
|
||||
#ifdef _WIN32
|
||||
scopeidx = Curl_if_nametoindex(zoneid);
|
||||
#else
|
||||
#ifdef HAVE_IF_NAMETOINDEX
|
||||
scopeidx = if_nametoindex(zoneid);
|
||||
#else
|
||||
scopeidx = Curl_if_nametoindex(zoneid);
|
||||
#endif
|
||||
if(!scopeidx) {
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue