mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
SSPI related code: Unicode support for WinCE
SSPI related code now compiles with ANSI and WCHAR versions of security methods (WinCE requires WCHAR versions of methods). Pulled UTF8 to WCHAR conversion methods out of idn_win32.c into their own file. curl_sasl.c - include curl_memory.h to use correct memory functions. getenv.c and telnet.c - WinCE compatibility fix With some committer adjustments
This commit is contained in:
parent
16c725dbc7
commit
46480bb9a1
82
lib/curl_multibyte.c
Normal file
82
lib/curl_multibyte.c
Normal file
@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(USE_WIN32_IDN) || \
|
||||
(defined(USE_WINDOWS_SSPI) && (defined(_WIN32_WCE) || defined(UNICODE)))
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
|
||||
#include "curl_multibyte.h"
|
||||
|
||||
wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
|
||||
{
|
||||
wchar_t *str_w = NULL;
|
||||
|
||||
if(str_utf8) {
|
||||
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
||||
str_utf8, -1, NULL, 0);
|
||||
if(str_w_len) {
|
||||
str_w = malloc(str_w_len * sizeof(wchar_t));
|
||||
if(str_w) {
|
||||
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||
str_w_len) == 0) {
|
||||
free(str_w);
|
||||
str_w = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_w;
|
||||
}
|
||||
|
||||
const char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
{
|
||||
char *str_utf8 = NULL;
|
||||
|
||||
if(str_w) {
|
||||
size_t str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
|
||||
0, NULL, NULL);
|
||||
if(str_utf8_len) {
|
||||
str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
|
||||
if(str_utf8) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||
NULL, FALSE) == 0) {
|
||||
(void) GetLastError();
|
||||
free((void *)str_utf8);
|
||||
str_utf8 = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
(void) GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_IDN || (USE_WINDOWS_SSPI && (_WIN32_WCE || UNICODE)) */
|
40
lib/curl_multibyte.h
Normal file
40
lib/curl_multibyte.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef HEADER_CURL_MULTIBYTE_H
|
||||
#define HEADER_CURL_MULTIBYTE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(USE_WIN32_IDN) || \
|
||||
(defined(USE_WINDOWS_SSPI) && (defined(_WIN32_WCE) || defined(UNICODE)))
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
|
||||
const char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
|
||||
|
||||
#endif /* USE_WIN32_IDN || (USE_WINDOWS_SSPI && (_WIN32_WCE || UNICODE)) */
|
||||
|
||||
#endif /* HEADER_CURL_MULTIBYTE_H */
|
@ -89,6 +89,7 @@
|
||||
#include "curl_base64.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_gethostname.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define BUILDING_CURL_NTLM_MSGS_C
|
||||
@ -394,7 +395,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
SecBufferDesc desc;
|
||||
SECURITY_STATUS status;
|
||||
ULONG attrs;
|
||||
const char *dest = "";
|
||||
const char *user;
|
||||
const char *domain = "";
|
||||
size_t userlen = 0;
|
||||
@ -431,12 +431,22 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
*/
|
||||
ntlm->p_identity = &ntlm->identity;
|
||||
memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));
|
||||
#ifdef UNICODE
|
||||
if((ntlm->identity.User = Curl_convert_UTF8_to_wchar(user)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
ntlm->identity.UserLength = (unsigned long)userlen;
|
||||
#ifdef UNICODE
|
||||
if((ntlm->identity.Password = Curl_convert_UTF8_to_wchar(passwdp)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
ntlm->identity.PasswordLength = (unsigned long)passwdlen;
|
||||
if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL)
|
||||
@ -450,10 +460,10 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
else
|
||||
ntlm->p_identity = NULL;
|
||||
|
||||
status = s_pSecFn->AcquireCredentialsHandleA(NULL, (void *)"NTLM",
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
ntlm->p_identity, NULL, NULL,
|
||||
&ntlm->handle, &tsDummy);
|
||||
status = s_pSecFn->AcquireCredentialsHandle(NULL, TEXT("NTLM"),
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
ntlm->p_identity, NULL, NULL,
|
||||
&ntlm->handle, &tsDummy);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@ -464,15 +474,15 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
buf.BufferType = SECBUFFER_TOKEN;
|
||||
buf.pvBuffer = ntlmbuf;
|
||||
|
||||
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL,
|
||||
(void *)dest,
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
NULL, 0,
|
||||
&ntlm->c_handle, &desc,
|
||||
&attrs, &tsDummy);
|
||||
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL,
|
||||
TEXT(""),
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
NULL, 0,
|
||||
&ntlm->c_handle, &desc,
|
||||
&attrs, &tsDummy);
|
||||
|
||||
if(status == SEC_I_COMPLETE_AND_CONTINUE ||
|
||||
status == SEC_I_CONTINUE_NEEDED)
|
||||
@ -615,7 +625,6 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
const char *dest = "";
|
||||
SecBuffer type_2;
|
||||
SecBuffer type_3;
|
||||
SecBufferDesc type_2_desc;
|
||||
@ -640,17 +649,17 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
type_3.pvBuffer = ntlmbuf;
|
||||
type_3.cbBuffer = NTLM_BUFSIZE;
|
||||
|
||||
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle,
|
||||
&ntlm->c_handle,
|
||||
(void *)dest,
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
&type_2_desc,
|
||||
0, &ntlm->c_handle,
|
||||
&type_3_desc,
|
||||
&attrs, &tsDummy);
|
||||
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle,
|
||||
&ntlm->c_handle,
|
||||
TEXT(""),
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
&type_2_desc,
|
||||
0, &ntlm->c_handle,
|
||||
&type_3_desc,
|
||||
&attrs, &tsDummy);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "curl_ntlm_msgs.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
@ -68,9 +68,11 @@
|
||||
#include "strerror.h"
|
||||
#include "select.h" /* for the socket readyness */
|
||||
#include "inet_pton.h" /* for IP addr SNI check */
|
||||
#include "curl_multibyte.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@ -98,6 +100,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr6;
|
||||
#endif
|
||||
LPTSTR host_name;
|
||||
|
||||
infof(data, "schannel: connecting to %s:%hu (step 1/3)\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
@ -166,7 +169,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
failf(data, "schannel: SNI or certificate check failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
else
|
||||
failf(data, "schannel: AcquireCredentialsHandleA failed: %s",
|
||||
failf(data, "schannel: AcquireCredentialsHandle failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
free(connssl->cred);
|
||||
connssl->cred = NULL;
|
||||
@ -196,18 +199,31 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
|
||||
|
||||
#ifdef UNICODE
|
||||
host_name = Curl_convert_UTF8_to_wchar(conn->host.name);
|
||||
if(!host_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
host_name = conn->host.name;
|
||||
#endif
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
|
||||
|
||||
sspi_status = s_pSecFn->InitializeSecurityContext(
|
||||
&connssl->cred->cred_handle, NULL, conn->host.name,
|
||||
&connssl->cred->cred_handle, NULL, host_name,
|
||||
connssl->req_flags, 0, 0, NULL, 0, &connssl->ctxt->ctxt_handle,
|
||||
&outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
|
||||
|
||||
#ifdef UNICODE
|
||||
free(host_name);
|
||||
#endif
|
||||
|
||||
if(sspi_status != SEC_I_CONTINUE_NEEDED) {
|
||||
if(sspi_status == SEC_E_WRONG_PRINCIPAL)
|
||||
failf(data, "schannel: SNI or certificate check failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
else
|
||||
failf(data, "schannel: initial InitializeSecurityContextA failed: %s",
|
||||
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
free(connssl->ctxt);
|
||||
connssl->ctxt = NULL;
|
||||
@ -247,6 +263,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
SecBuffer inbuf[2];
|
||||
SecBufferDesc inbuf_desc;
|
||||
SECURITY_STATUS sspi_status = SEC_E_OK;
|
||||
LPTSTR host_name;
|
||||
|
||||
infof(data, "schannel: connecting to %s:%hu (step 2/3)\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
@ -319,12 +336,25 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
/* copy received handshake data into input buffer */
|
||||
memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer, connssl->encdata_offset);
|
||||
|
||||
#ifdef UNICODE
|
||||
host_name = Curl_convert_UTF8_to_wchar(conn->host.name);
|
||||
if(!host_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
host_name = conn->host.name;
|
||||
#endif
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
|
||||
|
||||
sspi_status = s_pSecFn->InitializeSecurityContext(
|
||||
&connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle,
|
||||
conn->host.name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
|
||||
host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
|
||||
&outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
|
||||
|
||||
#ifdef UNICODE
|
||||
free(host_name);
|
||||
#endif
|
||||
|
||||
/* free buffer for received handshake data */
|
||||
free(inbuf[0].pvBuffer);
|
||||
|
||||
@ -364,7 +394,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
failf(data, "schannel: SNI or certificate check failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
else
|
||||
failf(data, "schannel: next InitializeSecurityContextA failed: %s",
|
||||
failf(data, "schannel: next InitializeSecurityContext failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
@ -36,13 +36,24 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/* We use our own typedef here since some headers might lack these */
|
||||
typedef PSecurityFunctionTableA (APIENTRY *INITSECURITYINTERFACE_FN_A)(VOID);
|
||||
typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID);
|
||||
|
||||
/* See definition of SECURITY_ENTRYPOINT in sspi.h */
|
||||
#ifdef UNICODE
|
||||
# ifdef _WIN32_WCE
|
||||
# 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 s_hSecDll = NULL;
|
||||
|
||||
/* Pointer to SSPI dispatch table */
|
||||
PSecurityFunctionTableA s_pSecFn = NULL;
|
||||
PSecurityFunctionTable s_pSecFn = NULL;
|
||||
|
||||
/*
|
||||
* Curl_sspi_global_init()
|
||||
@ -58,7 +69,7 @@ PSecurityFunctionTableA s_pSecFn = NULL;
|
||||
CURLcode Curl_sspi_global_init(void)
|
||||
{
|
||||
OSVERSIONINFO osver;
|
||||
INITSECURITYINTERFACE_FN_A pInitSecurityInterface;
|
||||
INITSECURITYINTERFACE_FN pInitSecurityInterface;
|
||||
|
||||
/* If security interface is not yet initialized try to do this */
|
||||
if(!s_hSecDll) {
|
||||
@ -76,15 +87,15 @@ CURLcode Curl_sspi_global_init(void)
|
||||
/* 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");
|
||||
s_hSecDll = LoadLibrary(TEXT("security.dll"));
|
||||
else
|
||||
s_hSecDll = LoadLibrary("secur32.dll");
|
||||
s_hSecDll = LoadLibrary(TEXT("secur32.dll"));
|
||||
if(!s_hSecDll)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Get address of the InitSecurityInterfaceA function from the SSPI dll */
|
||||
pInitSecurityInterface = (INITSECURITYINTERFACE_FN_A)
|
||||
GetProcAddress(s_hSecDll, "InitSecurityInterfaceA");
|
||||
pInitSecurityInterface = (INITSECURITYINTERFACE_FN)
|
||||
GetProcAddress(s_hSecDll, SECURITYENTRYPOINT);
|
||||
if(!pInitSecurityInterface)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
|
@ -46,7 +46,7 @@ void Curl_sspi_global_cleanup(void);
|
||||
/* Forward-declaration of global variables defined in curl_sspi.c */
|
||||
|
||||
extern HMODULE s_hSecDll;
|
||||
extern PSecurityFunctionTableA s_pSecFn;
|
||||
extern PSecurityFunctionTable s_pSecFn;
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2012, 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
|
||||
@ -42,7 +42,7 @@ char *GetEnv(const char *variable)
|
||||
char *temp = getenv(variable);
|
||||
env[0] = '\0';
|
||||
if(temp != NULL)
|
||||
ExpandEnvironmentStrings(temp, env, sizeof(env));
|
||||
ExpandEnvironmentStringsA(temp, env, sizeof(env));
|
||||
return (env[0] != '\0')?strdup(env):NULL;
|
||||
#else
|
||||
char *env = getenv(variable);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "curl_base64.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_multibyte.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@ -90,7 +91,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
SecBuffer in_sec_buff;
|
||||
ULONG context_attributes;
|
||||
TimeStamp lifetime;
|
||||
|
||||
LPTSTR sname;
|
||||
int ret;
|
||||
size_t len = 0, input_token_len = 0;
|
||||
bool gss = FALSE;
|
||||
@ -137,7 +138,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
|
||||
if(!neg_ctx->output_token) {
|
||||
PSecPkgInfo SecurityPackage;
|
||||
ret = s_pSecFn->QuerySecurityPackageInfo((SEC_CHAR *)"Negotiate",
|
||||
ret = s_pSecFn->QuerySecurityPackageInfo(TEXT("Negotiate"),
|
||||
&SecurityPackage);
|
||||
if(ret != SEC_E_OK)
|
||||
return -1;
|
||||
@ -166,7 +167,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
return -1;
|
||||
|
||||
neg_ctx->status =
|
||||
s_pSecFn->AcquireCredentialsHandle(NULL, (SEC_CHAR *)"Negotiate",
|
||||
s_pSecFn->AcquireCredentialsHandle(NULL, TEXT("Negotiate"),
|
||||
SECPKG_CRED_OUTBOUND, NULL, NULL,
|
||||
NULL, NULL, neg_ctx->credentials,
|
||||
&lifetime);
|
||||
@ -205,10 +206,18 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
in_sec_buff.pvBuffer = input_token;
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
sname = Curl_convert_UTF8_to_wchar(neg_ctx->server_name);
|
||||
if(!wserver)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
sname = neg_ctx->server_name;
|
||||
#endif
|
||||
|
||||
neg_ctx->status = s_pSecFn->InitializeSecurityContext(
|
||||
neg_ctx->credentials,
|
||||
input_token ? neg_ctx->context : 0,
|
||||
neg_ctx->server_name,
|
||||
sname,
|
||||
ISC_REQ_CONFIDENTIALITY,
|
||||
0,
|
||||
SECURITY_NATIVE_DREP,
|
||||
@ -219,6 +228,10 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
&context_attributes,
|
||||
&lifetime);
|
||||
|
||||
#ifdef UNICODE
|
||||
free(sname);
|
||||
#endif
|
||||
|
||||
if(GSS_ERROR(neg_ctx->status))
|
||||
return -1;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2012, 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
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#ifdef USE_WIN32_IDN
|
||||
|
||||
#include <tchar.h>
|
||||
#include "curl_multibyte.h"
|
||||
|
||||
#ifdef WANT_IDN_PROTOTYPES
|
||||
WINBASEAPI int WINAPI IdnToAscii(DWORD, LPCWSTR, int, LPWSTR, int);
|
||||
@ -37,57 +37,9 @@ WINBASEAPI int WINAPI IdnToUnicode(DWORD, LPCWSTR, int, LPWSTR, int);
|
||||
|
||||
#define IDN_MAX_LENGTH 255
|
||||
|
||||
static wchar_t *_curl_win32_UTF8_to_wchar(const char *str_utf8)
|
||||
{
|
||||
wchar_t *str_w = NULL;
|
||||
|
||||
if(str_utf8) {
|
||||
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
||||
str_utf8, -1, NULL, 0);
|
||||
if(str_w_len) {
|
||||
str_w = malloc(str_w_len * sizeof(wchar_t));
|
||||
if(str_w) {
|
||||
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||
str_w_len) == 0) {
|
||||
free(str_w);
|
||||
str_w = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_w;
|
||||
}
|
||||
|
||||
static const char *_curl_win32_wchar_to_UTF8(const wchar_t *str_w)
|
||||
{
|
||||
char *str_utf8 = NULL;
|
||||
|
||||
if(str_w) {
|
||||
size_t str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
|
||||
0, NULL, NULL);
|
||||
if(str_utf8_len) {
|
||||
str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
|
||||
if(str_utf8) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||
NULL, FALSE) == 0) {
|
||||
(void) GetLastError();
|
||||
free((void *)str_utf8);
|
||||
str_utf8 = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
(void) GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
int curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
{
|
||||
wchar_t *in_w = _curl_win32_UTF8_to_wchar(in);
|
||||
wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
|
||||
if(in_w) {
|
||||
wchar_t punycode[IDN_MAX_LENGTH];
|
||||
if(IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH) == 0) {
|
||||
@ -97,7 +49,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
}
|
||||
free(in_w);
|
||||
|
||||
*out = (char *)_curl_win32_wchar_to_UTF8(punycode);
|
||||
*out = (char *)Curl_convert_wchar_to_UTF8(punycode);
|
||||
if(!(*out)) {
|
||||
return 0;
|
||||
}
|
||||
@ -115,7 +67,7 @@ int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8)
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
const char *out_utf8 = _curl_win32_wchar_to_UTF8(unicode);
|
||||
const char *out_utf8 = Curl_convert_wchar_to_UTF8(unicode);
|
||||
if(!out_utf8) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "timeval.h"
|
||||
#include "socks.h"
|
||||
#include "curl_sspi.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||
@ -139,17 +140,17 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
cred_handle.dwLower = 0;
|
||||
cred_handle.dwUpper = 0;
|
||||
|
||||
status = s_pSecFn->AcquireCredentialsHandleA(NULL,
|
||||
(char *)"Kerberos",
|
||||
SECPKG_CRED_OUTBOUND,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&cred_handle,
|
||||
&expiry);
|
||||
status = s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
TEXT("Kerberos"),
|
||||
SECPKG_CRED_OUTBOUND,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&cred_handle,
|
||||
&expiry);
|
||||
|
||||
if(check_sspi_err(conn, status, "AcquireCredentialsHandleA")) {
|
||||
if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) {
|
||||
failf(data, "Failed to acquire credentials.");
|
||||
Curl_safefree(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
@ -159,22 +160,33 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
/* As long as we need to keep sending some context info, and there's no */
|
||||
/* errors, keep sending it... */
|
||||
for(;;) {
|
||||
LPTSTR sname;
|
||||
#ifdef UNICODE
|
||||
sname = Curl_convert_UTF8_to_wchar(service_name);
|
||||
if(!sname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#else
|
||||
sname = service_name;
|
||||
#endif
|
||||
status = s_pSecFn->InitializeSecurityContext(&cred_handle,
|
||||
context_handle,
|
||||
sname,
|
||||
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);
|
||||
|
||||
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);
|
||||
#ifdef UNICODE
|
||||
Curl_safefree(sname);
|
||||
#endif
|
||||
|
||||
if(sspi_recv_token.pvBuffer) {
|
||||
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
|
||||
@ -182,7 +194,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
sspi_recv_token.cbBuffer = 0;
|
||||
}
|
||||
|
||||
if(check_sspi_err(conn, status, "InitializeSecurityContextA")) {
|
||||
if(check_sspi_err(conn, status, "InitializeSecurityContext")) {
|
||||
Curl_safefree(service_name);
|
||||
s_pSecFn->FreeCredentialsHandle(&cred_handle);
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
@ -365,10 +377,10 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
memcpy(socksreq+2, &us_length, sizeof(short));
|
||||
}
|
||||
else {
|
||||
status = s_pSecFn->QueryContextAttributesA(&sspi_context,
|
||||
SECPKG_ATTR_SIZES,
|
||||
&sspi_sizes);
|
||||
if(check_sspi_err(conn, status, "QueryContextAttributesA")) {
|
||||
status = s_pSecFn->QueryContextAttributes(&sspi_context,
|
||||
SECPKG_ATTR_SIZES,
|
||||
&sspi_sizes);
|
||||
if(check_sspi_err(conn, status, "QueryContextAttributes")) {
|
||||
s_pSecFn->DeleteSecurityContext(&sspi_context);
|
||||
failf(data, "Failed to query security context attributes.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
|
@ -635,7 +635,7 @@ const char *Curl_strerror(struct connectdata *conn, int err)
|
||||
strncpy(buf, strerror(err), max);
|
||||
else {
|
||||
if(!get_winsock_error(err, buf, max) &&
|
||||
!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
|
||||
!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
|
||||
LANG_NEUTRAL, buf, (DWORD)max, NULL))
|
||||
snprintf(buf, max, "Unknown error %d (%#x)", err, err);
|
||||
}
|
||||
@ -788,7 +788,8 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
char txtbuf[80];
|
||||
char msgbuf[sizeof(conn->syserr_buf)];
|
||||
char *str, *msg = NULL;
|
||||
char *p, *str, *msg = NULL;
|
||||
bool msg_formatted = FALSE;
|
||||
int old_errno;
|
||||
#endif
|
||||
const char *txt;
|
||||
@ -1057,11 +1058,29 @@ const char *Curl_sspi_strerror (struct connectdata *conn, int err)
|
||||
snprintf(txtbuf, sizeof(txtbuf), "%s (0x%04X%04X)",
|
||||
txt, (err >> 16) & 0xffff, err & 0xffff);
|
||||
txtbuf[sizeof(txtbuf)-1] = '\0';
|
||||
if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err, LANG_NEUTRAL,
|
||||
msgbuf, sizeof(msgbuf)-1, NULL)) {
|
||||
char *p;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
{
|
||||
wchar_t wbuf[256];
|
||||
wbuf[0] = L'\0';
|
||||
|
||||
if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err, LANG_NEUTRAL,
|
||||
wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
|
||||
wcstombs(msgbuf,wbuf,sizeof(msgbuf)-1);
|
||||
msg_formatted = TRUE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err, LANG_NEUTRAL,
|
||||
msgbuf, sizeof(msgbuf)-1, NULL)) {
|
||||
msg_formatted = TRUE;
|
||||
}
|
||||
#endif
|
||||
if(msg_formatted) {
|
||||
msgbuf[sizeof(msgbuf)-1] = '\0';
|
||||
/* strip trailing '\r\n' or '\n' */
|
||||
if((p = strrchr(msgbuf,'\n')) != NULL && (p - msgbuf) >= 2)
|
||||
|
@ -1341,7 +1341,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
|
||||
/* OK, so we have WinSock 2.0. We need to dynamically */
|
||||
/* load ws2_32.dll and get the function pointers we need. */
|
||||
wsock2 = LoadLibrary("WS2_32.DLL");
|
||||
wsock2 = LoadLibrary(TEXT("WS2_32.DLL"));
|
||||
if(wsock2 == NULL) {
|
||||
failf(data,"failed to load WS2_32.DLL (%d)", ERRNO);
|
||||
return CURLE_FAILED_INIT;
|
||||
|
Loading…
Reference in New Issue
Block a user