Introduced curl_sspi.c and curl_sspi.h for the implementation of functions

Curl_sspi_global_init() and Curl_sspi_global_cleanup() which previously were
named Curl_ntlm_global_init() and Curl_ntlm_global_cleanup() in http_ntlm.c
Also adjusted socks_sspi.c to remove the link-time dependency on the Windows
SSPI library using it now in the same way as it was done in http_ntlm.c.
This commit is contained in:
Yang Tse 2009-01-29 20:32:27 +00:00
parent 1bd0be0361
commit e813bf31d7
11 changed files with 308 additions and 180 deletions

View File

@ -6,6 +6,13 @@
Changelog
Yang Tse (29 Jan 2009)
- Introduced curl_sspi.c and curl_sspi.h for the implementation of functions
Curl_sspi_global_init() and Curl_sspi_global_cleanup() which previously were
named Curl_ntlm_global_init() and Curl_ntlm_global_cleanup() in http_ntlm.c
Also adjusted socks_sspi.c to remove the link-time dependency on the Windows
SSPI library using it now in the same way as it was done in http_ntlm.c.
Daniel Stenberg (28 Jan 2009)
- Markus Moeller introduced two new options to libcurl:
CURLOPT_SOCKS5_GSSAPI_SERVICE and CURLOPT_SOCKS5_GSSAPI_NEC to allow libcurl

View File

@ -10,7 +10,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \
inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \
strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c \
socks_gssapi.c socks_sspi.c
socks_gssapi.c socks_sspi.c curl_sspi.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
@ -21,4 +21,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
strtoofft.h strerror.h inet_ntop.h curlx.h memory.h setup.h \
transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h \
tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \
curl_base64.h rawstr.h curl_addrinfo.h
curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h

View File

@ -101,7 +101,7 @@ LFLAGS = /nologo /machine:$(MACHINE)
SSLLIBS = libeay32.lib ssleay32.lib
ZLIBLIBSDLL= zdll.lib
ZLIBLIBS = zlib.lib
WINLIBS = wsock32.lib wldap32.lib secur32.lib
WINLIBS = wsock32.lib wldap32.lib
CFLAGS = $(CFLAGS)
CFGSET = FALSE
@ -450,6 +450,7 @@ X_OBJS= \
$(DIROBJ)\content_encoding.obj \
$(DIROBJ)\cookie.obj \
$(DIROBJ)\curl_addrinfo.obj \
$(DIROBJ)\curl_sspi.obj \
$(DIROBJ)\dict.obj \
$(DIROBJ)\easy.obj \
$(DIROBJ)\escape.obj \

119
lib/curl_sspi.c Normal file
View File

@ -0,0 +1,119 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#ifdef USE_WINDOWS_SSPI
#include <curl/curl.h>
#include "curl_sspi.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Handle of security.dll or secur32.dll, depending on Windows version */
HMODULE s_hSecDll = NULL;
/* Pointer to SSPI dispatch table */
PSecurityFunctionTableA s_pSecFn = NULL;
/*
* Curl_sspi_global_init()
*
* This is used to load the Security Service Provider Interface (SSPI)
* dynamic link library portably across all Windows versions, without
* the need to directly link libcurl, nor the application using it, at
* build time.
*
* Once this function has been execured, Windows SSPI functions can be
* called through the Security Service Provider Interface dispatch table.
*/
CURLcode
Curl_sspi_global_init(void)
{
OSVERSIONINFO osver;
INIT_SECURITY_INTERFACE_A pInitSecurityInterface;
/* If security interface is not yet initialized try to do this */
if(s_hSecDll == NULL) {
/* Find out Windows version */
memset(&osver, 0, sizeof(osver));
osver.dwOSVersionInfoSize = sizeof(osver);
if(! GetVersionEx(&osver))
return CURLE_FAILED_INIT;
/* 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(osver.dwPlatformId == VER_PLATFORM_WIN32_NT
&& osver.dwMajorVersion == 4)
s_hSecDll = LoadLibrary("security.dll");
else
s_hSecDll = LoadLibrary("secur32.dll");
if(! s_hSecDll)
return CURLE_FAILED_INIT;
/* Get address of the InitSecurityInterfaceA function from the SSPI dll */
pInitSecurityInterface = (INIT_SECURITY_INTERFACE_A)
GetProcAddress(s_hSecDll, "InitSecurityInterfaceA");
if(! pInitSecurityInterface)
return CURLE_FAILED_INIT;
/* Get pointer to Security Service Provider Interface dispatch table */
s_pSecFn = pInitSecurityInterface();
if(! s_pSecFn)
return CURLE_FAILED_INIT;
}
return CURLE_OK;
}
/*
* Curl_sspi_global_cleanup()
*
* This deinitializes the Security Service Provider Interface from libcurl.
*/
void
Curl_sspi_global_cleanup(void)
{
if(s_hSecDll) {
FreeLibrary(s_hSecDll);
s_hSecDll = NULL;
s_pSecFn = NULL;
}
}
#endif /* USE_WINDOWS_SSPI */

53
lib/curl_sspi.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef HEADER_CURL_SSPI_H
#define HEADER_CURL_SSPI_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#ifdef USE_WINDOWS_SSPI
#include <curl/curl.h>
/*
* When including the folowing three headers, it is mandatory to define either
* SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code.
*/
#undef SECURITY_WIN32
#undef SECURITY_KERNEL
#define SECURITY_WIN32 1
#include <security.h>
#include <sspi.h>
#include <rpc.h>
CURLcode Curl_sspi_global_init(void);
void Curl_sspi_global_cleanup(void);
/* Forward-declaration of global variables defined in curl_sspi.c */
extern HMODULE s_hSecDll;
extern PSecurityFunctionTableA s_pSecFn;
#endif /* USE_WINDOWS_SSPI */
#endif /* HEADER_CURL_SSPI_H */

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2009, 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
@ -111,7 +111,7 @@ static void win32_cleanup(void)
WSACleanup();
#endif
#ifdef USE_WINDOWS_SSPI
Curl_ntlm_global_cleanup();
Curl_sspi_global_cleanup();
#endif
}
@ -156,7 +156,7 @@ static CURLcode win32_init(void)
#ifdef USE_WINDOWS_SSPI
{
CURLcode err = Curl_ntlm_global_init();
CURLcode err = Curl_sspi_global_init();
if (err != CURLE_OK)
return err;
}

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2009, 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
@ -106,12 +106,7 @@
#else
#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;
#include "curl_sspi.h"
#endif
@ -552,7 +547,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
#ifdef USE_WINDOWS_SSPI
if (s_hSecDll == NULL) {
/* not thread safe and leaks - use curl_global_init() to avoid */
CURLcode err = Curl_ntlm_global_init();
CURLcode err = Curl_sspi_global_init();
if (s_hSecDll == NULL)
return err;
}
@ -1103,48 +1098,6 @@ Curl_ntlm_cleanup(struct connectdata *conn)
#endif
}
#ifdef USE_WINDOWS_SSPI
CURLcode Curl_ntlm_global_init(void)
{
/* 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(void)
{
if(s_hSecDll != NULL) {
FreeLibrary(s_hSecDll);
s_hSecDll = NULL;
s_pSecFn = NULL;
}
}
#endif
#endif /* USE_NTLM */
#endif /* !CURL_DISABLE_HTTP */

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2009, 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,11 +44,6 @@ void Curl_ntlm_cleanup(struct connectdata *conn);
#define Curl_ntlm_cleanup(x)
#endif
#ifdef USE_WINDOWS_SSPI
CURLcode Curl_ntlm_global_init(void);
void Curl_ntlm_global_cleanup(void);
#endif
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)

View File

@ -40,6 +40,7 @@
#include "connect.h"
#include "timeval.h"
#include "socks.h"
#include "curl_sspi.h"
/* The last #include file should be: */
#include "memdebug.h"
@ -233,22 +234,22 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
cred_handle.dwLower = 0;
cred_handle.dwUpper = 0;
sspi_major_status = AcquireCredentialsHandle( NULL,
(char *)"Kerberos",
SECPKG_CRED_OUTBOUND,
NULL,
NULL,
NULL,
NULL,
&cred_handle,
&expiry);
sspi_major_status = s_pSecFn->AcquireCredentialsHandleA( NULL,
(char *)"Kerberos",
SECPKG_CRED_OUTBOUND,
NULL,
NULL,
NULL,
NULL,
&cred_handle,
&expiry);
if(check_sspi_err(data, sspi_major_status,sspi_minor_status,
"AcquireCredentialsHandle") ) {
"AcquireCredentialsHandleA") ) {
failf(data, "Failed to acquire credentials.");
free(service_name);
service_name=NULL;
FreeCredentialsHandle(&cred_handle);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
return CURLE_COULDNT_CONNECT;
}
@ -256,35 +257,36 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
/* errors, keep sending it... */
for(;;) {
sspi_major_status = InitializeSecurityContext( &cred_handle,
context_handle,
service_name,
ISC_REQ_MUTUAL_AUTH |
ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_CONFIDENTIALITY |
ISC_REQ_REPLAY_DETECT,
0,
SECURITY_NATIVE_DREP,
&input_desc,
0,
&sspi_context,
&output_desc,
&sspi_ret_flags,
&expiry);
sspi_major_status = s_pSecFn->InitializeSecurityContextA(
&cred_handle,
context_handle,
service_name,
ISC_REQ_MUTUAL_AUTH |
ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_CONFIDENTIALITY |
ISC_REQ_REPLAY_DETECT,
0,
SECURITY_NATIVE_DREP,
&input_desc,
0,
&sspi_context,
&output_desc,
&sspi_ret_flags,
&expiry);
if(sspi_recv_token.pvBuffer) {
FreeContextBuffer(sspi_recv_token.pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
sspi_recv_token.pvBuffer = NULL;
sspi_recv_token.cbBuffer = 0;
}
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
"InitializeSecurityContext") ){
"InitializeSecurityContextA") ){
free(service_name);
service_name=NULL;
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
FreeContextBuffer(sspi_recv_token.pvBuffer);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
failf(data, "Failed to initialise security context.");
return CURLE_COULDNT_CONNECT;
}
@ -300,10 +302,10 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
failf(data, "Failed to send SSPI authentication request.");
free(service_name);
service_name=NULL;
FreeContextBuffer(sspi_send_token.pvBuffer);
FreeContextBuffer(sspi_recv_token.pvBuffer);
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -313,19 +315,19 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
failf(data, "Failed to send SSPI authentication token.");
free(service_name);
service_name=NULL;
FreeContextBuffer(sspi_send_token.pvBuffer);
FreeContextBuffer(sspi_recv_token.pvBuffer);
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
}
FreeContextBuffer(sspi_send_token.pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
sspi_send_token.pvBuffer = NULL;
sspi_send_token.cbBuffer = 0;
FreeContextBuffer(sspi_recv_token.pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
sspi_recv_token.pvBuffer = NULL;
sspi_recv_token.cbBuffer = 0;
if(sspi_major_status != SEC_I_CONTINUE_NEEDED) break;
@ -346,8 +348,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
failf(data, "Failed to receive SSPI authentication response.");
free(service_name);
service_name=NULL;
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -357,8 +359,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
socksreq[0], socksreq[1]);
free(service_name);
service_name=NULL;
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -367,8 +369,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
socksreq[0], socksreq[1]);
free(service_name);
service_name=NULL;
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -381,8 +383,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
if(!sspi_recv_token.pvBuffer) {
free(service_name);
service_name=NULL;
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_OUT_OF_MEMORY;
}
result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
@ -393,9 +395,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
failf(data, "Failed to receive SSPI authentication token.");
free(service_name);
service_name=NULL;
FreeContextBuffer(sspi_recv_token.pvBuffer);
FreeCredentialsHandle(&cred_handle);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -406,19 +408,20 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
service_name=NULL;
/* Everything is good so far, user was authenticated! */
sspi_major_status =
QueryCredentialsAttributes(&cred_handle, SECPKG_CRED_ATTR_NAMES, &names);
FreeCredentialsHandle(&cred_handle);
sspi_major_status = s_pSecFn->QueryCredentialsAttributes( &cred_handle,
SECPKG_CRED_ATTR_NAMES,
&names);
s_pSecFn->FreeCredentialsHandle(&cred_handle);
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
"QueryCredentialAttributes") ){
DeleteSecurityContext(&sspi_context);
FreeContextBuffer(names.sUserName);
s_pSecFn->DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(names.sUserName);
failf(data, "Failed to determine user name.");
return CURLE_COULDNT_CONNECT;
}
infof(data, "SOCKS5 server authencticated user %s with gssapi.\n",
names.sUserName);
FreeContextBuffer(names.sUserName);
s_pSecFn->FreeContextBuffer(names.sUserName);
/* Do encryption */
socksreq[0] = 1; /* gssapi subnegotiation version */
@ -472,12 +475,12 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
memcpy(socksreq+2, &us_length, sizeof(short));
}
else {
sspi_major_status = QueryContextAttributes( &sspi_context,
SECPKG_ATTR_SIZES,
&sspi_sizes);
sspi_major_status = s_pSecFn->QueryContextAttributesA( &sspi_context,
SECPKG_ATTR_SIZES,
&sspi_sizes);
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
"QueryContextAttributes")) {
DeleteSecurityContext(&sspi_context);
"QueryContextAttributesA")) {
s_pSecFn->DeleteSecurityContext(&sspi_context);
failf(data, "Failed to query security context attributes.");
return CURLE_COULDNT_CONNECT;
}
@ -487,15 +490,15 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer);
if(!sspi_w_token[0].pvBuffer) {
DeleteSecurityContext(&sspi_context);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_OUT_OF_MEMORY;
}
sspi_w_token[1].cbBuffer = 1;
sspi_w_token[1].pvBuffer = malloc(1);
if(!sspi_w_token[1].pvBuffer){
FreeContextBuffer(sspi_w_token[0].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_OUT_OF_MEMORY;
}
@ -504,21 +507,21 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
if(!sspi_w_token[2].pvBuffer) {
FreeContextBuffer(sspi_w_token[0].pvBuffer);
FreeContextBuffer(sspi_w_token[1].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_OUT_OF_MEMORY;
}
sspi_major_status = EncryptMessage( &sspi_context,
KERB_WRAP_NO_ENCRYPT,
&wrap_desc,
0);
sspi_major_status = s_pSecFn->EncryptMessage( &sspi_context,
KERB_WRAP_NO_ENCRYPT,
&wrap_desc,
0);
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
"EncryptMessage") ) {
FreeContextBuffer(sspi_w_token[0].pvBuffer);
FreeContextBuffer(sspi_w_token[1].pvBuffer);
FreeContextBuffer(sspi_w_token[2].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
failf(data, "Failed to query security context attributes.");
return CURLE_COULDNT_CONNECT;
}
@ -527,10 +530,10 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+ sspi_w_token[2].cbBuffer;
sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer);
if(!sspi_send_token.pvBuffer) {
FreeContextBuffer(sspi_w_token[0].pvBuffer);
FreeContextBuffer(sspi_w_token[1].pvBuffer);
FreeContextBuffer(sspi_w_token[2].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_OUT_OF_MEMORY;
}
@ -543,13 +546,13 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+sspi_w_token[1].cbBuffer,
sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer);
FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
sspi_w_token[0].pvBuffer = NULL;
sspi_w_token[0].cbBuffer = 0;
FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
sspi_w_token[1].pvBuffer = NULL;
sspi_w_token[1].cbBuffer = 0;
FreeContextBuffer(sspi_w_token[2].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
sspi_w_token[2].pvBuffer = NULL;
sspi_w_token[2].cbBuffer = 0;
@ -560,8 +563,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
if((code != CURLE_OK) || (4 != written)) {
failf(data, "Failed to send SSPI encryption request.");
FreeContextBuffer(sspi_send_token.pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -570,7 +573,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
if((code != CURLE_OK) || (1 != written)) {
failf(data, "Failed to send SSPI encryption type.");
DeleteSecurityContext(&sspi_context);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
} else {
@ -578,18 +581,18 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
sspi_send_token.cbBuffer, &written);
if((code != CURLE_OK) || (sspi_send_token.cbBuffer != (size_t)written)) {
failf(data, "Failed to send SSPI encryption type.");
FreeContextBuffer(sspi_send_token.pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
FreeContextBuffer(sspi_send_token.pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
}
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4,
&actualread, timeout);
if(result != CURLE_OK || actualread != 4) {
failf(data, "Failed to receive SSPI encryption response.");
DeleteSecurityContext(&sspi_context);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -597,14 +600,14 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
if(socksreq[1] == 255) { /* status / message type */
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
socksreq[0], socksreq[1]);
DeleteSecurityContext(&sspi_context);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
if(socksreq[1] != 2) { /* status / message type */
failf(data, "Invalid SSPI encryption response type (%d %d).",
socksreq[0], socksreq[1]);
DeleteSecurityContext(&sspi_context);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -614,7 +617,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
sspi_w_token[0].cbBuffer = us_length;
sspi_w_token[0].pvBuffer = malloc(us_length);
if(!sspi_w_token[0].pvBuffer) {
DeleteSecurityContext(&sspi_context);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_OUT_OF_MEMORY;
}
@ -624,8 +627,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
if(result != CURLE_OK || actualread != us_length) {
failf(data, "Failed to receive SSPI encryption type.");
FreeContextBuffer(sspi_w_token[0].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
@ -637,13 +640,16 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
sspi_w_token[1].cbBuffer = 0;
sspi_w_token[1].pvBuffer = NULL;
sspi_major_status = DecryptMessage(&sspi_context, &wrap_desc, 0, &qop);
sspi_major_status = s_pSecFn->DecryptMessage( &sspi_context,
&wrap_desc,
0,
&qop);
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
"DecryptMessage")) {
FreeContextBuffer(sspi_w_token[0].pvBuffer);
FreeContextBuffer(sspi_w_token[1].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
failf(data, "Failed to query security context attributes.");
return CURLE_COULDNT_CONNECT;
}
@ -651,25 +657,25 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
if(sspi_w_token[1].cbBuffer != 1) {
failf(data, "Invalid SSPI encryption response length (%d).",
sspi_w_token[1].cbBuffer);
FreeContextBuffer(sspi_w_token[0].pvBuffer);
FreeContextBuffer(sspi_w_token[1].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
memcpy(socksreq,sspi_w_token[1].pvBuffer,sspi_w_token[1].cbBuffer);
FreeContextBuffer(sspi_w_token[0].pvBuffer);
FreeContextBuffer(sspi_w_token[1].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
} else {
if(sspi_w_token[0].cbBuffer != 1) {
failf(data, "Invalid SSPI encryption response length (%d).",
sspi_w_token[0].cbBuffer);
FreeContextBuffer(sspi_w_token[0].pvBuffer);
DeleteSecurityContext(&sspi_context);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->DeleteSecurityContext(&sspi_context);
return CURLE_COULDNT_CONNECT;
}
memcpy(socksreq,sspi_w_token[0].pvBuffer,sspi_w_token[0].cbBuffer);
FreeContextBuffer(sspi_w_token[0].pvBuffer);
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
}
infof(data, "SOCKS5 access with%s protection granted.\n",
@ -681,7 +687,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
if (socksreq[0] != 0)
conn->socks5_sspi_context = sspi_context;
else {
DeleteSecurityContext(&sspi_context);
s_pSecFn->DeleteSecurityContext(&sspi_context);
conn->socks5_sspi_context = sspi_context;
}
*/

View File

@ -269,13 +269,7 @@ typedef enum {
} curlntlm;
#ifdef USE_WINDOWS_SSPI
/* When including these headers, you must define either SECURITY_WIN32
* or SECURITY_KERNEL, indicating who is compiling the code.
*/
#define SECURITY_WIN32 1
#include <security.h>
#include <sspi.h>
#include <rpc.h>
#include "curl_sspi.h"
#endif
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)

View File

@ -221,8 +221,8 @@ LFLAGS = $(LFLAGS) $(SSL_IMP_LFLAGS) $(ZLIB_LFLAGS)
!ENDIF
LINKLIBS = $(LINKLIBS) wsock32.lib wldap32.lib secur32.lib
LINKLIBS_DEBUG = $(LINKLIBS_DEBUG) wsock32.lib wldap32.lib secur32.lib
LINKLIBS = $(LINKLIBS) wsock32.lib wldap32.lib
LINKLIBS_DEBUG = $(LINKLIBS_DEBUG) wsock32.lib wldap32.lib
all : release