Fix tainted message for fakereject
[exim.git] / src / src / acl.c
index 2f20821c2ae4dabb086a597a126787ec2d86c3dd..89947f405836db9d3490658ec5799d7203f5d86b 100644 (file)
@@ -486,7 +486,7 @@ static control_def controls_list[] = {
   { US"no_delay_flush",          FALSE,
          ACL_BIT_NOTSMTP | ACL_BIT_NOTSMTP_START
   },
-  
+
 [CONTROL_NO_ENFORCE_SYNC] =
   { US"no_enforce_sync",         FALSE,
          ACL_BIT_NOTSMTP | ACL_BIT_NOTSMTP_START
@@ -744,7 +744,7 @@ while ((s = (*func)()))
   int v, c;
   BOOL negated = FALSE;
   uschar *saveline = s;
-  uschar name[64];
+  uschar name[EXIM_DRIVERNAME_MAX];
 
   /* Conditions (but not verbs) are allowed to be negated by an initial
   exclamation mark. */
@@ -3235,13 +3235,15 @@ for (; cb; cb = cb->next)
 
        case CONTROL_FAKEREJECT:
          cancel_cutthrough_connection(TRUE, US"fakereject");
-         case CONTROL_FAKEDEFER:
+       case CONTROL_FAKEDEFER:
          fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
          if (*p == '/')
            {
            const uschar *pp = p + 1;
            while (*pp) pp++;
-           fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
+           /* The entire control= line was expanded at top so no need to expand
+           the part after the / */
+           fake_response_text = string_copyn(p+1, pp-p-1);
            p = pp;
            }
           else /* Explicitly reset to default string */
@@ -3702,20 +3704,22 @@ for (; cb; cb = cb->next)
     #endif
 
     case ACLC_QUEUE:
-    if (is_tainted(arg))
       {
-      *log_msgptr = string_sprintf("Tainted name '%s' for queue not permitted",
-                                   arg);
-      return ERROR;
-      }
-    if (Ustrchr(arg, '/'))
-      {
-      *log_msgptr = string_sprintf(
-             "Directory separator not permitted in queue name: '%s'", arg);
-      return ERROR;
+      uschar *m;
+      if ((m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg)))
+        {
+        *log_msgptr = m;
+        return ERROR;
+        }
+      if (Ustrchr(arg, '/'))
+        {
+        *log_msgptr = string_sprintf(
+                "Directory separator not permitted in queue name: '%s'", arg);
+        return ERROR;
+        }
+      queue_name = string_copy_perm(arg, FALSE);
+      break;
       }
-    queue_name = string_copy_perm(arg, FALSE);
-    break;
 
     case ACLC_RATELIMIT:
     rc = acl_ratelimit(arg, where, log_msgptr);
@@ -4088,6 +4092,15 @@ while (isspace(*ss)) ss++;
 
 acl_text = ss;
 
+if (  !f.running_in_test_harness
+   &&  is_tainted2(acl_text, LOG_MAIN|LOG_PANIC,
+                         "Tainted ACL text \"%s\"", acl_text))
+  {
+  /* Avoid leaking info to an attacker */
+  *log_msgptr = US"internal configuration error";
+  return ERROR;
+  }
+
 /* Handle the case of a string that does not contain any spaces. Look for a
 named ACL among those read from the configuration, or a previously read file.
 It is possible that the pointer to the ACL is NULL if the configuration
@@ -4111,10 +4124,8 @@ if (Ustrchr(ss, ' ') == NULL)
   else if (*ss == '/')
     {
     struct stat statbuf;
-    if (is_tainted(ss))
+    if (is_tainted2(ss, LOG_MAIN|LOG_PANIC, "Tainted ACL file name '%s'", ss))
       {
-      log_write(0, LOG_MAIN|LOG_PANIC,
-       "attempt to open tainted ACL file name \"%s\"", ss);
       /* Avoid leaking info to an attacker */
       *log_msgptr = US"internal configuration error";
       return ERROR;