Move native sha1 implementation from auths to toplevel, only used for non-TLS builds
[exim.git] / src / src / expand.c
index 5189cdcfed5af230a5f80d60467f1271c1ec807c..40b697a5d2dc4ad0489d27e31482a7067c413baf 100644 (file)
@@ -2721,11 +2721,11 @@ switch(cond_type)
     else if (strncmpic(sub[1], US"{sha1}", 6) == 0)
       {
       int sublen = Ustrlen(sub[1]+6);
-      sha1 base;
+      hctx h;
       uschar digest[20];
 
-      sha1_start(&base);
-      sha1_end(&base, (uschar *)sub[0], Ustrlen(sub[0]), digest);
+      sha1_start(&h);
+      sha1_end(&h, (uschar *)sub[0], Ustrlen(sub[0]), digest);
 
       /* If the length that we are comparing against is 28, assume the SHA1
       digest is expressed as a base64 string. If the length is 40, assume a
@@ -3338,7 +3338,7 @@ chash_start(int type, void *base)
 if (type == HMAC_MD5)
   md5_start((md5 *)base);
 else
-  sha1_start((sha1 *)base);
+  sha1_start((hctx *)base);
 }
 
 static void
@@ -3347,7 +3347,7 @@ chash_mid(int type, void *base, uschar *string)
 if (type == HMAC_MD5)
   md5_mid((md5 *)base, string);
 else
-  sha1_mid((sha1 *)base, string);
+  sha1_mid((hctx *)base, string);
 }
 
 static void
@@ -3356,7 +3356,7 @@ chash_end(int type, void *base, uschar *string, int length, uschar *digest)
 if (type == HMAC_MD5)
   md5_end((md5 *)base, string, length, digest);
 else
-  sha1_end((sha1 *)base, string, length, digest);
+  sha1_end((hctx *)base, string, length, digest);
 }
 
 
@@ -3415,8 +3415,7 @@ prvs_hmac_sha1(uschar *address, uschar *key, uschar *key_num, uschar *daystamp)
 {
 uschar *hash_source, *p;
 int size = 0,offset = 0,i;
-sha1 sha1_base;
-void *use_base = &sha1_base;
+hctx h;
 uschar innerhash[20];
 uschar finalhash[20];
 uschar innerkey[64];
@@ -3445,13 +3444,13 @@ for (i = 0; i < Ustrlen(key); i++)
   outerkey[i] ^= key[i];
   }
 
-chash_start(HMAC_SHA1, use_base);
-chash_mid(HMAC_SHA1, use_base, innerkey);
-chash_end(HMAC_SHA1, use_base, hash_source, offset, innerhash);
+chash_start(HMAC_SHA1, &h);
+chash_mid(HMAC_SHA1, &h, innerkey);
+chash_end(HMAC_SHA1, &h, hash_source, offset, innerhash);
 
-chash_start(HMAC_SHA1, use_base);
-chash_mid(HMAC_SHA1, use_base, outerkey);
-chash_end(HMAC_SHA1, use_base, innerhash, 20, finalhash);
+chash_start(HMAC_SHA1, &h);
+chash_mid(HMAC_SHA1, &h, outerkey);
+chash_end(HMAC_SHA1, &h, innerhash, 20, finalhash);
 
 p = finalhash_hex;
 for (i = 0; i < 3; i++)
@@ -3851,8 +3850,8 @@ expand_string_internal(const uschar *string, BOOL ket_ends, const uschar **left,
 {
 int ptr = 0;
 int size = Ustrlen(string)+ 64;
-int item_type;
 uschar *yield = store_get(size);
+int item_type;
 const uschar *s = string;
 uschar *save_expand_nstring[EXPAND_MAXN+1];
 int save_expand_nlength[EXPAND_MAXN+1];
@@ -5144,7 +5143,7 @@ while (*s != 0)
       {
       uschar *sub[3];
       md5 md5_base;
-      sha1 sha1_base;
+      hctx sha1_ctx;
       void *use_base;
       int type, i;
       int hashlen;      /* Number of octets for the hash algorithm's output */
@@ -5176,7 +5175,7 @@ while (*s != 0)
       else if (Ustrcmp(sub[0], "sha1") == 0)
         {
         type = HMAC_SHA1;
-        use_base = &sha1_base;
+        use_base = &sha1_ctx;
         hashlen = 20;
         hashblocklen = 64;
         }
@@ -5359,7 +5358,7 @@ while (*s != 0)
     case EITEM_EXTRACT:
       {
       int i;
-      int j = 2;
+      int j;
       int field_number = 1;
       BOOL field_number_set = FALSE;
       uschar *save_lookup_value = lookup_value;
@@ -5369,12 +5368,12 @@ while (*s != 0)
 
       /* While skipping we cannot rely on the data for expansions being
       available (eg. $item) hence cannot decide on numeric vs. keyed.
-      Just read as many arguments as there are. */
+      Read a maximum of 5 arguments (inclding the yes/no) */
 
       if (skipping)
        {
         while (isspace(*s)) s++;
-        while (*s == '{')
+        for (j = 5; j > 0 && *s == '{'; j--)
          {
           if (!expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok))
            goto EXPAND_FAILED;                                 /*{*/
@@ -5385,6 +5384,13 @@ while (*s != 0)
            }
          while (isspace(*s)) s++;
          }
+       if (  Ustrncmp(s, "fail", 4) == 0
+          && (s[4] == '}' || s[4] == ' ' || s[4] == '\t' || !s[4])
+          )
+         {
+         s += 4;
+         while (isspace(*s)) s++;
+         }
        if (*s != '}')
          {
          expand_string_message = US"missing '}' closing extract";
@@ -5392,7 +5398,7 @@ while (*s != 0)
          }
        }
 
-      else for (i = 0; i < j; i++) /* Read the proper number of arguments */
+      else for (i = 0, j = 2; i < j; i++) /* Read the proper number of arguments */
         {
         while (isspace(*s)) s++;
         if (*s == '{')                                                 /*}*/
@@ -5402,7 +5408,7 @@ while (*s != 0)
           if (*s++ != '}')
            {
            expand_string_message = string_sprintf(
-             US"missing '}' closing arg %d of extract", i+1);
+             "missing '}' closing arg %d of extract", i+1);
            goto EXPAND_FAILED_CURLY;
            }
 
@@ -5448,7 +5454,7 @@ while (*s != 0)
         else
          {
          expand_string_message = string_sprintf(
-           US"missing '{' for arg %d of extract", i+1);
+           "missing '{' for arg %d of extract", i+1);
          goto EXPAND_FAILED_CURLY;
          }
         }
@@ -5505,7 +5511,7 @@ while (*s != 0)
         if (*s != '{')                                 /*}*/
          {
          expand_string_message = string_sprintf(
-           US"missing '{' for arg %d of listextract", i+1);
+           "missing '{' for arg %d of listextract", i+1);
          goto EXPAND_FAILED_CURLY;
          }
 
@@ -5514,7 +5520,7 @@ while (*s != 0)
        if (*s++ != '}')
          {
          expand_string_message = string_sprintf(
-           US"missing '}' closing arg %d of listextract", i+1);
+           "missing '}' closing arg %d of listextract", i+1);
          goto EXPAND_FAILED_CURLY;
          }
 
@@ -6351,12 +6357,12 @@ while (*s != 0)
        else
 #endif
          {
-         sha1 base;
+         hctx h;
          uschar digest[20];
          int j;
          char st[41];
-         sha1_start(&base);
-         sha1_end(&base, sub, Ustrlen(sub), digest);
+         sha1_start(&h);
+         sha1_end(&h, sub, Ustrlen(sub), digest);
          for(j = 0; j < 20; j++) sprintf(st+2*j, "%02X", digest[j]);
          yield = string_cat(yield, &size, &ptr, US st);
          }
@@ -7624,6 +7630,29 @@ return OK;
 
 
 
+/* Avoid potentially exposing a password in a string about to be logged */
+
+uschar *
+expand_hide_passwords(uschar * s)
+{
+return (  (  Ustrstr(s, "failed to expand") != NULL
+         || Ustrstr(s, "expansion of ")    != NULL
+         ) 
+       && (  Ustrstr(s, "mysql")   != NULL
+         || Ustrstr(s, "pgsql")   != NULL
+         || Ustrstr(s, "redis")   != NULL
+         || Ustrstr(s, "sqlite")  != NULL
+         || Ustrstr(s, "ldap:")   != NULL
+         || Ustrstr(s, "ldaps:")  != NULL
+         || Ustrstr(s, "ldapi:")  != NULL
+         || Ustrstr(s, "ldapdn:") != NULL
+         || Ustrstr(s, "ldapm:")  != NULL
+       )  ) 
+  ? US"Temporary internal error" : s;
+}
+
+
+
 
 /*************************************************
 **************************************************