Sophie

Sophie

distrib > Mageia > 9 > x86_64 > by-pkgid > fcde572b33713a16d1c874ad6d7225d3 > files > 1

libesmtp-1.0.6-14.mga9.src.rpm

From 4c0657de592139bd37a0c3fb0d07757f1a8bc73c Mon Sep 17 00:00:00 2001
From: Brian Stafford <contact@brianstafford.info>
Date: Mon, 24 Aug 2020 14:09:15 +0100
Subject: [PATCH] Fix potential stack corruption. CVE-2019-19977

* a sufficiently long domain, workstation or user name will overwrite
the stack.
* nt_unicode() called with incorrect argument possibly reads
uninitialised memory.
See issue #6.

Change lm_uccpy() to return number of bytes copied and to acccept NULL
source as a zero length string. 2nd argument to lm_uccpy() is now length
of buffer. nt_unicode() now returns NULL if passed zero length string.

Update DES API for current OpenSSL.
---
 ntlm/ntlm.h       |  2 +-
 ntlm/ntlmdes.c    | 25 ++++++++-------
 ntlm/ntlmstruct.c | 79 ++++++++++++++---------------------------------
 3 files changed, 38 insertions(+), 68 deletions(-)

diff --git a/ntlm/ntlm.h b/ntlm/ntlm.h
index 50a49d6..f0a8a94 100644
--- a/ntlm/ntlm.h
+++ b/ntlm/ntlm.h
@@ -24,7 +24,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-char *lm_uccpy (char *dst, size_t dstlen, const char *src);
+int lm_uccpy (char *dst, size_t dstlen, const char *src);
 unsigned char *nt_unicode (const char *string, size_t len);
 
 void lm_hash_password (unsigned char *hash, const char *pass);
diff --git a/ntlm/ntlmdes.c b/ntlm/ntlmdes.c
index 57a39d1..083f7f4 100644
--- a/ntlm/ntlmdes.c
+++ b/ntlm/ntlmdes.c
@@ -30,10 +30,10 @@
 #include "ntlm.h"
 
 static void
-lm_deshash (void *result, const_des_cblock *iv, const void *secret)
+lm_deshash (void *result, const_DES_cblock *iv, const void *secret)
 {
-  des_cblock key;
-  des_key_schedule ks;
+  DES_cblock key;
+  DES_key_schedule ks;
   unsigned char key_56[8];
   size_t len;
 
@@ -55,9 +55,9 @@ lm_deshash (void *result, const_des_cblock *iv, const void *secret)
   key[6] = (key_56[5] << 2) | (key_56[6] >> 6);
   key[7] = (key_56[6] << 1);
 
-  des_set_odd_parity (&key);
-  des_set_key (&key, ks);
-  des_ecb_encrypt (iv, result, ks, DES_ENCRYPT);
+  DES_set_odd_parity (&key);
+  DES_set_key (&key, &ks);
+  DES_ecb_encrypt (iv, result, &ks, DES_ENCRYPT);
 
   /* paranoia */
   memset (key, 0, sizeof key);
@@ -66,26 +66,26 @@ lm_deshash (void *result, const_des_cblock *iv, const void *secret)
 
 /* Copy and convert to upper case.  If supplied string is shorter than the
    destination, zero pad the remainder. */
-char *
+int
 lm_uccpy (char *dst, size_t dstlen, const char *src)
 {
   char *p;
   size_t len;
 
-  if ((len = strlen (src)) > dstlen)
+  if ((len = src != NULL ? strlen (src) : 0) > dstlen)
     len = dstlen;
   for (p = dst; len > 0; p++, src++, len--)
     *p = toupper (*src);
   if (p < dst + dstlen)
     memset (p, 0, dst + dstlen - p);
-  return dst;
+  return len;
 }
 
 /* create LanManager hashed password */
 void
 lm_hash_password (unsigned char *hash, const char *pass)
 {
-  static const_des_cblock iv = { 0x4B, 0x47, 0x53, 0x21,
+  static const_DES_cblock iv = { 0x4B, 0x47, 0x53, 0x21,
                                  0x40, 0x23, 0x24, 0x25 };
   char lmpass[14];
 
@@ -101,6 +101,9 @@ nt_unicode (const char *string, size_t len)
 {
   unsigned char *uni, *pp;
 
+  if (len == 0)
+    return NULL;
+
   uni = malloc (len * 2);
   if ((pp = uni) != NULL)
     while (len-- > 0)
@@ -137,7 +140,7 @@ ntlm_responses (unsigned char *lm_resp, unsigned char *nt_resp,
 		const unsigned char *challenge, const char *secret)
 {
   unsigned char hash[21];
-  des_cblock nonce;
+  DES_cblock nonce;
 
   memcpy (&nonce, challenge, sizeof nonce);
 
diff --git a/ntlm/ntlmstruct.c b/ntlm/ntlmstruct.c
index dfb80de..a42c9cf 100644
--- a/ntlm/ntlmstruct.c
+++ b/ntlm/ntlmstruct.c
@@ -187,7 +187,6 @@ ntlm_build_type_1 (char *buf, size_t buflen, unsigned int flags,
 {
   size_t offset = T1SIZE;
   size_t len;
-  unsigned char *up;
   char string[256];
 
   if (buflen < offset)
@@ -195,25 +194,13 @@ ntlm_build_type_1 (char *buf, size_t buflen, unsigned int flags,
   memcpy (buf, NTLMSSP, 8);
   write_uint32 (buf, MSGTYPE, 1);
   write_uint32 (buf, T1FLAGS, flags);
-  up = NULL;
-  len = 0;
-  if (domain != NULL)
-    {
-      len = strlen (domain);
-      if (offset + len > buflen)
-	return 0;
-      lm_uccpy (string, len, domain);
-    }
+  len = lm_uccpy (string, sizeof string, domain);
+  if (offset + len > buflen)
+    return 0;
   write_string (buf, T1DOMAIN, &offset, string, len);
-  up = NULL;
-  len = 0;
-  if (workstation != NULL)
-    {
-      len = strlen (workstation);
-      if (offset + len > buflen)
-	return 0;
-      lm_uccpy (string, len, workstation);
-    }
+  len = lm_uccpy (string, sizeof string, workstation);
+  if (offset + len > buflen)
+    return 0;
   write_string (buf, T1WKSTN, &offset, string, len);
   return offset;
 }
@@ -232,16 +219,11 @@ ntlm_build_type_2 (char *buf, size_t buflen, unsigned int flags,
     return 0;
   memcpy (buf, NTLMSSP, 8);
   write_uint32 (buf, MSGTYPE, 2);
-  up = NULL;
-  len = 0;
-  if (domain != NULL)
-    {
-      len = strlen (domain);
-      if (offset + 2 * len > buflen)
-	return 0;
-      up = nt_unicode (lm_uccpy (string, len, domain), 2 * len);
-    }
-  write_string (buf, T2AUTHTARGET, &offset, up, len);
+  len = lm_uccpy (string, sizeof string, domain);
+  if (offset + 2 * len > buflen)
+    return 0;
+  up = nt_unicode (string, len);
+  write_string (buf, T2AUTHTARGET, &offset, up, 2 * len);
   if (up != NULL)
     free (up);
   write_uint32 (buf, T2FLAGS, flags);
@@ -267,39 +249,24 @@ ntlm_build_type_3 (char *buf, size_t buflen, unsigned int flags,
   write_uint32 (buf, MSGTYPE, 3);
   write_string (buf, T3LMRESPONSE, &offset, lm_resp, 24);
   write_string (buf, T3NTRESPONSE, &offset, nt_resp, 24);
-  up = NULL;
-  len = 0;
-  if (domain != NULL)
-    {
-      len = strlen (domain);
-      if (offset + 2 * len > buflen)
-	return 0;
-      up = nt_unicode (lm_uccpy (string, len, domain), 2 * len);
-    }
+  len = lm_uccpy (string, sizeof string, domain);
+  if (offset + 2 * len > buflen)
+    return 0;
+  up = nt_unicode (string, len);
   write_string (buf, T3DOMAIN, &offset, up, 2 * len);
   if (up != NULL)
     free (up);
-  up = NULL;
-  len = 0;
-  if (user != NULL)
-    {
-      len = strlen (user);
-      if (offset + 2 * len > buflen)
-	return 0;
-      up = nt_unicode (lm_uccpy (string, len, user), 2 * len);
-    }
+  len = lm_uccpy (string, sizeof string, user);
+  if (offset + 2 * len > buflen)
+    return 0;
+  up = nt_unicode (string, len);
   write_string (buf, T3USER, &offset, up, 2 * len);
   if (up != NULL)
     free (up);
-  up = NULL;
-  len = 0;
-  if (workstation != NULL)
-    {
-      len = strlen (workstation);
-      if (offset + 2 * len > buflen)
-	return 0;
-      up = nt_unicode (lm_uccpy (string, len, workstation), 2 * len);
-    }
+  len = lm_uccpy (string, sizeof string, workstation);
+  if (offset + 2 * len > buflen)
+    return 0;
+  up = nt_unicode (string, len);
   write_string (buf, T3WKSTN, &offset, up, 2 * len);
   if (up != NULL)
     free (up);