aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/curl_multibyte.c82
-rw-r--r--lib/curl_multibyte.h40
-rw-r--r--lib/curl_ntlm_msgs.c61
-rw-r--r--lib/curl_sasl.c1
-rw-r--r--lib/curl_schannel.c40
-rw-r--r--lib/curl_sspi.c25
-rw-r--r--lib/curl_sspi.h2
-rw-r--r--lib/getenv.c4
-rw-r--r--lib/http_negotiate_sspi.c21
-rw-r--r--lib/idn_win32.c58
-rw-r--r--lib/socks_sspi.c76
-rw-r--r--lib/strerror.c33
-rw-r--r--lib/telnet.c2
13 files changed, 307 insertions, 138 deletions
diff --git a/lib/curl_multibyte.c b/lib/curl_multibyte.c
new file mode 100644
index 000000000..b48c32348
--- /dev/null
+++ b/lib/curl_multibyte.c
@@ -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)) */
diff --git a/lib/curl_multibyte.h b/lib/curl_multibyte.h
new file mode 100644
index 000000000..015b9d418
--- /dev/null
+++ b/lib/curl_multibyte.h
@@ -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 */
diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c
index 5789a24c7..0fd34cb80 100644
--- a/lib/curl_ntlm_msgs.c
+++ b/lib/curl_ntlm_msgs.c
@@ -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;
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index c5793f956..ccb54a89f 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -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>
diff --git a/lib/curl_schannel.c b/lib/curl_schannel.c
index a2a5f381f..040133824 100644
--- a/lib/curl_schannel.c
+++ b/lib/curl_schannel.c
@@ -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;
}
diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c
index cb83809b3..c3c41ec2f 100644
--- a/lib/curl_sspi.c
+++ b/lib/curl_sspi.c
@@ -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;
diff --git a/lib/curl_sspi.h b/lib/curl_sspi.h
index 4e7d4cfe6..c3e6d9760 100644
--- a/lib/curl_sspi.h
+++ b/lib/curl_sspi.h
@@ -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 */
diff --git a/lib/getenv.c b/lib/getenv.c
index 6b40dd68d..a2d69830e 100644
--- a/lib/getenv.c
+++ b/lib/getenv.c
@@ -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);
diff --git a/lib/http_negotiate_sspi.c b/lib/http_negotiate_sspi.c
index f1ab33d6d..ac197f6cf 100644
--- a/lib/http_negotiate_sspi.c
+++ b/lib/http_negotiate_sspi.c
@@ -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;
diff --git a/lib/idn_win32.c b/lib/idn_win32.c
index 70286c0fd..6351f791d 100644
--- a/lib/idn_win32.c
+++ b/lib/idn_win32.c
@@ -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;
}
diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c
index 61ef2f4a7..8bbaef101 100644
--- a/lib/socks_sspi.c
+++ b/lib/socks_sspi.c
@@ -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);
-
- if(check_sspi_err(conn, status, "AcquireCredentialsHandleA")) {
+ status = s_pSecFn->AcquireCredentialsHandle(NULL,
+ TEXT("Kerberos"),
+ SECPKG_CRED_OUTBOUND,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &cred_handle,
+ &expiry);
+
+ 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(;;) {
-
- 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);
+ 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);
+
+#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;
diff --git a/lib/strerror.c b/lib/strerror.c
index 84a900047..dd7d37565 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -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)
diff --git a/lib/telnet.c b/lib/telnet.c
index 26fa3ac67..1c294e2ab 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -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;