Fix client-only use of gsasl authenticator. Bug 2818
[exim.git] / src / src / base64.c
index 61b600f6cec332e5ca5961dc92f7a591c257314b..29f9c77b0d59746cc17c8963df92ddad4d841cf9 100644 (file)
@@ -5,7 +5,8 @@
 /* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004, 2015 */
 /* License: GPL */
 
 /* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004, 2015 */
 /* License: GPL */
 
-/* Copyright (c) University of Cambridge 1995 - 2015 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -38,7 +39,7 @@ ssize_t
 mime_decode_base64(FILE * in, FILE * out, uschar * boundary)
 {
 uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH];
 mime_decode_base64(FILE * in, FILE * out, uschar * boundary)
 {
 uschar ibuf[MIME_MAX_LINE_LENGTH], obuf[MIME_MAX_LINE_LENGTH];
-uschar *ipos, *opos;
+uschar *opos;
 ssize_t len, size = 0;
 int bytestate = 0;
 
 ssize_t len, size = 0;
 int bytestate = 0;
 
@@ -52,7 +53,7 @@ while (Ufgets(ibuf, MIME_MAX_LINE_LENGTH, in) != NULL)
      )
     break;
 
      )
     break;
 
-  for (ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos != 0; ++ipos)
+  for (uschar * ipos = ibuf ; *ipos != '\r' && *ipos != '\n' && *ipos; ++ipos)
     if (*ipos == '=')                  /* skip padding */
       ++bytestate;
 
     if (*ipos == '=')                  /* skip padding */
       ++bytestate;
 
@@ -100,21 +101,21 @@ return size;
 #endif /*WITH_CONTENT_SCAN*/
 
 /*************************************************
 #endif /*WITH_CONTENT_SCAN*/
 
 /*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************
+ *************************************************/
 
 
 /*************************************************
 
 
 /*************************************************
@@ -129,7 +130,7 @@ compact loop is messy and would probably run more slowly.
 Arguments:
   code        points to the coded string, zero-terminated
   ptr         where to put the pointer to the result, which is in
 Arguments:
   code        points to the coded string, zero-terminated
   ptr         where to put the pointer to the result, which is in
-              dynamic store, and zero-terminated
+              allocated store, and zero-terminated
 
 Returns:      the number of bytes in the result,
               or -1 if the input was malformed
 
 Returns:      the number of bytes in the result,
               or -1 if the input was malformed
@@ -150,12 +151,16 @@ static uschar dec64table[] = {
 };
 
 int
 };
 
 int
-b64decode(uschar *code, uschar **ptr)
+b64decode(const uschar *code, uschar **ptr)
 {
 {
+
 int x, y;
 int x, y;
-uschar *result = store_get(3*(Ustrlen(code)/4) + 1);
+uschar *result;
 
 
-*ptr = result;
+{
+  int l = Ustrlen(code);
+  *ptr = result = store_get(1 + l/4 * 3 + l%4, is_tainted(code));
+}
 
 /* Each cycle of the loop handles a quantum of 4 input bytes. For the last
 quantum this may decode to 1, 2, or 3 output bytes. */
 
 /* Each cycle of the loop handles a quantum of 4 input bytes. For the last
 quantum this may decode to 1, 2, or 3 output bytes. */
@@ -163,35 +168,50 @@ quantum this may decode to 1, 2, or 3 output bytes. */
 while ((x = *code++) != 0)
   {
   if (isspace(x)) continue;
 while ((x = *code++) != 0)
   {
   if (isspace(x)) continue;
+  /* debug_printf("b64d: '%c'\n", x); */
 
   if (x > 127 || (x = dec64table[x]) == 255) return -1;
 
   while (isspace(y = *code++)) ;
 
   if (x > 127 || (x = dec64table[x]) == 255) return -1;
 
   while (isspace(y = *code++)) ;
-  if (y == 0 || (y = dec64table[y]) == 255)
+  /* debug_printf("b64d: '%c'\n", y); */
+  if (y > 127 || (y = dec64table[y]) == 255)
     return -1;
 
   *result++ = (x << 2) | (y >> 4);
     return -1;
 
   *result++ = (x << 2) | (y >> 4);
+  /* debug_printf("b64d:      -> %02x\n", result[-1]); */
 
   while (isspace(x = *code++)) ;
 
   while (isspace(x = *code++)) ;
-  if (x == '=')
+  /* debug_printf("b64d: '%c'\n", x); */
+  if (x == '=')                /* endmarker, but there should be another */
     {
     while (isspace(x = *code++)) ;
     {
     while (isspace(x = *code++)) ;
-    if (x != '=' || *code != 0) return -1;
+    /* debug_printf("b64d: '%c'\n", x); */
+    if (x != '=') return -1;
+    while (isspace(y = *code++)) ;
+    if (y != 0) return -1;
+    /* debug_printf("b64d: DONE\n"); */
+    break;
     }
   else
     {
     if (x > 127 || (x = dec64table[x]) == 255) return -1;
     *result++ = (y << 4) | (x >> 2);
     }
   else
     {
     if (x > 127 || (x = dec64table[x]) == 255) return -1;
     *result++ = (y << 4) | (x >> 2);
+    /* debug_printf("b64d:      -> %02x\n", result[-1]); */
 
     while (isspace(y = *code++)) ;
 
     while (isspace(y = *code++)) ;
+    /* debug_printf("b64d: '%c'\n", y); */
     if (y == '=')
       {
     if (y == '=')
       {
-      if (*code != 0) return -1;
+      while (isspace(y = *code++)) ;
+      if (y != 0) return -1;
+      /* debug_printf("b64d: DONE\n"); */
+      break;
       }
     else
       {
       if (y > 127 || (y = dec64table[y]) == 255) return -1;
       *result++ = (x << 6) | y;
       }
     else
       {
       if (y > 127 || (y = dec64table[y]) == 255) return -1;
       *result++ = (x << 6) | y;
+      /* debug_printf("b64d:      -> %02x\n", result[-1]); */
       }
     }
   }
       }
     }
   }
@@ -201,23 +221,6 @@ return result - *ptr;
 }
 
 
 }
 
 
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-/*************************************************
-
 /*************************************************
 *          Encode byte-string in base 64         *
 *************************************************/
 /*************************************************
 *          Encode byte-string in base 64         *
 *************************************************/
@@ -240,14 +243,14 @@ static uschar *enc64table =
   US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 uschar *
   US"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 uschar *
-b64encode(uschar *clear, int len)
+b64encode_taint(const uschar * clear, int len, BOOL tainted)
 {
 {
-uschar *code = store_get(4*((len+2)/3) + 1);
+uschar *code = store_get(4*((len+2)/3) + 1, tainted);
 uschar *p = code;
 
 while (len-- >0)
   {
 uschar *p = code;
 
 while (len-- >0)
   {
-  register int x, y;
+  int x, y;
 
   x = *clear++;
   *p++ = enc64table[(x >> 2) & 63];
 
   x = *clear++;
   *p++ = enc64table[(x >> 2) & 63];
@@ -281,6 +284,12 @@ while (len-- >0)
 return code;
 }
 
 return code;
 }
 
+uschar *
+b64encode(const uschar * clear, int len)
+{
+return b64encode_taint(clear, len, is_tainted(clear));
+}
+
 
 /* End of base64.c */
 /* vi: sw ai sw=2
 
 /* End of base64.c */
 /* vi: sw ai sw=2