]> granicus.if.org Git - curl/commitdiff
SSPI related code: Unicode support for WinCE
authorMark Salisbury <mark.salisbury@hp.com>
Fri, 15 Jun 2012 16:05:11 +0000 (18:05 +0200)
committerYang Tse <yangsita@gmail.com>
Fri, 15 Jun 2012 16:41:49 +0000 (18:41 +0200)
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

13 files changed:
lib/curl_multibyte.c [new file with mode: 0644]
lib/curl_multibyte.h [new file with mode: 0644]
lib/curl_ntlm_msgs.c
lib/curl_sasl.c
lib/curl_schannel.c
lib/curl_sspi.c
lib/curl_sspi.h
lib/getenv.c
lib/http_negotiate_sspi.c
lib/idn_win32.c
lib/socks_sspi.c
lib/strerror.c
lib/telnet.c

diff --git a/lib/curl_multibyte.c b/lib/curl_multibyte.c
new file mode 100644 (file)
index 0000000..b48c323
--- /dev/null
@@ -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 (file)
index 0000000..015b9d4
--- /dev/null
@@ -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 */
index 5789a24c73e3920d1f70cc48896407e1da2d601e..0fd34cb802a868e6821374f6c875d5f60c3d070c 100644 (file)
@@ -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;
 
index c5793f956a521864f1f4c5fb02e6e9eacde0670c..ccb54a89f50ee33f88ee32253329b625c5cff9b9 100644 (file)
@@ -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>
index a2a5f381fc5f26d09aba0b1dd7a787da880fa560..0401338244297c8253564aab4e2b117c781add11 100644 (file)
 #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;
   }
index cb83809b37ddec44fbbc1097e4867534fc7ef5f7..c3c41ec2f7dd6409178ea884155f36bb25915374 100644 (file)
 #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;
 
index 4e7d4cfe60e9617a1c823072cf8ad159a5a2abda..c3e6d9760ccdac03852dbd978a5c3d7a8245df90 100644 (file)
@@ -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 */
 
index 6b40dd68dd0df08796a228503767b41369b6e0b6..a2d69830e19b247053d928d9a68c3690d3caab8d 100644 (file)
@@ -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);
index f1ab33d6d438fef1e603bcc4a1067f0dfb5194f3..ac197f6cf7e18c4626bfec35e90b64523312766e 100644 (file)
@@ -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;
 
index 70286c0fd489d8c2cf6d97f2471b134397cb86d4..6351f791ddea9bed21db102c5c4a1980e98a39d0 100644 (file)
@@ -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;
       }
index 61ef2f4a73a8bd91b60d6352ac8484f5a7f762f3..8bbaef101df1141ae23e1c3ac289a854fdbe6c00 100644 (file)
@@ -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;
index 84a900047fc06b4fe0a1bc7d9038f4e775e2e434..dd7d37565a56cec0a6da7bcb7841307ff4161238 100644 (file)
@@ -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)
index 26fa3ac67e0645f26dc01407b8718121306afce2..1c294e2ab7c1fe7cc9487e79b2e40e3043b25e10 100644 (file)
@@ -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;