Check query strings of query-style lookups for quoting. Bug 2850
[exim.git] / src / src / receive.c
index 3adcbbd88b19de4344dec4e36a78759cedca3464..ba84967c1caa70a4cd34d6889c9ecb331b389ac0 100644 (file)
@@ -527,7 +527,7 @@ if (recipients_count >= recipients_list_max)
     }
 
   recipients_list_max = recipients_list_max ? 2*recipients_list_max : 50;
-  recipients_list = store_get(recipients_list_max * sizeof(recipient_item), FALSE);
+  recipients_list = store_get(recipients_list_max * sizeof(recipient_item), GET_UNTAINTED);
   if (oldlist)
     memcpy(recipients_list, oldlist, oldmax * sizeof(recipient_item));
   }
@@ -1760,17 +1760,18 @@ if (extract_recip || !smtp_input)
 header. Temporarily mark it as "old", i.e. not to be used. We keep header_last
 pointing to the end of the chain to make adding headers simple. */
 
-received_header = header_list = header_last = store_get(sizeof(header_line), FALSE);
+received_header = header_list = header_last = store_get(sizeof(header_line), GET_UNTAINTED);
 header_list->next = NULL;
 header_list->type = htype_old;
 header_list->text = NULL;
 header_list->slen = 0;
 
-/* Control block for the next header to be read. */
+/* Control block for the next header to be read.
+The data comes from the message, so is tainted. */
 
 reset_point = store_mark();
-next = store_get(sizeof(header_line), FALSE);  /* not tainted */
-next->text = store_get(header_size, TRUE);     /* tainted */
+next = store_get(sizeof(header_line), GET_UNTAINTED);
+next->text = store_get(header_size, GET_TAINTED);
 
 /* Initialize message id to be null (indicating no message read), and the
 header names list to be the normal list. Indicate there is no data file open
@@ -1917,10 +1918,8 @@ for (;;)
       goto OVERSIZE;
     header_size *= 2;
 
-    /* The data came from the message, so is tainted. */
-
-    if (!store_extend(next->text, TRUE, oldsize, header_size))
-      next->text = store_newblock(next->text, TRUE, header_size, ptr);
+    if (!store_extend(next->text, oldsize, header_size))
+      next->text = store_newblock(next->text, header_size, ptr);
     }
 
   /* Cope with receiving a binary zero. There is dispute about whether
@@ -2309,8 +2308,8 @@ OVERSIZE:
 
   reset_point = store_mark();
   header_size = 256;
-  next = store_get(sizeof(header_line), FALSE);
-  next->text = store_get(header_size, TRUE);
+  next = store_get(sizeof(header_line), GET_UNTAINTED);
+  next->text = store_get(header_size, GET_TAINTED);
   ptr = 0;
   had_zero = 0;
   prevlines_length = 0;
@@ -2594,7 +2593,7 @@ if (extract_recip)
         white space that follows the newline must not be removed - it is part
         of the header. */
 
-        pp = recipient = store_get(ss - s + 1, is_tainted(s));
+        pp = recipient = store_get(ss - s + 1, s);
         for (uschar * p = s; p < ss; p++) if (*p != '\n') *pp++ = *p;
         *pp = 0;
 
@@ -2626,7 +2625,7 @@ if (extract_recip)
         if (!recipient && Ustrcmp(errmess, "empty address") != 0)
           {
           int len = Ustrlen(s);
-          error_block *b = store_get(sizeof(error_block), FALSE);
+          error_block * b = store_get(sizeof(error_block), GET_UNTAINTED);
           while (len > 0 && isspace(s[len-1])) len--;
           b->next = NULL;
           b->text1 = string_printing(string_copyn(s, len));
@@ -2825,7 +2824,7 @@ function may mess with the real recipients. */
 
 if (LOGGING(received_recipients))
   {
-  raw_recipients = store_get(recipients_count * sizeof(uschar *), FALSE);
+  raw_recipients = store_get(recipients_count * sizeof(uschar *), GET_UNTAINTED);
   for (int i = 0; i < recipients_count; i++)
     raw_recipients[i] = string_copy(recipients_list[i].address);
   raw_recipients_count = recipients_count;
@@ -2835,10 +2834,13 @@ if (LOGGING(received_recipients))
 recipients will get here only if the conditions were right (allow_unqualified_
 recipient is TRUE). */
 
+DEBUG(D_rewrite)
+  { debug_printf_indent("qualify & rewrite recipients list\n"); acl_level++; }
 for (int i = 0; i < recipients_count; i++)
   recipients_list[i].address = /* deconst ok as src was not cont */
     US rewrite_address(recipients_list[i].address, TRUE, TRUE,
       global_rewrite_rules, rewrite_existflags);
+DEBUG(D_rewrite) acl_level--;
 
 /* If there is no From: header, generate one for local (without
 suppress_local_fixups) or submission_mode messages. If there is no sender
@@ -3010,6 +3012,8 @@ if (  from_header
 /* If there are any rewriting rules, apply them to the sender address, unless
 it has already been rewritten as part of verification for SMTP input. */
 
+DEBUG(D_rewrite)
+  { debug_printf("global rewrite rules\n"); acl_level++; }
 if (global_rewrite_rules && !sender_address_unrewritten && *sender_address)
   {
   /* deconst ok as src was not const */
@@ -3018,6 +3022,7 @@ if (global_rewrite_rules && !sender_address_unrewritten && *sender_address)
   DEBUG(D_receive|D_rewrite)
     debug_printf("rewritten sender = %s\n", sender_address);
   }
+DEBUG(D_rewrite) acl_level--;
 
 
 /* The headers must be run through rewrite_header(), because it ensures that
@@ -3034,12 +3039,13 @@ We start at the second header, skipping our own Received:. This rewriting is
 documented as happening *after* recipient addresses are taken from the headers
 by the -t command line option. An added Sender: gets rewritten here. */
 
-for (header_line * h = header_list->next; h; h = h->next)
-  {
-  header_line *newh = rewrite_header(h, NULL, NULL, global_rewrite_rules,
-    rewrite_existflags, TRUE);
-  if (newh) h = newh;
-  }
+DEBUG(D_rewrite)
+  { debug_printf("rewrite headers\n"); acl_level++; }
+for (header_line * h = header_list->next, * newh; h; h = h->next)
+  if ((newh = rewrite_header(h, NULL, NULL, global_rewrite_rules,
+                             rewrite_existflags, TRUE)))
+    h = newh;
+DEBUG(D_rewrite) acl_level--;
 
 
 /* An RFC 822 (sic) message is not legal unless it has at least one of "to",
@@ -4212,7 +4218,7 @@ f.receive_call_bombout = TRUE;
 /* Before sending an SMTP response in a TCP/IP session, we check to see if the
 connection has gone away. This can only be done if there is no unconsumed input
 waiting in the local input buffer. We can test for this by calling
-receive_smtp_buffered(). RFC 2920 (pipelining) explicitly allows for additional
+receive_hasc(). RFC 2920 (pipelining) explicitly allows for additional
 input to be sent following the final dot, so the presence of following input is
 not an error.
 
@@ -4227,8 +4233,8 @@ Of course, since TCP/IP is asynchronous, there is always a chance that the
 connection will vanish between the time of this test and the sending of the
 response, but the chance of this happening should be small. */
 
-if (smtp_input && sender_host_address && !f.sender_host_notsocket &&
-    !receive_smtp_buffered())
+if (  smtp_input && sender_host_address && !f.sender_host_notsocket
+   && !receive_hasc())
   {
   if (poll_one_fd(fileno(smtp_in), POLLIN, 0) != 0)
     {
@@ -4409,12 +4415,12 @@ if (smtp_input)
        the socket. */
 
         smtp_printf("250- %u byte chunk, total %d\r\n250 OK id=%s\r\n",
-           receive_smtp_buffered(),
+           receive_hasc(),
            chunking_datasize, message_size+message_linecount, message_id);
        chunking_state = CHUNKING_OFFERED;
        }
       else
-        smtp_printf("250 OK id=%s\r\n", receive_smtp_buffered(), message_id);
+        smtp_printf("250 OK id=%s\r\n", receive_hasc(), message_id);
 
       if (host_checking)
         fprintf(stdout,