cppcheck sliencing
[exim.git] / src / src / spool_in.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2020 - 2022 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 /* Functions for reading spool files. When compiling for a utility (eximon),
11 not all are needed, and some functionality can be cut out. */
12
13
14 #include "exim.h"
15
16
17
18 #ifndef COMPILE_UTILITY
19 /*************************************************
20 *           Open and lock data file              *
21 *************************************************/
22
23 /* The data file is the one that is used for locking, because the header file
24 can get replaced during delivery because of header rewriting. The file has
25 to opened with write access so that we can get an exclusive lock, but in
26 fact it won't be written to. Just in case there's a major disaster (e.g.
27 overwriting some other file descriptor with the value of this one), open it
28 with append.
29
30 As called by deliver_message() (at least) we are operating as root.
31
32 Argument: the id of the message
33 Returns:  fd if file successfully opened and locked, else -1
34
35 Side effect: message_subdir is set for the (possibly split) spool directory
36 */
37
38 int
39 spool_open_datafile(uschar *id)
40 {
41 struct stat statbuf;
42 flock_t lock_data;
43 int fd;
44
45 /* If split_spool_directory is set, first look for the file in the appropriate
46 sub-directory of the input directory. If it is not found there, try the input
47 directory itself, to pick up leftovers from before the splitting. If split_
48 spool_directory is not set, first look in the main input directory. If it is
49 not found there, try the split sub-directory, in case it is left over from a
50 splitting state. */
51
52 for (int i = 0; i < 2; i++)
53   {
54   uschar * fname;
55   int save_errno;
56
57   set_subdir_str(message_subdir, id, i);
58   fname = spool_fname(US"input", message_subdir, id, US"-D");
59   DEBUG(D_deliver) debug_printf_indent("Trying spool file %s\n", fname);
60
61   /* We protect against symlink attacks both in not propagating the
62    * file-descriptor to other processes as we exec, and also ensuring that we
63    * don't even open symlinks.
64    * No -D file inside the spool area should be a symlink.
65    */
66   if ((fd = Uopen(fname,
67                   EXIM_CLOEXEC | EXIM_NOFOLLOW | O_RDWR | O_APPEND, 0)) >= 0)
68     break;
69   save_errno = errno;
70   if (errno == ENOENT)
71     {
72     if (i == 0) continue;
73     if (!f.queue_running)
74       log_write(0, LOG_MAIN, "Spool%s%s file %s-D not found",
75         *queue_name ? US" Q=" : US"",
76         *queue_name ? queue_name : US"",
77         id);
78     }
79   else
80     log_write(0, LOG_MAIN, "Spool error for %s: %s", fname, strerror(errno));
81   errno = save_errno;
82   return -1;
83   }
84
85 /* File is open and message_subdir is set. Set the close-on-exec flag, and lock
86 the file. We lock only the first line of the file (containing the message ID)
87 because this apparently is needed for running Exim under Cygwin. If the entire
88 file is locked in one process, a sub-process cannot access it, even when passed
89 an open file descriptor (at least, I think that's the Cygwin story). On real
90 Unix systems it doesn't make any difference as long as Exim is consistent in
91 what it locks. */
92
93 #ifndef O_CLOEXEC
94 (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
95 #endif
96
97 lock_data.l_type = F_WRLCK;
98 lock_data.l_whence = SEEK_SET;
99 lock_data.l_start = 0;
100 lock_data.l_len = SPOOL_DATA_START_OFFSET;
101
102 if (fcntl(fd, F_SETLK, &lock_data) < 0)
103   {
104   log_write(L_skip_delivery, LOG_MAIN,
105       "Spool file for %s is locked (another process is handling this message)",
106       id);
107   (void)close(fd);
108   errno = 0;
109   return -1;
110   }
111
112 /* Get the size of the data; don't include the leading filename line
113 in the count, but add one for the newline before the data. */
114
115 if (fstat(fd, &statbuf) == 0)
116   {
117   message_body_size = statbuf.st_size - SPOOL_DATA_START_OFFSET;
118   message_size = message_body_size + 1;
119   }
120
121 return fd;
122 }
123 #endif  /* COMPILE_UTILITY */
124
125
126
127 /*************************************************
128 *    Read non-recipients tree from spool file    *
129 *************************************************/
130
131 /* The tree of non-recipients is written to the spool file in a form that
132 makes it easy to read back into a tree. The format is as follows:
133
134    . Each node is preceded by two letter(Y/N) indicating whether it has left
135      or right children. There's one space after the two flags, before the name.
136
137    . The left subtree (if any) then follows, then the right subtree (if any).
138
139 This function is entered with the next input line in the buffer. Note we must
140 save the right flag before recursing with the same buffer.
141
142 Once the tree is read, we re-construct the balance fields by scanning the tree.
143 I forgot to write them out originally, and the compatible fix is to do it this
144 way. This initial local recursing function does the necessary.
145
146 Arguments:
147   node      tree node
148
149 Returns:    maximum depth below the node, including the node itself
150 */
151
152 static int
153 count_below(tree_node *node)
154 {
155 int nleft, nright;
156 if (node == NULL) return 0;
157 nleft = count_below(node->left);
158 nright = count_below(node->right);
159 node->balance = (nleft > nright)? 1 : ((nright > nleft)? 2 : 0);
160 return 1 + ((nleft > nright)? nleft : nright);
161 }
162
163 /* This is the real function...
164
165 Arguments:
166   connect      pointer to the root of the tree
167   f            FILE to read data from
168   buffer       contains next input line; further lines read into it
169   buffer_size  size of the buffer
170
171 Returns:       FALSE on format error
172 */
173
174 static BOOL
175 read_nonrecipients_tree(tree_node **connect, FILE *f, uschar *buffer,
176   int buffer_size)
177 {
178 tree_node *node;
179 int n = Ustrlen(buffer);
180 BOOL right = buffer[1] == 'Y';
181
182 if (n < 5) return FALSE;    /* malformed line */
183 buffer[n-1] = 0;            /* Remove \n */
184 node = store_get(sizeof(tree_node) + n - 3, GET_TAINTED);       /* rcpt names tainted */
185 *connect = node;
186 Ustrcpy(node->name, buffer + 3);
187 node->data.ptr = NULL;
188
189 if (buffer[0] == 'Y')
190   {
191   if (Ufgets(buffer, buffer_size, f) == NULL ||
192     !read_nonrecipients_tree(&node->left, f, buffer, buffer_size))
193       return FALSE;
194   }
195 else node->left = NULL;
196
197 if (right)
198   {
199   if (Ufgets(buffer, buffer_size, f) == NULL ||
200     !read_nonrecipients_tree(&node->right, f, buffer, buffer_size))
201       return FALSE;
202   }
203 else node->right = NULL;
204
205 (void) count_below(*connect);
206 return TRUE;
207 }
208
209
210
211
212 /* Reset all the global variables to their default values. However, there is
213 one exception. DO NOT change the default value of dont_deliver, because it may
214 be forced by an external setting. */
215
216 void
217 spool_clear_header_globals(void)
218 {
219 acl_var_c = acl_var_m = NULL;
220 authenticated_id = NULL;
221 authenticated_sender = NULL;
222 f.allow_unqualified_recipient = FALSE;
223 f.allow_unqualified_sender = FALSE;
224 body_linecount = 0;
225 body_zerocount = 0;
226 f.deliver_firsttime = FALSE;
227 f.deliver_freeze = FALSE;
228 deliver_frozen_at = 0;
229 f.deliver_manual_thaw = FALSE;
230 /* f.dont_deliver must NOT be reset */
231 header_list = header_last = NULL;
232 host_lookup_deferred = FALSE;
233 host_lookup_failed = FALSE;
234 interface_address = NULL;
235 interface_port = 0;
236 f.local_error_message = FALSE;
237 #ifdef HAVE_LOCAL_SCAN
238 local_scan_data = NULL;
239 #endif
240 max_received_linelength = 0;
241 message_linecount = 0;
242 received_protocol = NULL;
243 received_count = 0;
244 recipients_list = NULL;
245 sender_address = NULL;
246 sender_fullhost = NULL;
247 sender_helo_name = NULL;
248 sender_host_address = NULL;
249 sender_host_name = NULL;
250 sender_host_port = 0;
251 sender_host_authenticated = sender_host_auth_pubname = NULL;
252 sender_ident = NULL;
253 f.sender_local = FALSE;
254 f.sender_set_untrusted = FALSE;
255 smtp_active_hostname = primary_hostname;
256 #ifndef COMPILE_UTILITY
257 f.spool_file_wireformat = FALSE;
258 #endif
259 tree_nonrecipients = NULL;
260
261 #ifdef EXPERIMENTAL_BRIGHTMAIL
262 bmi_run = 0;
263 bmi_verdicts = NULL;
264 #endif
265
266 #ifndef DISABLE_DKIM
267 dkim_signers = NULL;
268 f.dkim_disable_verify = FALSE;
269 dkim_collect_input = 0;
270 #endif
271
272 #ifndef DISABLE_TLS
273 tls_in.certificate_verified = FALSE;
274 # ifdef SUPPORT_DANE
275 tls_in.dane_verified = FALSE;
276 # endif
277 tls_in.ver = tls_in.cipher = NULL;
278 # ifndef COMPILE_UTILITY        /* tls support fns not built in */
279 tls_free_cert(&tls_in.ourcert);
280 tls_free_cert(&tls_in.peercert);
281 # endif
282 tls_in.peerdn = NULL;
283 tls_in.sni = NULL;
284 tls_in.ocsp = OCSP_NOT_REQ;
285 #endif
286
287 #ifdef WITH_CONTENT_SCAN
288 spam_bar = NULL;
289 spam_score = NULL;
290 spam_score_int = NULL;
291 #endif
292
293 #if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
294 message_smtputf8 = FALSE;
295 message_utf8_downconvert = 0;
296 #endif
297
298 #ifndef COMPILE_UTILITY
299 debuglog_name[0] = '\0';
300 #endif
301 dsn_ret = 0;
302 dsn_envid = NULL;
303 }
304
305 static void *
306 fgets_big_buffer(FILE *fp)
307 {
308 int len = 0;
309
310 big_buffer[0] = 0;
311 if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) return NULL;
312
313 while ((len = Ustrlen(big_buffer)) == big_buffer_size-1
314       && big_buffer[len-1] != '\n')
315   {
316   uschar *newbuffer;
317   int newsize;
318
319   if (big_buffer_size >= BIG_BUFFER_SIZE * 4) return NULL;
320   newsize = big_buffer_size * 2;
321   newbuffer = store_get_perm(newsize, FALSE);
322   memcpy(newbuffer, big_buffer, len);
323
324   big_buffer = newbuffer;
325   big_buffer_size = newsize;
326   if (Ufgets(big_buffer + len, big_buffer_size - len, fp) == NULL) return NULL;
327   }
328
329 if (len <= 0 || big_buffer[len-1] != '\n') return NULL;
330 return big_buffer;
331 }
332
333
334
335 /*************************************************
336 *             Read spool header file             *
337 *************************************************/
338
339 /* This function reads a spool header file and places the data into the
340 appropriate global variables. The header portion is always read, but header
341 structures are built only if read_headers is set true. It isn't, for example,
342 while generating -bp output.
343
344 It may be possible for blocks of nulls (binary zeroes) to get written on the
345 end of a file if there is a system crash during writing. It was observed on an
346 earlier version of Exim that omitted to fsync() the files - this is thought to
347 have been the cause of that incident, but in any case, this code must be robust
348 against such an event, and if such a file is encountered, it must be treated as
349 malformed.
350
351 As called from deliver_message() (at least) we are running as root.
352
353 Arguments:
354   name          name of the header file, including the -H
355   read_headers  TRUE if in-store header structures are to be built
356   subdir_set    TRUE is message_subdir is already set
357
358 Returns:        spool_read_OK        success
359                 spool_read_notopen   open failed
360                 spool_read_enverror  error in the envelope portion
361                 spool_read_hdrerror  error in the header portion
362 */
363
364 int
365 spool_read_header(uschar *name, BOOL read_headers, BOOL subdir_set)
366 {
367 FILE * fp = NULL;
368 int n;
369 int rcount = 0;
370 long int uid, gid;
371 BOOL inheader = FALSE;
372
373 /* Reset all the global variables to their default values. However, there is
374 one exception. DO NOT change the default value of dont_deliver, because it may
375 be forced by an external setting. */
376
377 spool_clear_header_globals();
378
379 /* Generate the full name and open the file. If message_subdir is already
380 set, just look in the given directory. Otherwise, look in both the split
381 and unsplit directories, as for the data file above. */
382
383 for (int n = 0; n < 2; n++)
384   {
385   if (!subdir_set)
386     set_subdir_str(message_subdir, name, n);
387
388   if ((fp = Ufopen(spool_fname(US"input", message_subdir, name, US""), "rb")))
389     break;
390   if (n != 0 || subdir_set || errno != ENOENT)
391     return spool_read_notopen;
392   }
393
394 errno = 0;
395
396 #ifndef COMPILE_UTILITY
397 DEBUG(D_deliver) debug_printf_indent("reading spool file %s\n", name);
398 #endif  /* COMPILE_UTILITY */
399
400 /* The first line of a spool file contains the message id followed by -H (i.e.
401 the file name), in order to make the file self-identifying. */
402
403 if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
404 if (Ustrlen(big_buffer) != MESSAGE_ID_LENGTH + 3 ||
405     Ustrncmp(big_buffer, name, MESSAGE_ID_LENGTH + 2) != 0)
406   goto SPOOL_FORMAT_ERROR;
407
408 /* The next three lines in the header file are in a fixed format. The first
409 contains the login, uid, and gid of the user who caused the file to be written.
410 There are known cases where a negative gid is used, so we allow for both
411 negative uids and gids. The second contains the mail address of the message's
412 sender, enclosed in <>. The third contains the time the message was received,
413 and the number of warning messages for delivery delays that have been sent. */
414
415 if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
416
417  {
418   uschar *p = big_buffer + Ustrlen(big_buffer);
419   while (p > big_buffer && isspace(p[-1])) p--;
420   *p = 0;
421   if (!isdigit(p[-1])) goto SPOOL_FORMAT_ERROR;
422   while (p > big_buffer && (isdigit(p[-1]) || '-' == p[-1])) p--;
423   gid = Uatoi(p);
424   if (p <= big_buffer || *(--p) != ' ') goto SPOOL_FORMAT_ERROR;
425   *p = 0;
426   if (!isdigit(p[-1])) goto SPOOL_FORMAT_ERROR;
427   while (p > big_buffer && (isdigit(p[-1]) || '-' == p[-1])) p--;
428   uid = Uatoi(p);
429   if (p <= big_buffer || *(--p) != ' ') goto SPOOL_FORMAT_ERROR;
430   *p = 0;
431  }
432
433 originator_login = string_copy(big_buffer);
434 originator_uid = (uid_t)uid;
435 originator_gid = (gid_t)gid;
436
437 /* envelope from */
438 if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
439 n = Ustrlen(big_buffer);
440 if (n < 3 || big_buffer[0] != '<' || big_buffer[n-2] != '>')
441   goto SPOOL_FORMAT_ERROR;
442
443 sender_address = store_get(n-2, GET_TAINTED);
444 Ustrncpy(sender_address, big_buffer+1, n-3);
445 sender_address[n-3] = 0;
446
447 /* time */
448 if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
449 if (sscanf(CS big_buffer, TIME_T_FMT " %d", &received_time.tv_sec, &warning_count) != 2)
450   goto SPOOL_FORMAT_ERROR;
451 received_time.tv_usec = 0;
452 received_time_complete = received_time;
453
454
455 message_age = time(NULL) - received_time.tv_sec;
456 #ifndef COMPILE_UTILITY
457 if (f.running_in_test_harness)
458   message_age = test_harness_fudged_queue_time(message_age);
459 #endif
460
461 #ifndef COMPILE_UTILITY
462 DEBUG(D_deliver) debug_printf_indent("user=%s uid=%ld gid=%ld sender=%s\n",
463   originator_login, (long int)originator_uid, (long int)originator_gid,
464   sender_address);
465 #endif
466
467 /* Now there may be a number of optional lines, each starting with "-". If you
468 add a new setting here, make sure you set the default above.
469
470 Because there are now quite a number of different possibilities, we use a
471 switch on the first character to avoid too many failing tests. Thanks to Nico
472 Erfurth for the patch that implemented this. I have made it even more efficient
473 by not re-scanning the first two characters.
474
475 To allow new versions of Exim that add additional flags to interwork with older
476 versions that do not understand them, just ignore any lines starting with "-"
477 that we don't recognize. Otherwise it wouldn't be possible to back off a new
478 version that left new-style flags written on the spool.
479
480 If the line starts with "--" the content of the variable is tainted.
481 If the line start "--(<lookuptype>)" it is also quoted for the given <lookuptype>.
482 */
483
484 for (;;)
485   {
486   const void * proto_mem;
487   uschar * var;
488   const uschar * p;
489
490   if (fgets_big_buffer(fp) == NULL) goto SPOOL_READ_ERROR;
491   if (big_buffer[0] != '-') break;
492   big_buffer[Ustrlen(big_buffer)-1] = 0;
493
494   proto_mem = big_buffer[1] == '-' ? GET_TAINTED : GET_UNTAINTED;
495   var =  big_buffer + (proto_mem == GET_UNTAINTED ? 1 : 2);
496   if (*var == '(')                              /* marker for quoted value */
497     {
498     uschar * s;
499     int idx;
500     for (s = ++var; *s != ')'; ) s++;
501 #ifndef COMPILE_UTILITY
502     if ((idx = search_findtype(var, s - var)) < 0)
503       {
504       DEBUG(D_any) debug_printf("Unrecognised quoter %.*s\n", (int)(s - var), var+1);
505       goto SPOOL_FORMAT_ERROR;
506       }
507     proto_mem = store_get_quoted(1, GET_TAINTED, idx);
508 #endif  /* COMPILE_UTILITY */
509     var = s + 1;
510     }
511   p = var + 1;
512
513   switch(*var)
514     {
515     case 'a':
516
517     /* Nowadays we use "-aclc" and "-aclm" for the different types of ACL
518     variable, because Exim allows any number of them, with arbitrary names.
519     The line in the spool file is "-acl[cm] <name> <length>". The name excludes
520     the c or m. */
521
522     if (Ustrncmp(p, "clc ", 4) == 0 ||
523         Ustrncmp(p, "clm ", 4) == 0)
524       {
525       uschar *name, *endptr;
526       int count;
527       tree_node *node;
528       endptr = Ustrchr(var + 5, ' ');
529       if (endptr == NULL) goto SPOOL_FORMAT_ERROR;
530       name = string_sprintf("%c%.*s", var[3],
531         (int)(endptr - var - 5), var + 5);
532       if (sscanf(CS endptr, " %d", &count) != 1) goto SPOOL_FORMAT_ERROR;
533       node = acl_var_create(name);
534       node->data.ptr = store_get(count + 1, proto_mem);
535       if (fread(node->data.ptr, 1, count+1, fp) < count) goto SPOOL_READ_ERROR;
536       ((uschar*)node->data.ptr)[count] = 0;
537       }
538
539     else if (Ustrcmp(p, "llow_unqualified_recipient") == 0)
540       f.allow_unqualified_recipient = TRUE;
541     else if (Ustrcmp(p, "llow_unqualified_sender") == 0)
542       f.allow_unqualified_sender = TRUE;
543
544     else if (Ustrncmp(p, "uth_id", 6) == 0)
545       authenticated_id = string_copy_taint(var + 8, proto_mem);
546     else if (Ustrncmp(p, "uth_sender", 10) == 0)
547       authenticated_sender = string_copy_taint(var + 12, proto_mem);
548     else if (Ustrncmp(p, "ctive_hostname", 14) == 0)
549       smtp_active_hostname = string_copy_taint(var + 16, proto_mem);
550
551     /* For long-term backward compatibility, we recognize "-acl", which was
552     used before the number of ACL variables changed from 10 to 20. This was
553     before the subsequent change to an arbitrary number of named variables.
554     This code is retained so that upgrades from very old versions can still
555     handle old-format spool files. The value given after "-acl" is a number
556     that is 0-9 for connection variables, and 10-19 for message variables. */
557
558     else if (Ustrncmp(p, "cl ", 3) == 0)
559       {
560       unsigned index, count;
561       uschar name[20];   /* Need plenty of space for %u format */
562       tree_node * node;
563       if (  sscanf(CS var + 4, "%u %u", &index, &count) != 2
564          || index >= 20
565          || count > 16384       /* arbitrary limit on variable size */
566          )
567         goto SPOOL_FORMAT_ERROR;
568       if (index < 10)
569         (void) string_format(name, sizeof(name), "%c%u", 'c', index);
570       else
571         (void) string_format(name, sizeof(name), "%c%u", 'm', index - 10);
572       node = acl_var_create(name);
573       node->data.ptr = store_get(count + 1, proto_mem);
574       /* We sanity-checked the count, so disable the Coverity error */
575       /* coverity[tainted_data] */
576       if (fread(node->data.ptr, 1, count+1, fp) < count) goto SPOOL_READ_ERROR;
577       (US node->data.ptr)[count] = '\0';
578       }
579     break;
580
581     case 'b':
582     if (Ustrncmp(p, "ody_linecount", 13) == 0)
583       body_linecount = Uatoi(var + 14);
584     else if (Ustrncmp(p, "ody_zerocount", 13) == 0)
585       body_zerocount = Uatoi(var + 14);
586 #ifdef EXPERIMENTAL_BRIGHTMAIL
587     else if (Ustrncmp(p, "mi_verdicts ", 12) == 0)
588       bmi_verdicts = string_copy_taint(var + 13, proto_mem);
589 #endif
590     break;
591
592     case 'd':
593     if (Ustrcmp(p, "eliver_firsttime") == 0)
594       f.deliver_firsttime = TRUE;
595     else if (Ustrncmp(p, "sn_ret", 6) == 0)
596       dsn_ret= atoi(CS var + 7);
597     else if (Ustrncmp(p, "sn_envid", 8) == 0)
598       dsn_envid = string_copy_taint(var + 10, proto_mem);
599 #ifndef COMPILE_UTILITY
600     else if (Ustrncmp(p, "ebug_selector ", 14) == 0)
601       debug_selector = strtol(CS var + 15, NULL, 0);
602     else if (Ustrncmp(p, "ebuglog_name ", 13) == 0)
603       debug_logging_from_spool(var + 14);
604 #endif
605     break;
606
607     case 'f':
608     if (Ustrncmp(p, "rozen", 5) == 0)
609       {
610       f.deliver_freeze = TRUE;
611       if (sscanf(CS var+6, TIME_T_FMT, &deliver_frozen_at) != 1)
612         goto SPOOL_READ_ERROR;
613       }
614     break;
615
616     case 'h':
617     if (Ustrcmp(p, "ost_lookup_deferred") == 0)
618       host_lookup_deferred = TRUE;
619     else if (Ustrcmp(p, "ost_lookup_failed") == 0)
620       host_lookup_failed = TRUE;
621     else if (Ustrncmp(p, "ost_auth_pubname", 16) == 0)
622       sender_host_auth_pubname = string_copy_taint(var + 18, proto_mem);
623     else if (Ustrncmp(p, "ost_auth", 8) == 0)
624       sender_host_authenticated = string_copy_taint(var + 10, proto_mem);
625     else if (Ustrncmp(p, "ost_name", 8) == 0)
626       sender_host_name = string_copy_taint(var + 10, proto_mem);
627     else if (Ustrncmp(p, "elo_name", 8) == 0)
628       sender_helo_name = string_copy_taint(var + 10, proto_mem);
629
630     /* We now record the port number after the address, separated by a
631     dot. For compatibility during upgrading, do nothing if there
632     isn't a value (it gets left at zero). */
633
634     else if (Ustrncmp(p, "ost_address", 11) == 0)
635       {
636       sender_host_port = host_address_extract_port(var + 13);
637       sender_host_address = string_copy_taint(var + 13, proto_mem);
638       }
639     break;
640
641     case 'i':
642     if (Ustrncmp(p, "nterface_address", 16) == 0)
643       {
644       interface_port = host_address_extract_port(var + 18);
645       interface_address = string_copy_taint(var + 18, proto_mem);
646       }
647     else if (Ustrncmp(p, "dent", 4) == 0)
648       sender_ident = string_copy_taint(var + 6, proto_mem);
649     break;
650
651     case 'l':
652     if (Ustrcmp(p, "ocal") == 0)
653       f.sender_local = TRUE;
654     else if (Ustrcmp(var, "localerror") == 0)
655       f.local_error_message = TRUE;
656 #ifdef HAVE_LOCAL_SCAN
657     else if (Ustrncmp(p, "ocal_scan ", 10) == 0)
658       local_scan_data = string_copy_taint(var + 11, proto_mem);
659 #endif
660     break;
661
662     case 'm':
663     if (Ustrcmp(p, "anual_thaw") == 0)
664       f.deliver_manual_thaw = TRUE;
665     else if (Ustrncmp(p, "ax_received_linelength", 22) == 0)
666       max_received_linelength = Uatoi(var + 23);
667     break;
668
669     case 'N':
670     if (*p == 0) f.dont_deliver = TRUE;   /* -N */
671     break;
672
673     case 'r':
674     if (Ustrncmp(p, "eceived_protocol", 16) == 0)
675       received_protocol = string_copy_taint(var + 18, proto_mem);
676     else if (Ustrncmp(p, "eceived_time_usec", 17) == 0)
677       {
678       unsigned usec;
679       if (sscanf(CS var + 20, "%u", &usec) == 1)
680         {
681         received_time.tv_usec = usec;
682         if (!received_time_complete.tv_sec) received_time_complete.tv_usec = usec;
683         }
684       }
685     else if (Ustrncmp(p, "eceived_time_complete", 21) == 0)
686       {
687       unsigned sec, usec;
688       if (sscanf(CS var + 23, "%u.%u", &sec, &usec) == 2)
689         {
690         received_time_complete.tv_sec = sec;
691         received_time_complete.tv_usec = usec;
692         }
693       }
694     break;
695
696     case 's':
697     if (Ustrncmp(p, "ender_set_untrusted", 19) == 0)
698       f.sender_set_untrusted = TRUE;
699 #ifdef WITH_CONTENT_SCAN
700     else if (Ustrncmp(p, "pam_bar ", 8) == 0)
701       spam_bar = string_copy_taint(var + 9, proto_mem);
702     else if (Ustrncmp(p, "pam_score ", 10) == 0)
703       spam_score = string_copy_taint(var + 11, proto_mem);
704     else if (Ustrncmp(p, "pam_score_int ", 14) == 0)
705       spam_score_int = string_copy_taint(var + 15, proto_mem);
706 #endif
707 #ifndef COMPILE_UTILITY
708     else if (Ustrncmp(p, "pool_file_wireformat", 20) == 0)
709       f.spool_file_wireformat = TRUE;
710 #endif
711 #if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
712     else if (Ustrncmp(p, "mtputf8", 7) == 0)
713       message_smtputf8 = TRUE;
714 #endif
715     break;
716
717 #ifndef DISABLE_TLS
718     case 't':
719     if (Ustrncmp(p, "ls_", 3) == 0)
720       {
721       const uschar * q = p + 3;
722       if (Ustrncmp(q, "certificate_verified", 20) == 0)
723         tls_in.certificate_verified = TRUE;
724       else if (Ustrncmp(q, "cipher", 6) == 0)
725         tls_in.cipher = string_copy_taint(q+7, proto_mem);
726 # ifndef COMPILE_UTILITY        /* tls support fns not built in */
727       else if (Ustrncmp(q, "ourcert", 7) == 0)
728         (void) tls_import_cert(q+8, &tls_in.ourcert);
729       else if (Ustrncmp(q, "peercert", 8) == 0)
730         (void) tls_import_cert(q+9, &tls_in.peercert);
731 # endif
732       else if (Ustrncmp(q, "peerdn", 6) == 0)
733         tls_in.peerdn = string_unprinting(string_copy_taint(q+7, proto_mem));
734       else if (Ustrncmp(q, "sni", 3) == 0)
735         tls_in.sni = string_unprinting(string_copy_taint(q+4, proto_mem));
736       else if (Ustrncmp(q, "ocsp", 4) == 0)
737         tls_in.ocsp = q[5] - '0';
738 # ifndef DISABLE_TLS_RESUME
739       else if (Ustrncmp(q, "resumption", 10) == 0)
740         tls_in.resumption = q[11] - 'A';
741 # endif
742       else if (Ustrncmp(q, "ver", 3) == 0)
743         tls_in.ver = string_copy_taint(q+4, proto_mem);
744       }
745     break;
746 #endif
747
748 #if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
749     case 'u':
750     if (Ustrncmp(p, "tf8_downcvt", 11) == 0)
751       message_utf8_downconvert = 1;
752     else if (Ustrncmp(p, "tf8_optdowncvt", 15) == 0)
753       message_utf8_downconvert = -1;
754     break;
755 #endif
756
757     default:    /* Present because some compilers complain if all */
758     break;      /* possibilities are not covered. */
759     }
760   }
761
762 /* Build sender_fullhost if required */
763
764 #ifndef COMPILE_UTILITY
765 host_build_sender_fullhost();
766 #endif  /* COMPILE_UTILITY */
767
768 #ifndef COMPILE_UTILITY
769 DEBUG(D_deliver)
770   debug_printf_indent("sender_local=%d ident=%s\n", f.sender_local,
771     sender_ident ? sender_ident : US"unset");
772 #endif  /* COMPILE_UTILITY */
773
774 /* We now have the tree of addresses NOT to deliver to, or a line
775 containing "XX", indicating no tree. */
776
777 if (Ustrncmp(big_buffer, "XX\n", 3) != 0 &&
778   !read_nonrecipients_tree(&tree_nonrecipients, fp, big_buffer, big_buffer_size))
779     goto SPOOL_FORMAT_ERROR;
780
781 #ifndef COMPILE_UTILITY
782 DEBUG(D_deliver) debug_print_tree("Non-recipients", tree_nonrecipients);
783 #endif  /* COMPILE_UTILITY */
784
785 /* After reading the tree, the next line has not yet been read into the
786 buffer. It contains the count of recipients which follow on separate lines.
787 Apply an arbitrary sanity check.*/
788
789 if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
790 if (sscanf(CS big_buffer, "%d", &rcount) != 1 || rcount > 16384)
791   goto SPOOL_FORMAT_ERROR;
792
793 #ifndef COMPILE_UTILITY
794 DEBUG(D_deliver) debug_printf_indent("recipients_count=%d\n", rcount);
795 #endif  /* COMPILE_UTILITY */
796
797 recipients_list_max = rcount;
798 recipients_list = store_get(rcount * sizeof(recipient_item), GET_UNTAINTED);
799
800 /* We sanitised the count and know we have enough memory, so disable
801 the Coverity error on recipients_count */
802 /* coverity[tainted_data] */
803
804 for (recipients_count = 0; recipients_count < rcount; recipients_count++)
805   {
806   int nn;
807   int pno = -1;
808   int dsn_flags = 0;
809   uschar *orcpt = NULL;
810   uschar *errors_to = NULL;
811   uschar *p;
812
813   if (fgets_big_buffer(fp) == NULL) goto SPOOL_READ_ERROR;
814   nn = Ustrlen(big_buffer);
815   if (nn < 2) goto SPOOL_FORMAT_ERROR;
816
817   /* Remove the newline; this terminates the address if there is no additional
818   data on the line. */
819
820   p = big_buffer + nn - 1;
821   *p-- = 0;
822
823   /* Look back from the end of the line for digits and special terminators.
824   Since an address must end with a domain, we can tell that extra data is
825   present by the presence of the terminator, which is always some character
826   that cannot exist in a domain. (If I'd thought of the need for additional
827   data early on, I'd have put it at the start, with the address at the end. As
828   it is, we have to operate backwards. Addresses are permitted to contain
829   spaces, you see.)
830
831   This code has to cope with various versions of this data that have evolved
832   over time. In all cases, the line might just contain an address, with no
833   additional data. Otherwise, the possibilities are as follows:
834
835   Exim 3 type:       <address><space><digits>,<digits>,<digits>
836
837     The second set of digits is the parent number for one_time addresses. The
838     other values were remnants of earlier experiments that were abandoned.
839
840   Exim 4 first type: <address><space><digits>
841
842     The digits are the parent number for one_time addresses.
843
844   Exim 4 new type:   <address><space><data>#<type bits>
845
846     The type bits indicate what the contents of the data are.
847
848     Bit 01 indicates that, reading from right to left, the data
849       ends with <errors_to address><space><len>,<pno> where pno is
850       the parent number for one_time addresses, and len is the length
851       of the errors_to address (zero meaning none).
852
853     Bit 02 indicates that, again reading from right to left, the data continues
854      with orcpt len(orcpt),dsn_flags
855    */
856
857   while (isdigit(*p)) p--;
858
859   /* Handle Exim 3 spool files */
860
861   if (*p == ',')
862     {
863     int dummy;
864 #if !defined (COMPILE_UTILITY)
865     DEBUG(D_deliver) debug_printf_indent("**** SPOOL_IN - Exim 3 spool file\n");
866 #endif
867     while (isdigit(*(--p)) || *p == ',');
868     if (*p == ' ')
869       {
870       *p++ = 0;
871       (void)sscanf(CS p, "%d,%d", &dummy, &pno);
872       }
873     }
874
875   /* Handle early Exim 4 spool files */
876
877   else if (*p == ' ')
878     {
879 #if !defined (COMPILE_UTILITY)
880     DEBUG(D_deliver) debug_printf_indent("**** SPOOL_IN - early Exim 4 spool file\n");
881 #endif
882     *p++ = 0;
883     (void)sscanf(CS p, "%d", &pno);
884     }
885
886   /* Handle current format Exim 4 spool files */
887
888   else if (*p == '#')
889     {
890     int flags;
891
892 #if !defined (COMPILE_UTILITY)
893     DEBUG(D_deliver) debug_printf_indent("**** SPOOL_IN - Exim standard format spoolfile\n");
894 #endif
895
896     (void)sscanf(CS p+1, "%d", &flags);
897
898     if (flags & 0x01)      /* one_time data exists */
899       {
900       int len;
901       while (isdigit(*(--p)) || *p == ',' || *p == '-');
902       (void)sscanf(CS p+1, "%d,%d", &len, &pno);
903       *p = 0;
904       if (len > 0)
905         {
906         p -= len;
907         errors_to = string_copy_taint(p, GET_TAINTED);
908         }
909       }
910
911     *--p = 0;   /* Terminate address */
912     if (flags & 0x02)      /* one_time data exists */
913       {
914       int len;
915       while (isdigit(*(--p)) || *p == ',' || *p == '-');
916       (void)sscanf(CS p+1, "%d,%d", &len, &dsn_flags);
917       *p = 0;
918       if (len > 0)
919         {
920         p -= len;
921         orcpt = string_copy_taint(p, GET_TAINTED);
922         }
923       }
924
925     *--p = 0;   /* Terminate address */
926     }
927 #if !defined(COMPILE_UTILITY)
928   else
929     { DEBUG(D_deliver) debug_printf_indent("**** SPOOL_IN - No additional fields\n"); }
930
931   if (orcpt || dsn_flags)
932     DEBUG(D_deliver) debug_printf_indent("**** SPOOL_IN - address: <%s> orcpt: <%s> dsn_flags: 0x%x\n",
933       big_buffer, orcpt, dsn_flags);
934   if (errors_to)
935     DEBUG(D_deliver) debug_printf_indent("**** SPOOL_IN - address: <%s> errorsto: <%s>\n",
936       big_buffer, errors_to);
937 #endif
938
939   recipients_list[recipients_count].address = string_copy_taint(big_buffer, GET_TAINTED);
940   recipients_list[recipients_count].pno = pno;
941   recipients_list[recipients_count].errors_to = errors_to;
942   recipients_list[recipients_count].orcpt = orcpt;
943   recipients_list[recipients_count].dsn_flags = dsn_flags;
944   }
945
946 /* The remainder of the spool header file contains the headers for the message,
947 separated off from the previous data by a blank line. Each header is preceded
948 by a count of its length and either a certain letter (for various identified
949 headers), space (for a miscellaneous live header) or an asterisk (for a header
950 that has been rewritten). Count the Received: headers. We read the headers
951 always, in order to check on the format of the file, but only create a header
952 list if requested to do so. */
953
954 inheader = TRUE;
955 if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR;
956 if (big_buffer[0] != '\n') goto SPOOL_FORMAT_ERROR;
957
958 while ((n = fgetc(fp)) != EOF)
959   {
960   header_line *h;
961   uschar flag[4];
962   int i;
963
964   if (!isdigit(n)) goto SPOOL_FORMAT_ERROR;
965   if(ungetc(n, fp) == EOF  ||  fscanf(fp, "%d%c ", &n, flag) == EOF)
966     goto SPOOL_READ_ERROR;
967   if (flag[0] != '*') message_size += n;  /* Omit non-transmitted headers */
968
969   if (read_headers)
970     {
971     h = store_get(sizeof(header_line), GET_UNTAINTED);
972     h->next = NULL;
973     h->type = flag[0];
974     h->slen = n;
975     h->text = store_get(n+1, GET_TAINTED);
976
977     if (h->type == htype_received) received_count++;
978
979     if (header_list) header_last->next = h;
980     else header_list = h;
981     header_last = h;
982
983     for (i = 0; i < n; i++)
984       {
985       int c = fgetc(fp);
986       if (c == 0 || c == EOF) goto SPOOL_FORMAT_ERROR;
987       if (c == '\n' && h->type != htype_old) message_linecount++;
988       h->text[i] = c;
989       }
990     h->text[i] = 0;
991     }
992
993   /* Not requiring header data, just skip through the bytes */
994
995   else for (i = 0; i < n; i++)
996     {
997     int c = fgetc(fp);
998     if (c == 0 || c == EOF) goto SPOOL_FORMAT_ERROR;
999     }
1000   }
1001
1002 /* We have successfully read the data in the header file. Update the message
1003 line count by adding the body linecount to the header linecount. Close the file
1004 and give a positive response. */
1005
1006 #ifndef COMPILE_UTILITY
1007 DEBUG(D_deliver) debug_printf_indent("body_linecount=%d message_linecount=%d\n",
1008   body_linecount, message_linecount);
1009 #endif  /* COMPILE_UTILITY */
1010
1011 message_linecount += body_linecount;
1012
1013 fclose(fp);
1014 return spool_read_OK;
1015
1016
1017 /* There was an error reading the spool or there was missing data,
1018 or there was a format error. A "read error" with no errno means an
1019 unexpected EOF, which we treat as a format error. */
1020
1021 SPOOL_READ_ERROR:
1022 if (errno != 0)
1023   {
1024   n = errno;
1025
1026 #ifndef COMPILE_UTILITY
1027   DEBUG(D_any) debug_printf("Error while reading spool file %s\n", name);
1028 #endif  /* COMPILE_UTILITY */
1029
1030   fclose(fp);
1031   errno = n;
1032   return inheader ? spool_read_hdrerror : spool_read_enverror;
1033   }
1034
1035 SPOOL_FORMAT_ERROR:
1036
1037 #ifndef COMPILE_UTILITY
1038 DEBUG(D_any) debug_printf("Format error in spool file %s\n", name);
1039 #endif  /* COMPILE_UTILITY */
1040
1041 fclose(fp);
1042 errno = ERRNO_SPOOLFORMAT;
1043 return inheader? spool_read_hdrerror : spool_read_enverror;
1044 }
1045
1046
1047 #ifndef COMPILE_UTILITY
1048 /* Read out just the (envelope) sender string from the spool -H file.
1049 Remove the <> wrap and return it in allocated store.  Return NULL on error.
1050
1051 We assume that message_subdir is already set.
1052 */
1053
1054 uschar *
1055 spool_sender_from_msgid(const uschar * id)
1056 {
1057 uschar * name = string_sprintf("%s-H", id);
1058 FILE * fp;
1059 int n;
1060 uschar * yield = NULL;
1061
1062 if (!(fp = Ufopen(spool_fname(US"input", message_subdir, name, US""), "rb")))
1063   return NULL;
1064
1065 DEBUG(D_deliver) debug_printf_indent("reading spool file %s\n", name);
1066
1067 /* Skip the line with the copy of the filename, then the line with login/uid/gid.
1068 Read the next line, which should be the envelope sender.
1069 Do basic validation on that. */
1070
1071 if (  Ufgets(big_buffer, big_buffer_size, fp) != NULL
1072    && Ufgets(big_buffer, big_buffer_size, fp) != NULL
1073    && Ufgets(big_buffer, big_buffer_size, fp) != NULL
1074    && (n = Ustrlen(big_buffer)) >= 3
1075    && big_buffer[0] == '<' && big_buffer[n-2] == '>'
1076    )
1077   {
1078   yield = store_get(n-2, GET_TAINTED);
1079   Ustrncpy(yield, big_buffer+1, n-3);
1080   yield[n-3] = 0;
1081   }
1082 fclose(fp);
1083 return yield;
1084 }
1085 #endif  /* COMPILE_UTILITY */
1086
1087 /* vi: aw ai sw=2
1088 */
1089 /* End of spool_in.c */