X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b6054898ace169a0e5143117397a4f666a5e7283..6db92eab5917e515c83fd773dad6111177a0207f:/src/src/spool_in.c diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 7d95fccc1..de6ee7e51 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -3,7 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 */ +/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for reading spool files. When compiling for a utility (eximon), @@ -253,7 +253,7 @@ sender_helo_name = NULL; sender_host_address = NULL; sender_host_name = NULL; sender_host_port = 0; -sender_host_authenticated = NULL; +sender_host_authenticated = sender_host_auth_pubname = NULL; sender_ident = NULL; f.sender_local = FALSE; f.sender_set_untrusted = FALSE; @@ -304,6 +304,35 @@ dsn_ret = 0; dsn_envid = NULL; } +static void * +fgets_big_buffer(FILE *fp) +{ +int len = 0; + +big_buffer[0] = 0; +if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) return NULL; + +while ((len = Ustrlen(big_buffer)) == big_buffer_size-1 + && big_buffer[len-1] != '\n') + { + uschar *newbuffer; + int newsize; + + if (big_buffer_size >= BIG_BUFFER_SIZE * 4) return NULL; + newsize = big_buffer_size * 2; + newbuffer = store_get_perm(newsize, FALSE); + memcpy(newbuffer, big_buffer, len); + + big_buffer = newbuffer; + big_buffer_size = newsize; + if (Ufgets(big_buffer + len, big_buffer_size - len, fp) == NULL) return NULL; + } + +if (len <= 0 || big_buffer[len-1] != '\n') return NULL; +return big_buffer; +} + + /************************************************* * Read spool header file * @@ -422,6 +451,8 @@ if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR; if (sscanf(CS big_buffer, TIME_T_FMT " %d", &received_time.tv_sec, &warning_count) != 2) goto SPOOL_FORMAT_ERROR; received_time.tv_usec = 0; +received_time_complete = received_time; + message_age = time(NULL) - received_time.tv_sec; #ifndef COMPILE_UTILITY @@ -452,26 +483,13 @@ If the line starts with "--" the content of the variable is tainted. */ for (;;) { - int len; BOOL tainted; uschar * var; const uschar * p; - if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR; + if (fgets_big_buffer(fp) == NULL) goto SPOOL_READ_ERROR; if (big_buffer[0] != '-') break; - while ( (len = Ustrlen(big_buffer)) == big_buffer_size-1 - && big_buffer[len-1] != '\n' - ) - { /* buffer not big enough for line; certs make this possible */ - uschar * buf; - if (big_buffer_size >= BIG_BUFFER_SIZE*4) goto SPOOL_READ_ERROR; - buf = store_get_perm(big_buffer_size *= 2, FALSE); - memcpy(buf, big_buffer, --len); - big_buffer = buf; - if (Ufgets(big_buffer+len, big_buffer_size-len, fp) == NULL) - goto SPOOL_READ_ERROR; - } - big_buffer[len-1] = 0; + big_buffer[Ustrlen(big_buffer)-1] = 0; tainted = big_buffer[1] == '-'; var = big_buffer + (tainted ? 2 : 1); @@ -580,6 +598,8 @@ for (;;) host_lookup_deferred = TRUE; else if (Ustrcmp(p, "ost_lookup_failed") == 0) host_lookup_failed = TRUE; + else if (Ustrncmp(p, "ost_auth_pubname", 16) == 0) + sender_host_auth_pubname = string_copy_taint(var + 18, tainted); else if (Ustrncmp(p, "ost_auth", 8) == 0) sender_host_authenticated = string_copy_taint(var + 10, tainted); else if (Ustrncmp(p, "ost_name", 8) == 0) @@ -637,7 +657,19 @@ for (;;) { unsigned usec; if (sscanf(CS var + 20, "%u", &usec) == 1) + { received_time.tv_usec = usec; + if (!received_time_complete.tv_sec) received_time_complete.tv_usec = usec; + } + } + else if (Ustrncmp(p, "eceived_time_complete", 21) == 0) + { + unsigned sec, usec; + if (sscanf(CS var + 23, "%u.%u", &sec, &usec) == 2) + { + received_time_complete.tv_sec = sec; + received_time_complete.tv_usec = usec; + } } break; @@ -758,7 +790,7 @@ for (recipients_count = 0; recipients_count < rcount; recipients_count++) uschar *errors_to = NULL; uschar *p; - if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR; + if (fgets_big_buffer(fp) == NULL) goto SPOOL_READ_ERROR; nn = Ustrlen(big_buffer); if (nn < 2) goto SPOOL_FORMAT_ERROR; @@ -991,6 +1023,47 @@ errno = ERRNO_SPOOLFORMAT; return inheader? spool_read_hdrerror : spool_read_enverror; } + +#ifndef COMPILE_UTILITY +/* Read out just the (envelope) sender string from the spool -H file. +Remove the <> wrap and return it in allocated store. Return NULL on error. + +We assume that message_subdir is already set. +*/ + +uschar * +spool_sender_from_msgid(const uschar * id) +{ +uschar * name = string_sprintf("%s-H", id); +FILE * fp; +int n; +uschar * yield = NULL; + +if (!(fp = Ufopen(spool_fname(US"input", message_subdir, name, US""), "rb"))) + return NULL; + +DEBUG(D_deliver) debug_printf_indent("reading spool file %s\n", name); + +/* Skip the line with the copy of the filename, then the line with login/uid/gid. +Read the next line, which should be the envelope sender. +Do basic validation on that. */ + +if ( Ufgets(big_buffer, big_buffer_size, fp) != NULL + && Ufgets(big_buffer, big_buffer_size, fp) != NULL + && Ufgets(big_buffer, big_buffer_size, fp) != NULL + && (n = Ustrlen(big_buffer)) >= 3 + && big_buffer[0] == '<' && big_buffer[n-2] == '>' + ) + { + yield = store_get(n-2, TRUE); /* tainted */ + Ustrncpy(yield, big_buffer+1, n-3); + yield[n-3] = 0; + } +fclose(fp); +return yield; +} +#endif /* COMPILE_UTILITY */ + /* vi: aw ai sw=2 */ /* End of spool_in.c */