git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
tidying
[exim.git]
/
src
/
src
/
dkim_transport.c
diff --git
a/src/src/dkim_transport.c
b/src/src/dkim_transport.c
index 4d26f9291dba78cc3a75fa93e4eb8610257a5cd8..c09c5059b871e5477204ababd9202a4b650f363b 100644
(file)
--- a/
src/src/dkim_transport.c
+++ b/
src/src/dkim_transport.c
@@
-2,7
+2,7
@@
* Exim - an Internet mail transport agent *
*************************************************/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 201
6
*/
+/* Copyright (c) University of Cambridge 1995 - 201
8
*/
/* See the file NOTICE for conditions of use and distribution. */
/* Transport shim for dkim signing */
/* 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)
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;
{
/* 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
/* 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));
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() ? */
/*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. */
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;
{
ssize_t copied = 0;
@@
-75,9
+83,9
@@
else
while (sread)
{
while (sread)
{
-#if
def SUPPORT
_TLS
- wwritten = tls_out.active == out_fd
- ? tls_write(
FALSE
, p, sread, FALSE)
+#if
ndef 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);
: write(out_fd, CS p, sread);
#else
wwritten = write(out_fd, CS p, sread);
@@
-116,9
+124,10
@@
dkt_direct(transport_ctx * tctx, struct ob_dkim * dkim,
{
int save_fd = tctx->u.fd;
int save_options = tctx->options;
{
int save_fd = tctx->u.fd;
int save_options = tctx->options;
-BOOL save_wireformat = spool_file_wireformat;
-uschar * hdrs, * dkim_signature;
-int siglen = 0, hsize;
+BOOL save_wireformat = f.spool_file_wireformat;
+uschar * hdrs;
+gstring * dkim_signature;
+int hsize;
const uschar * errstr;
BOOL rc;
const uschar * errstr;
BOOL rc;
@@
-132,8
+141,8
@@
tctx->options = tctx->options & ~(topt_end_dot | topt_use_bdat)
| topt_output_string | topt_no_body;
rc = transport_write_message(tctx, 0);
| topt_output_string | topt_no_body;
rc = transport_write_message(tctx, 0);
-hdrs =
tctx->u.msg
;
-h
drs[hsize = tctx->msg_ptr] = '\0'
;
+hdrs =
string_from_gstring(tctx->u.msg)
;
+h
size = tctx->u.msg->ptr
;
tctx->u.fd = save_fd;
tctx->options = save_options;
tctx->u.fd = save_fd;
tctx->options = save_options;
@@
-141,16
+150,33
@@
if (!rc) return FALSE;
/* Get signatures for headers plus spool data file */
/* 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. */
-if ((dkim_signature = dkim_exim_sign(deliver_datafile, SPOOL_DATA_START_OFFSET,
+dkim->dot_stuffed = f.spool_file_wireformat;
+if (!(dkim_signature = dkim_exim_sign(deliver_datafile, SPOOL_DATA_START_OFFSET,
hdrs, dkim, &errstr)))
hdrs, dkim, &errstr)))
- siglen = Ustrlen(dkim_signature);
-else if (!(rc = dkt_sign_fail(dkim, &errno)))
+ if (!(rc = dkt_sign_fail(dkim, &errno)))
+ {
+ *err = errstr;
+ return FALSE;
+ }
+
+#ifdef EXPERIMENTAL_ARC
+if (dkim->arc_signspec) /* Prepend ARC headers */
{
{
- *err = errstr;
- return FALSE;
+ 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
/* 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
@@
-160,13
+186,17
@@
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;
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);
transport_write_reset(0);
-if ( siglen > 0 && !write_chunk(tctx, dkim_signature, siglen)
- || !write_chunk(tctx, hdrs, hsize))
+if ( ( dkim_signature
+ && dkim_signature->ptr > 0
+ && !write_chunk(tctx, dkim_signature->s, dkim_signature->ptr)
+ )
+ || !write_chunk(tctx, hdrs, hsize)
+ )
return FALSE;
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)))
tctx->options = save_options | topt_no_headers | topt_continuation;
if (!(transport_write_message(tctx, 0)))
@@
-199,8
+229,9
@@
dkt_via_kfile(transport_ctx * tctx, struct ob_dkim * dkim, const uschar ** err)
int dkim_fd;
int save_errno = 0;
BOOL rc;
int dkim_fd;
int save_errno = 0;
BOOL rc;
-uschar * dkim_spool_name, * dkim_signature;
-int sread = 0, wwritten = 0, siglen = 0, options;
+uschar * dkim_spool_name;
+gstring * dkim_signature;
+int options, dlen;
off_t k_file_size;
const uschar * errstr;
off_t k_file_size;
const uschar * errstr;
@@
-240,16
+271,35
@@
if (!rc)
goto CLEANUP;
}
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);
dkim->dot_stuffed = !!(options & topt_end_dot);
-if ((dkim_signature = dkim_exim_sign(dkim_fd, 0, NULL, dkim, &errstr)))
- siglen = Ustrlen(dkim_signature);
-else if (!(rc = dkt_sign_fail(dkim, &save_errno)))
+if (!(dkim_signature = dkim_exim_sign(dkim_fd, 0, NULL, dkim, &errstr)))
{
{
- *err = errstr;
- goto CLEANUP;
+ dlen = 0;
+ if (!(rc = dkt_sign_fail(dkim, &save_errno)))
+ {
+ *err = errstr;
+ goto CLEANUP;
+ }
}
}
+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)
#ifndef OS_SENDFILE
if (options & topt_use_bdat)
@@
-266,27
+316,33
@@
if (options & topt_use_bdat)
MAIL & RCPT commands flushed, then reap the responses so we can
error out on RCPT rejects before sending megabytes. */
MAIL & RCPT commands flushed, then reap the responses so we can
error out on RCPT rejects before sending megabytes. */
- if (siglen + k_file_size > DELIVER_OUT_BUFFER_SIZE && siglen > 0)
+ if ( dlen + k_file_size > DELIVER_OUT_BUFFER_SIZE
+ && dlen > 0)
{
{
- if ( tctx->chunk_cb(tctx, siglen, 0) != OK
- || !transport_write_block(tctx, dkim_signature, siglen, FALSE)
+ if ( tctx->chunk_cb(tctx, dlen, 0) != OK
+ || !transport_write_block(tctx,
+ dkim_signature->s, dlen, FALSE)
|| tctx->chunk_cb(tctx, 0, tc_reap_prev) != OK
)
goto err;
|| tctx->chunk_cb(tctx, 0, tc_reap_prev) != OK
)
goto err;
-
sig
len = 0;
+
d
len = 0;
}
/* Send the BDAT command for the entire message, as a single LAST-marked
chunk. */
}
/* Send the BDAT command for the entire message, as a single LAST-marked
chunk. */
- if (tctx->chunk_cb(tctx,
sig
len + k_file_size, tc_chunk_last) != OK)
+ if (tctx->chunk_cb(tctx,
d
len + k_file_size, tc_chunk_last) != OK)
goto err;
}
goto err;
}
-if(
siglen > 0 && !transport_write_block(tctx, dkim_signature, sig
len, TRUE))
+if(
dlen > 0 && !transport_write_block(tctx, dkim_signature->s, d
len, TRUE))
goto err;
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;
{
save_errno = errno;
rc = FALSE;
@@
-328,7
+384,8
@@
dkim_transport_write_message(transport_ctx * tctx,
{
/* If we can't sign, just call the original function. */
{
/* 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
return transport_write_message(tctx, 0);
/* If there is no filter command set up, construct the message and calculate