X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Ftransport.c;h=aca33762b12c10036da01ac4a3c7567ebe8632b5;hb=875512a36119423217802de1f79350e7fce1cd9b;hp=efc30be593645ebd2585c914bc1e3b407341363f;hpb=40c90bca9f7e2952bd64faebceb53538f80805a7;p=exim.git diff --git a/src/src/transport.c b/src/src/transport.c index efc30be59..aca33762b 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -108,10 +108,23 @@ optionlist optionlist_transports[] = { (void *)offsetof(transport_instance, uid) } }; -int optionlist_transports_size = - sizeof(optionlist_transports)/sizeof(optionlist); +int optionlist_transports_size = nelem(optionlist_transports); +void +readconf_options_transports(void) +{ +struct transport_info * ti; + +readconf_options_from_list(optionlist_transports, nelem(optionlist_transports), US"TRANSPORTS", NULL); + +for (ti = transports_available; ti->driver_name[0]; ti++) + { + macro_create(string_sprintf("_DRIVER_TRANSPORT_%T", ti->driver_name), US"y", FALSE, TRUE); + readconf_options_from_list(ti->options, (unsigned)*ti->options_count, US"TRANSPORT", ti->driver_name); + } +} + /************************************************* * Initialize transport list * *************************************************/ @@ -611,7 +624,7 @@ return write_chunk(fd, tctx, pp->address, Ustrlen(pp->address)); -/* Add/remove/rewwrite headers, and send them plus the empty-line sparator. +/* Add/remove/rewrite headers, and send them plus the empty-line separator. Globals: header_list @@ -895,7 +908,7 @@ if (!(tctx->options & topt_no_headers)) /* Pick up from all the addresses. The plist and dlist variables are anchors for lists of addresses already handled; they have to be defined at - this level becuase write_env_to() calls itself recursively. */ + this level because write_env_to() calls itself recursively. */ for (p = tctx->addr; p; p = p->next) if (!write_env_to(p, &plist, &dlist, &first, fd, tctx)) @@ -941,7 +954,7 @@ suboptimal. */ if (tctx->options & topt_use_bdat) { off_t fsize; - int hsize, size; + int hsize, size = 0; if ((hsize = chunk_ptr - deliver_out_buffer) < 0) hsize = 0; @@ -965,7 +978,7 @@ if (tctx->options & topt_use_bdat) if (size > DELIVER_OUT_BUFFER_SIZE && hsize > 0) { DEBUG(D_transport) - debug_printf("sending small initial BDAT; hssize=%d\n", hsize); + debug_printf("sending small initial BDAT; hsize=%d\n", hsize); if ( tctx->chunk_cb(fd, tctx, hsize, 0) != OK || !transport_write_block(fd, deliver_out_buffer, hsize) || tctx->chunk_cb(fd, tctx, 0, tc_reap_prev) != OK @@ -1049,18 +1062,16 @@ Returns: TRUE on success; FALSE (with errno) for any failure BOOL dkim_transport_write_message(int out_fd, transport_ctx * tctx, - struct ob_dkim * dkim) + struct ob_dkim * dkim, const uschar ** err) { int dkim_fd; int save_errno = 0; BOOL rc; uschar * dkim_spool_name; -int sread = 0; -int wwritten = 0; -uschar *dkim_signature = NULL; -int siglen = 0; +uschar * dkim_signature = NULL; +int sread = 0, wwritten = 0, siglen = 0, options; off_t k_file_size; -int options; +const uschar * errstr; /* If we can't sign, just call the original function. */ @@ -1075,6 +1086,7 @@ if ((dkim_fd = Uopen(dkim_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE)) < 0) /* Can't create spool file. Ugh. */ rc = FALSE; save_errno = errno; + *err = string_sprintf("dkim spoolfile create: %s", strerror(errno)); goto CLEANUP; } @@ -1096,7 +1108,7 @@ if (!rc) /* Rewind file and feed it to the goats^W DKIM lib */ dkim->dot_stuffed = !!(options & topt_end_dot); lseek(dkim_fd, 0, SEEK_SET); -if ((dkim_signature = dkim_exim_sign(dkim_fd, dkim))) +if ((dkim_signature = dkim_exim_sign(dkim_fd, dkim, &errstr))) siglen = Ustrlen(dkim_signature); else if (dkim->dkim_strict) { @@ -1109,6 +1121,7 @@ else if (dkim->dkim_strict) save_errno = EACCES; log_write(0, LOG_MAIN, "DKIM: message could not be signed," " and dkim_strict is set. Deferring message delivery."); + *err = errstr; rc = FALSE; goto CLEANUP; } @@ -1172,17 +1185,17 @@ else /* Send file down the original fd */ while((sread = read(dkim_fd, deliver_out_buffer, DELIVER_OUT_BUFFER_SIZE)) >0) { - char *p = deliver_out_buffer; + uschar * p = deliver_out_buffer; /* write the chunk */ while (sread) { #ifdef SUPPORT_TLS wwritten = tls_out.active == out_fd - ? tls_write(FALSE, US p, sread) - : write(out_fd, p, sread); + ? tls_write(FALSE, p, sread) + : write(out_fd, CS p, sread); #else - wwritten = write(out_fd, p, sread); + wwritten = write(out_fd, CS p, sread); #endif if (wwritten == -1) goto err; @@ -1235,7 +1248,6 @@ Returns: TRUE on success; FALSE (with errno) for any failure BOOL transport_write_message(int fd, transport_ctx * tctx, int size_limit) { -unsigned wck_flags; BOOL last_filter_was_NL = TRUE; int rc, len, yield, fd_read, fd_write, save_errno; int pfd[2] = {-1, -1}; @@ -1259,7 +1271,6 @@ if ( !transport_filter_argv before being written to the incoming fd. First set up the special processing to be done during the copying. */ -wck_flags = tctx->options & topt_use_crlf; nl_partial_match = -1; if (tctx->check_string && tctx->escape_string) @@ -1283,10 +1294,13 @@ save_errno = 0; yield = FALSE; write_pid = (pid_t)(-1); -(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); -filter_pid = child_open(USS transport_filter_argv, NULL, 077, - &fd_write, &fd_read, FALSE); -(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC); + { + int bits = fcntl(fd, F_GETFD); + (void)fcntl(fd, F_SETFD, bits | FD_CLOEXEC); + filter_pid = child_open(USS transport_filter_argv, NULL, 077, + &fd_write, &fd_read, FALSE); + (void)fcntl(fd, F_SETFD, bits & ~FD_CLOEXEC); + } if (filter_pid < 0) goto TIDY_UP; /* errno set */ DEBUG(D_transport) @@ -1425,14 +1439,19 @@ if (write_pid > 0) { rc = child_close(write_pid, 30); if (yield) - { if (rc == 0) { BOOL ok; - int dummy = read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)); - if (!ok) + if (read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)) != sizeof(BOOL)) + { + DEBUG(D_transport) + debug_printf("pipe read from writing process: %s\n", strerror(errno)); + save_errno = ERRNO_FILTER_FAIL; + yield = FALSE; + } + else if (!ok) { - dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); + int dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); dummy = read(pfd[pipe_read], (void *)&(tctx->addr->more_errno), sizeof(int)); yield = FALSE; } @@ -1444,7 +1463,6 @@ if (write_pid > 0) tctx->addr->more_errno = rc; DEBUG(D_transport) debug_printf("writing process returned %d\n", rc); } - } } (void)close(pfd[pipe_read]); @@ -1941,7 +1959,7 @@ DEBUG(D_transport) debug_printf("transport_pass_socket entered\n"); if ((pid = fork()) == 0) { - int i = 17; + int i = 19; const uschar **argv; /* Disconnect entirely from the parent process. If we are running in the @@ -1964,7 +1982,15 @@ if ((pid = fork()) == 0) if (smtp_peer_options & PEER_OFFERED_PIPE) argv[i++] = US"-MCP"; if (smtp_peer_options & PEER_OFFERED_SIZE) argv[i++] = US"-MCS"; #ifdef SUPPORT_TLS - if (smtp_peer_options & PEER_OFFERED_TLS) argv[i++] = US"-MCT"; + if (smtp_peer_options & PEER_OFFERED_TLS) + if (tls_out.active >= 0 || continue_proxy) + { + argv[i++] = US"-MCt"; + argv[i++] = sending_ip_address; + argv[i++] = string_sprintf("%d", sending_port); + } + else + argv[i++] = US"-MCT"; #endif if (queue_run_pid != (pid_t)0) @@ -2254,7 +2280,7 @@ if (expand_arguments) */ if (address_pipe_argcount > 1) memmove( - /* current position + additonal args */ + /* current position + additional args */ argv + i + address_pipe_argcount, /* current position + 1 (for the (uschar *)0 at the end) */ argv + i + 1,