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
Fix build with older GnuTLS, redux
[exim.git]
/
src
/
src
/
dkim_transport.c
diff --git
a/src/src/dkim_transport.c
b/src/src/dkim_transport.c
index 882fc877296bb7b45eba57b431430f8a154ea0b8..8ce18c818186ce53ccd9ca12dd5adf4ad757b678 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 */
@@
-12,10
+12,6
@@
#ifndef DISABLE_DKIM /* rest of file */
#ifndef DISABLE_DKIM /* rest of file */
-#ifdef HAVE_LINUX_SENDFILE
-# include <sys/sendfile.h>
-#endif
-
static BOOL
dkt_sign_fail(struct ob_dkim * dkim, int * errp)
static BOOL
dkt_sign_fail(struct ob_dkim * dkim, int * errp)
@@
-41,23
+37,31
@@
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() ? */
-#ifdef
HAVE_LINUX
_SENDFILE
+#ifdef
OS
_SENDFILE
/* We can use sendfile() to shove the file contents
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. */
/* We can use sendfile() to shove the file contents
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;
while(copied >= 0 && off < size)
{
ssize_t copied = 0;
while(copied >= 0 && off < size)
- copied = sendfile(out_fd, in_fd, &off, size - off);
+ copied =
os_
sendfile(out_fd, in_fd, &off, size - off);
if (copied < 0)
return FALSE;
}
if (copied < 0)
return FALSE;
}
@@
-80,8
+84,8
@@
else
while (sread)
{
#ifdef SUPPORT_TLS
while (sread)
{
#ifdef SUPPORT_TLS
- wwritten = tls_out.active == out_fd
- ? tls_write(
FALSE, p, sread
)
+ 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);
@@
-120,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;
@@
-136,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;
@@
-145,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
@@
-164,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)))
@@
-203,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;
@@
-244,18
+271,37
@@
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;
-#ifndef HAVE_LINUX_SENDFILE
+#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
if ((k_file_size = lseek(dkim_fd, 0, SEEK_END)) < 0)
if (options & topt_use_bdat)
#endif
if ((k_file_size = lseek(dkim_fd, 0, SEEK_END)) < 0)
@@
-270,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;
@@
-332,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