#include <rpc.h>
+/* Handle of security.dll or secur32.dll, depending on Windows version */
+static HMODULE s_hSecDll = NULL;
+/* Pointer to SSPI dispatch table */
+static PSecurityFunctionTable s_pSecFn = NULL;
+
#endif
/* The last #include file should be: */
ntlm->type_2 = NULL;
}
if (ntlm->has_handles) {
- DeleteSecurityContext(&ntlm->c_handle);
- FreeCredentialsHandle(&ntlm->handle);
+ s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
+ s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
ntlm->has_handles = 0;
}
if (ntlm->p_identity) {
if(!passwdp)
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_pSecFn == NULL)
+ return CURLE_RECV_ERROR;
+#endif
+
switch(ntlm->state) {
case NTLMSTATE_TYPE1:
default: /* for the weird cases we (re)start here */
ntlm->p_identity = NULL;
}
- if (AcquireCredentialsHandle(
+ if (s_pSecFn->AcquireCredentialsHandle(
NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity,
NULL, NULL, &ntlm->handle, &tsDummy
) != SEC_E_OK) {
buf.BufferType = SECBUFFER_TOKEN;
buf.pvBuffer = ntlmbuf;
- status = InitializeSecurityContext(&ntlm->handle, NULL, (char *) host,
+ status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL, (char *) host,
ISC_REQ_CONFIDENTIALITY |
ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONNECTION,
if (status == SEC_I_COMPLETE_AND_CONTINUE ||
status == SEC_I_CONTINUE_NEEDED) {
- /* CompleteAuthToken() is not present in Win9x, so load it dynamically */
- SECURITY_STATUS (__stdcall * pCompleteAuthToken)
- (PCtxtHandle,PSecBufferDesc);
- HMODULE hSecur32 = GetModuleHandle("secur32.dll");
- if (hSecur32 != NULL) {
- pCompleteAuthToken =
- (SECURITY_STATUS (__stdcall *)(PCtxtHandle,PSecBufferDesc))
- GetProcAddress(hSecur32, "CompleteAuthToken");
- if( pCompleteAuthToken != NULL ) {
- pCompleteAuthToken(&ntlm->c_handle, &desc);
- }
- }
+ s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc);
}
else if (status != SEC_E_OK) {
- FreeCredentialsHandle(&ntlm->handle);
+ s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
return CURLE_RECV_ERROR;
}
type_3.pvBuffer = ntlmbuf;
type_3.cbBuffer = sizeof(ntlmbuf);
- status = InitializeSecurityContext(&ntlm->handle, &ntlm->c_handle,
+ status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, &ntlm->c_handle,
(char *) host,
ISC_REQ_CONFIDENTIALITY |
ISC_REQ_REPLAY_DETECT |
#ifdef USE_WINDOWS_SSPI
ntlm_sspi_cleanup(&conn->ntlm);
ntlm_sspi_cleanup(&conn->proxyntlm);
+ if (s_hSecDll != NULL) {
+ FreeLibrary(s_hSecDll);
+ s_hSecDll = NULL;
+ s_pSecFn = NULL;
+ }
#else
(void)conn;
#endif