]> granicus.if.org Git - curl/commitdiff
unicode NTLM SSPI: heap corruption fixed
authorChristian Hägele <haegele@teamviewer.com>
Mon, 2 Jul 2012 20:59:54 +0000 (22:59 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 2 Jul 2012 20:59:54 +0000 (22:59 +0200)
When compiling libcurl with UNICODE defined and using unicode characters
in username.

lib/curl_ntlm_msgs.c

index c17880bb410f905b417a70fa6f6979e74cde1326..0fcfec69e49331d5ffe143d12df034c2a88e612a 100644 (file)
@@ -351,67 +351,88 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
   SecBufferDesc desc;
   SECURITY_STATUS status;
   unsigned long attrs;
-  const char *user;
-  const char *domain = "";
-  size_t userlen = 0;
+  const TCHAR *useranddomain;
+  const TCHAR *user;
+  const TCHAR *passwd;
+  const TCHAR *domain = TEXT("");
   size_t domlen = 0;
-  size_t passwdlen = 0;
   TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
 
   Curl_ntlm_sspi_cleanup(ntlm);
 
-  user = strchr(userp, '\\');
-  if(!user)
-    user = strchr(userp, '/');
-
-  if(user) {
-    domain = userp;
-    domlen = user - userp;
-    user++;
-  }
-  else {
-    user = userp;
-    domain = "";
-    domlen = 0;
-  }
-
-  if(user)
-    userlen = strlen(user);
+  if(userp && *userp) {
+#ifdef UNICODE
+    useranddomain = Curl_convert_UTF8_to_wchar(userp);
+    if(useranddomain == NULL)
+      return CURLE_OUT_OF_MEMORY;
+#else
+    useranddomain = userp;
+#endif
 
-  if(passwdp)
-    passwdlen = strlen(passwdp);
+    user = _tcschr(useranddomain, TEXT('\\'));
+    if(!user)
+      user = _tcschr(useranddomain, TEXT('/'));
+
+    if(user) {
+      domain = useranddomain;
+      domlen = user - useranddomain;
+      user++;
+    }
+    else {
+      user = useranddomain;
+      domain = TEXT("");
+      domlen = 0;
+    }
 
-  if(userlen > 0) {
     /* note: initialize all of this before doing the mallocs so that
      * it can be cleaned up later without leaking memory.
      */
     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)
+    if((ntlm->identity.User = (unsigned short *)_wcsdup(user)) == NULL) {
+      free((void *)useranddomain);
       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)_tcslen(user);
+
+    ntlm->identity.Domain = malloc(sizeof(TCHAR) * (domlen + 1));
+    if(ntlm->identity.Domain == NULL) {
+#ifdef UNICODE
+      free((void *)useranddomain);
+#endif
+      return CURLE_OUT_OF_MEMORY;
+    }
+    _tcsncpy((TCHAR *)ntlm->identity.Domain, domain, domlen);
+    ntlm->identity.Domain[domlen] = TEXT('\0');
+    ntlm->identity.DomainLength = (unsigned long)domlen;
+
+#ifdef UNICODE
+    free((void *)useranddomain);
+#endif
 
-    ntlm->identity.UserLength = (unsigned long)userlen;
 #ifdef UNICODE
-    if((ntlm->identity.Password = Curl_convert_UTF8_to_wchar(passwdp)) == NULL)
+    ntlm->identity.Password = (unsigned short *)
+      Curl_convert_UTF8_to_wchar(passwdp);
+    if(ntlm->identity.Password == 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)_tcslen((TCHAR *)ntlm->identity.Password);
 
-    ntlm->identity.PasswordLength = (unsigned long)passwdlen;
-    if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL)
-      return CURLE_OUT_OF_MEMORY;
-
-    strncpy((char *)ntlm->identity.Domain, domain, domlen);
-    ntlm->identity.Domain[domlen] = '\0';
-    ntlm->identity.DomainLength = (unsigned long)domlen;
+#ifdef UNICODE
+    ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+#else
     ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
+#endif
   }
   else
     ntlm->p_identity = NULL;