X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Fdkim_transport.c;h=c09c5059b871e5477204ababd9202a4b650f363b;hp=b61c41edcc49467eabe79c5034ba40f245e49ed1;hb=HEAD;hpb=94e1f16d6033683bdebaf5092f64c58bc044dd2d diff --git a/src/src/dkim_transport.c b/src/src/dkim_transport.c index b61c41edc..c09c5059b 100644 --- a/src/src/dkim_transport.c +++ b/src/src/dkim_transport.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2016 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* Transport shim for dkim signing */ @@ -21,8 +21,8 @@ if (dkim->dkim_strict) uschar * dkim_strict_result = expand_string(dkim->dkim_strict); if (dkim_strict_result) - if ( (strcmpic(dkim->dkim_strict, US"1") == 0) || - (strcmpic(dkim->dkim_strict, US"true") == 0) ) + if ( strcmpic(dkim_strict_result, US"1") == 0 + || strcmpic(dkim_strict_result, US"true") == 0) { /* Set errno to something halfway meaningful */ *errp = EACCES; @@ -37,9 +37,17 @@ return TRUE; /* Send the file at in_fd down the output fd */ static BOOL -dkt_send_file(int out_fd, int in_fd, off_t off, size_t size) +dkt_send_file(int out_fd, int in_fd, off_t off +#ifdef OS_SENDFILE + , size_t size +#endif + ) { +#ifdef OS_SENDFILE DEBUG(D_transport) debug_printf("send file fd=%d size=%u\n", out_fd, (unsigned)(size - off)); +#else +DEBUG(D_transport) debug_printf("send file fd=%d\n", out_fd); +#endif /*XXX should implement timeout, like transport_write_block_fd() ? */ @@ -48,7 +56,7 @@ DEBUG(D_transport) debug_printf("send file fd=%d size=%u\n", out_fd, (unsigned)( to the socket. However only if we don't use TLS, as then there's another layer of indirection before the data finally hits the socket. */ -if (tls_out.active != out_fd) +if (tls_out.active.sock != out_fd) { ssize_t copied = 0; @@ -75,9 +83,9 @@ else while (sread) { -#ifdef SUPPORT_TLS - wwritten = tls_out.active == out_fd - ? tls_write(FALSE, p, sread, FALSE) +#ifndef DISABLE_TLS + wwritten = tls_out.active.sock == out_fd + ? tls_write(tls_out.active.tls_ctx, p, sread, FALSE) : write(out_fd, CS p, sread); #else wwritten = write(out_fd, CS p, sread); @@ -116,7 +124,7 @@ dkt_direct(transport_ctx * tctx, struct ob_dkim * dkim, { int save_fd = tctx->u.fd; int save_options = tctx->options; -BOOL save_wireformat = spool_file_wireformat; +BOOL save_wireformat = f.spool_file_wireformat; uschar * hdrs; gstring * dkim_signature; int hsize; @@ -142,8 +150,14 @@ if (!rc) return FALSE; /* Get signatures for headers plus spool data file */ -dkim->dot_stuffed = !!(save_options & topt_end_dot); +#ifdef EXPERIMENTAL_ARC +arc_sign_init(); +#endif + +/* The dotstuffed status of the datafile depends on whether it was stored +in wireformat. */ +dkim->dot_stuffed = f.spool_file_wireformat; if (!(dkim_signature = dkim_exim_sign(deliver_datafile, SPOOL_DATA_START_OFFSET, hdrs, dkim, &errstr))) if (!(rc = dkt_sign_fail(dkim, &errno))) @@ -152,6 +166,18 @@ if (!(dkim_signature = dkim_exim_sign(deliver_datafile, SPOOL_DATA_START_OFFSET, return FALSE; } +#ifdef EXPERIMENTAL_ARC +if (dkim->arc_signspec) /* Prepend ARC headers */ + { + uschar * e; + if (!(dkim_signature = arc_sign(dkim->arc_signspec, dkim_signature, &e))) + { + *err = e; + return FALSE; + } + } +#endif + /* Write the signature and headers into the deliver-out-buffer. This should mean they go out in the same packet as the MAIL, RCPT and (first) BDAT commands (transport_write_message() sizes the BDAT for the buffered amount) - for short @@ -160,7 +186,7 @@ having already been done - but we have to say we want CRLF output format, and temporarily set the marker for possible already-CRLF input. */ tctx->options &= ~topt_escape_headers; -spool_file_wireformat = TRUE; +f.spool_file_wireformat = TRUE; transport_write_reset(0); if ( ( dkim_signature && dkim_signature->ptr > 0 @@ -170,7 +196,7 @@ if ( ( dkim_signature ) return FALSE; -spool_file_wireformat = save_wireformat; +f.spool_file_wireformat = save_wireformat; tctx->options = save_options | topt_no_headers | topt_continuation; if (!(transport_write_message(tctx, 0))) @@ -245,7 +271,13 @@ if (!rc) goto CLEANUP; } -/* Feed the file to the goats^W DKIM lib */ +#ifdef EXPERIMENTAL_ARC +arc_sign_init(); +#endif + +/* Feed the file to the goats^W DKIM lib. At this point the dotstuffed +status of the file depends on the output of transport_write_message() just +above, which should be the result of the end_dot flag in tctx->options. */ dkim->dot_stuffed = !!(options & topt_end_dot); if (!(dkim_signature = dkim_exim_sign(dkim_fd, 0, NULL, dkim, &errstr))) @@ -260,6 +292,15 @@ if (!(dkim_signature = dkim_exim_sign(dkim_fd, 0, NULL, dkim, &errstr))) else dlen = dkim_signature->ptr; +#ifdef EXPERIMENTAL_ARC +if (dkim->arc_signspec) /* Prepend ARC headers */ + { + if (!(dkim_signature = arc_sign(dkim->arc_signspec, dkim_signature, USS err))) + goto CLEANUP; + dlen = dkim_signature->ptr; + } +#endif + #ifndef OS_SENDFILE if (options & topt_use_bdat) #endif @@ -297,7 +338,11 @@ if (options & topt_use_bdat) if(dlen > 0 && !transport_write_block(tctx, dkim_signature->s, dlen, TRUE)) goto err; -if (!dkt_send_file(tctx->u.fd, dkim_fd, 0, k_file_size)) +if (!dkt_send_file(tctx->u.fd, dkim_fd, 0 +#ifdef OS_SENDFILE + , k_file_size +#endif + )) { save_errno = errno; rc = FALSE; @@ -339,7 +384,8 @@ dkim_transport_write_message(transport_ctx * tctx, { /* If we can't sign, just call the original function. */ -if (!(dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector)) +if ( !(dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector) + && !dkim->force_bodyhash) return transport_write_message(tctx, 0); /* If there is no filter command set up, construct the message and calculate