Gitweb:
https://git.exim.org/exim.git/commitdiff/9b604221c5e94f8146f48e47a76865c11eedb7a1
Commit: 9b604221c5e94f8146f48e47a76865c11eedb7a1
Parent: 23e95e18a9b2e5e2cfbd2e3548c0107edb4f92a8
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Fri Sep 6 12:29:23 2024 +0100
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Fri Sep 6 12:31:18 2024 +0100
arc dynamic module
---
doc/doc-txt/NewStuff | 6 +-
doc/doc-txt/experimental-spec.txt | 2 +
src/OS/Makefile-Base | 6 +-
src/scripts/Configure-Makefile | 2 +-
src/scripts/MakeLinks | 3 +-
src/src/acl.c | 67 ++++++---
src/src/config.h.defaults | 1 +
src/src/drtables.c | 13 +-
src/src/exim.c | 3 -
src/src/exim.h | 3 +
src/src/expand.c | 11 +-
src/src/functions.h | 16 --
src/src/globals.c | 8 -
src/src/globals.h | 7 -
src/src/miscmods/Makefile | 1 +
src/src/{ => miscmods}/arc.c | 237 ++++++++++++++++++------------
src/src/miscmods/{spf_api.h => arc_api.h} | 13 +-
src/src/miscmods/dkim_transport.c | 40 +++--
src/src/miscmods/dmarc.c | 27 +++-
src/src/miscmods/pdkim/pdkim.c | 32 ++--
src/src/miscmods/spf_api.h | 8 +-
src/src/receive.c | 11 +-
src/src/smtp_in.c | 5 +-
src/src/transports/smtp.c | 37 ++---
24 files changed, 333 insertions(+), 226 deletions(-)
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 1189ce3f3..5220408e8 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -14,9 +14,9 @@ Version 4.98
3. Events smtp:fail:protocol and smtp:fail:syntax
- 4. JSON and LDAP lookup support, SPF, DKIM and DMARC support, all the router
- and authenticator drivers, and all the transport drivers except smtp, can
- now be built as loadable modules
+ 4. JSON and LDAP lookup support, SPF, DKIM, DMARC and ARC support, all the
+ router and authenticator drivers, and all the transport drivers except
+ smtp, can now be built as loadable modules
Version 4.98
------------
diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt
index 56ee10f82..a73007700 100644
--- a/doc/doc-txt/experimental-spec.txt
+++ b/doc/doc-txt/experimental-spec.txt
@@ -498,6 +498,8 @@ Enable using EXPERIMENTAL_ARC=yes in your Local/Makefile.
You must also have DKIM present (not disabled), and you very likely
want to have SPF enabled.
+It is possible to build as a dynamic-load module: set also SUPPORT_ARC=2.
+
Verification
--
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base
index 12319967e..857c44776 100644
--- a/src/OS/Makefile-Base
+++ b/src/OS/Makefile-Base
@@ -495,8 +495,7 @@ transport-filter.pl: config ../src/transport-filter.src
# are thrown away by the linker.
OBJ_WITH_CONTENT_SCAN = malware.o mime.o regex.o spam.o spool_mbox.o
-OBJ_EXPERIMENTAL = arc.o \
- bmi_spam.o \
+OBJ_EXPERIMENTAL = bmi_spam.o \
dane.o \
dcc.o \
imap_utf7.o \
@@ -685,6 +684,7 @@ HDRS = blob.h \
hintsdb/hints_tdb.h \
local_scan.h \
macros.h \
+ miscmods/arc_api.h \
miscmods/dkim_api.h \
miscmods/dmarc_api.h \
miscmods/spf_api.h \
@@ -707,6 +707,7 @@ PHDRS = ../config.h \
../hintsdb/hints_tdb.h \
../local_scan.h \
../macros.h \
+ ../miscmods/arc_api.h \
../miscmods/dkim_api.h \
../miscmods/dmarc_api.h \
../miscmods/spf_api.h \
@@ -900,7 +901,6 @@ spool_mbox.o: $(HDRS) spool_mbox.c
# Dependencies for EXPERIMENTAL_* modules
-arc.o: $(HDRS) miscmods/pdkim.h arc.c
bmi_spam.o: $(HDRS) bmi_spam.c
dane.o: $(HDRS) dane.c dane-openssl.c
dcc.o: $(HDRS) dcc.h dcc.c
diff --git a/src/scripts/Configure-Makefile b/src/scripts/Configure-Makefile
index 12f0ddd9c..1eb79a291 100755
--- a/src/scripts/Configure-Makefile
+++ b/src/scripts/Configure-Makefile
@@ -311,7 +311,7 @@ done <<-END
routers ROUTER ACCEPT DNSLOOKUP IPLITERAL IPLOOKUP MANUALROUTE QUERYPROGRAM REDIRECT
transports TRANSPORT APPENDFILE AUTOREPLY LMTP PIPE QUEUEFILE SMTP
auths AUTH CRAM_MD5 CYRUS_SASL DOVECOT EXTERNAL GSASL HEIMDAL_GSSAPI PLAINTEXT SPA TLS
- miscmods SUPPORT _DKIM DMARC SPF
+ miscmods SUPPORT ARC _DKIM DMARC SPF
END
# See if there is a definition of EXIM_PERL in what we have built so far.
diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks
index a6521a95e..481f36fe3 100755
--- a/src/scripts/MakeLinks
+++ b/src/scripts/MakeLinks
@@ -97,6 +97,7 @@ mkdir $d
cd $d
# Makefile is generated
for f in dummy.c \
+ arc.c arc_api.h \
dkim.c dkim_transport.c dkim.h dkim_api.h \
pdkim/crypt_ver.h pdkim/pdkim.c pdkim/pdkim.h \
pdkim/pdkim_hash.h pdkim/signing.c pdkim/signing.h \
@@ -149,7 +150,7 @@ do
done
# EXPERIMENTAL_*
-for f in arc.c bmi_spam.c bmi_spam.h dcc.c dcc.h dane.c dane-openssl.c \
+for f in bmi_spam.c bmi_spam.h dcc.c dcc.h dane.c dane-openssl.c \
danessl.h imap_utf7.c utf8.c xclient.c
do
ln -s ../src/$f $f
diff --git a/src/src/acl.c b/src/src/acl.c
index 878278313..18d892ec5 100644
--- a/src/src/acl.c
+++ b/src/src/acl.c
@@ -207,9 +207,17 @@ static condition_def conditions[] = {
[ACLC_DELAY] = { US"delay", ACD_EXP | ACD_MOD,
FORBIDDEN(ACL_BIT_NOTQUIT) },
#ifndef DISABLE_DKIM
- [ACLC_DKIM_SIGNER] = { US"dkim_signers", ACD_EXP,
+ [ACLC_DKIM_SIGNER] = { US"dkim_signers",
+# if SUPPORT_DKIM==2
+ ACD_LOAD |
+# endif
+ ACD_EXP,
PERMITTED(ACL_BIT_DKIM) },
- [ACLC_DKIM_STATUS] = { US"dkim_status", ACD_EXP,
+ [ACLC_DKIM_STATUS] = { US"dkim_status",
+# if SUPPORT_DKIM==2
+ ACD_LOAD |
+# endif
+ ACD_EXP,
PERMITTED(ACL_BIT_DKIM | ACL_BIT_DATA | ACL_BIT_MIME
# ifndef DISABLE_PRDR
| ACL_BIT_PRDR
@@ -394,6 +402,7 @@ for (condition_def * c = conditions; c < conditions + nelem(conditions); c++)
}
#endif
+/******************************************************************************/
#ifndef MACRO_PREDEF
@@ -410,20 +419,31 @@ typedef struct condition_module {
# if SUPPORT_SPF==2
static int spf_condx[] = { ACLC_SPF, ACLC_SPF_GUESS, -1 };
# endif
+# if SUPPORT_DKIM==2
+static int dkim_condx[] = { ACLC_DKIM_SIGNER, ACLC_DKIM_STATUS, -1 };
+# endif
# if SUPPORT_DMARC==2
static int dmarc_condx[] = { ACLC_DMARC_STATUS, -1 };
# endif
+/* These are modules which can be loaded on seeing an ACL condition
+during readconf, The "arc" module is handled by custom coding. */
+
static condition_module condition_modules[] = {
# if SUPPORT_SPF==2
{.mod_name = US"spf", .conditions = spf_condx},
# endif
-# if SUPPORT_SPF==2
+# if SUPPORT_DKIM==2
+ {.mod_name = US"dkim", .conditions = dkim_condx},
+# endif
+# if SUPPORT_DMARC==2
{.mod_name = US"dmarc", .conditions = dmarc_condx},
# endif
};
-# endif
+# endif /*LOOKUP_MODULE_DIR*/
+
+/****************************/
/* Return values from decode_control() */
@@ -933,7 +953,7 @@ while ((s = (*func)()))
if ((v = acl_checkname(name, verbs, nelem(verbs))) < 0)
{
- if (!this)
+ if (!this) /* not handling a verb right now */
{
*error = string_sprintf("unknown ACL verb \"%s\" in \"%s\"", name,
saveline);
@@ -1002,6 +1022,9 @@ while ((s = (*func)()))
condition_module * cm;
uschar * s = NULL;
+ /* Over the list of modules we support, check the list of ACL conditions
+ each supports. This assumes no duplicates. */
+
for (cm = condition_modules;
cm < condition_modules + nelem(condition_modules); cm++)
for (const int * cond = cm->conditions; *cond != -1; cond++)
@@ -1022,7 +1045,21 @@ while ((s = (*func)()))
return NULL;
}
}
-#endif
+# ifdef EXPERIMENTAL_ARC
+ else if (c == ACLC_VERIFY) /* Special handling for verify=arc; */
+ { /* not invented a more general method yet- flag in verify_type_list? */
+ const uschar * t = s;
+ uschar * e;
+ if ( *t++ == '=' && Uskip_whitespace(&t) && Ustrncmp(t, "arc", 3) == 0
+ && !misc_mod_find(US"arc", &e))
+ {
+ *error = string_sprintf("ACL error: failed to find module for '%s': %s",
+ conditions[c].name, e);
+ return NULL;
+ }
+ }
+# endif
+#endif /*LOOKUP_MODULE_DIR*/
cond = store_get(sizeof(acl_condition_block), GET_UNTAINTED);
cond->next = NULL;
@@ -1876,19 +1913,11 @@ switch(vp->value)
#ifdef EXPERIMENTAL_ARC
case VERIFY_ARC:
- { /* Do Authenticated Received Chain checks in a separate function. */
- const uschar * condlist = CUS string_nextinlist(&list, &sep, NULL, 0);
- int csep = 0;
- uschar * cond;
-
- if (!(arc_state = acl_verify_arc())) return DEFER;
- DEBUG(D_acl) debug_printf_indent("ARC verify result %s %s%s%s\n", arc_state,
- arc_state_reason ? "(":"", arc_state_reason, arc_state_reason ? ")":"");
-
- if (!condlist) condlist = US"none:pass";
- while ((cond = string_nextinlist(&condlist, &csep, NULL, 0)))
- if (Ustrcmp(arc_state, cond) == 0) return OK;
- return FAIL;
+ {
+ const misc_module_info * mi = misc_mod_findonly(US"arc");
+ typedef int (*fn_t)(const uschar *);
+ if (mi) return (((fn_t *) mi->functions)[ARC_VERIFY])
+ (CUS string_nextinlist(&list, &sep, NULL, 0));
}
#endif
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index d602886a0..20a288d66 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -169,6 +169,7 @@ Do not put spaces between # and the 'define'.
/* Required to support dynamic-module build */
#define SUPPORT_DKIM
+#define SUPPORT_ARC
#define SYSLOG_LOG_PID
#define SYSLOG_LONG_LINES
diff --git a/src/src/drtables.c b/src/src/drtables.c
index 61ced3e6a..32765aedc 100644
--- a/src/src/drtables.c
+++ b/src/src/drtables.c
@@ -441,6 +441,7 @@ if (mi->init && mi->init(mi))
}
else DEBUG(D_any)
debug_printf_indent("module init call failed for %s\n", mi->name);
+/* fprintf(stderr,"misc_mod_add: added %s\n", mi->name); */
}
@@ -746,6 +747,9 @@ extern misc_module_info dmarc_module_info;
#if defined(SUPPORT_SPF) && SUPPORT_SPF!=2
extern misc_module_info spf_module_info;
#endif
+#if defined(EXPERIMENTAL_ARC) && (!defined(SUPPORT_ARC) || SUPPORT_ARC!=2)
+extern misc_module_info arc_module_info;
+#endif
void
init_misc_mod_list(void)
@@ -755,14 +759,17 @@ if (onetime) return;
onetime = TRUE;
#if !defined(DISABLE_DKIM) && (!defined(SUPPORT_DKIM) || SUPPORT_DKIM!=2)
-misc_mod_add(&dkim_module_info);
+ misc_mod_add(&dkim_module_info);
#endif
#if defined(SUPPORT_SPF) && SUPPORT_SPF!=2
-misc_mod_add(&spf_module_info);
+ misc_mod_add(&spf_module_info);
#endif
#if defined(SUPPORT_DMARC) && SUPPORT_DMARC!=2
/* dmarc depends on spf so this add must go after, for the both-static case */
-misc_mod_add(&dmarc_module_info);
+ misc_mod_add(&dmarc_module_info);
+#endif
+#if defined(EXPERIMENTAL_ARC) && (!defined(SUPPORT_ARC) || SUPPORT_ARC!=2)
+ misc_mod_add(&arc_module_info);
#endif
}
diff --git a/src/src/exim.c b/src/src/exim.c
index ca98e25de..2349260df 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -4211,9 +4211,6 @@ is equivalent to the ability to modify a setuid binary!
This needs to happen before we read the main configuration. */
init_lookup_list();
init_misc_mod_list();
-#ifdef EXPERIMENTAL_ARC
-arc_init(); /*XXX temporary, until we do an arc module */
-#endif
/*XXX this excrescence could move to the testsuite standard config setup file */
#ifdef SUPPORT_I18N
diff --git a/src/src/exim.h b/src/src/exim.h
index 8260dc75f..f5043aea9 100644
--- a/src/src/exim.h
+++ b/src/src/exim.h
@@ -555,6 +555,9 @@ config.h, mytypes.h, and store.h, so we don't need to mention them explicitly.
# include "miscmods/dmarc_api.h"
# include <opendmarc/dmarc.h>
#endif
+#ifdef EXPERIMENTAL_ARC
+# include "miscmods/arc_api.h"
+#endif
/* The following stuff must follow the inclusion of config.h because it
requires various things that are set therein. */
diff --git a/src/src/expand.c b/src/src/expand.c
index 02680771f..a41ba98cf 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -454,10 +454,10 @@ static var_entry var_table[] = {
{ "address_file", vtype_stringptr, &address_file },
{ "address_pipe", vtype_stringptr, &address_pipe },
#ifdef EXPERIMENTAL_ARC
- { "arc_domains", vtype_string_func, (void *) &fn_arc_domains },
- { "arc_oldest_pass", vtype_int, &arc_oldest_pass },
- { "arc_state", vtype_stringptr, &arc_state },
- { "arc_state_reason", vtype_stringptr, &arc_state_reason },
+ { "arc_domains", vtype_module, US"arc" },
+ { "arc_oldest_pass", vtype_module, US"arc" },
+ { "arc_state", vtype_module, US"arc" },
+ { "arc_state_reason", vtype_module, US"arc" },
#endif
{ "authenticated_fail_id",vtype_stringptr, &authenticated_fail_id },
{ "authenticated_id", vtype_stringptr, &authenticated_id },
@@ -4890,9 +4890,6 @@ while (*s)
yield = authres_iprev(yield);
yield = authres_smtpauth(yield);
yield = misc_mod_authres(yield);
-#ifdef EXPERIMENTAL_ARC
- yield = authres_arc(yield);
-#endif
break;
}
diff --git a/src/src/functions.h b/src/src/functions.h
index 4f4e615ca..deec54590 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -1,4 +1,3 @@
-extern BOOL arc_init(void);
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
@@ -111,18 +110,6 @@ extern void acl_var_write(uschar *, uschar *, void *);
extern void add_driver_info(driver_info **, const driver_info *, size_t);
-#ifdef EXPERIMENTAL_ARC
-# ifdef SUPPORT_DMARC
-extern gstring *arc_dmarc_hist_append(gstring *);
-# endif
-extern void *arc_ams_setup_sign_bodyhash(void);
-extern const uschar *arc_header_feed(gstring *, BOOL);
-extern gstring *arc_sign(const uschar *, gstring *, uschar **);
-extern void arc_sign_init(void);
-extern const uschar *acl_verify_arc(void);
-extern uschar * fn_arc_domains(void);
-#endif
-
extern void assert_no_variables(void *, int, const char *, int);
extern int auth_call_pam(const uschar *, uschar **);
extern int auth_call_pwcheck(uschar *, uschar **);
@@ -142,9 +129,6 @@ extern int auth_read_input(const uschar *);
extern gstring * auth_show_supported(gstring *);
extern uschar *authenticator_current_name(void);
-#ifdef EXPERIMENTAL_ARC
-extern gstring *authres_arc(gstring *);
-#endif
extern gstring *authres_smtpauth(gstring *);
extern uschar *b64encode(const uschar *, int);
diff --git a/src/src/globals.c b/src/src/globals.c
index 6fae1582f..c65ddf413 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -615,14 +615,6 @@ tree_node *addresslist_anchor = NULL;
int addresslist_count = 0;
gid_t *admin_groups = NULL;
-#ifdef EXPERIMENTAL_ARC
-struct arc_set *arc_received = NULL;
-int arc_received_instance = 0;
-int arc_oldest_pass = 0;
-const uschar *arc_state = NULL;
-const uschar *arc_state_reason = NULL;
-#endif
-
uschar *authenticated_fail_id = NULL;
uschar *authenticated_id = NULL;
uschar *authenticated_sender = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index 1f03cefee..2f2f023e3 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -360,13 +360,6 @@ extern int addresslist_count; /* Number defined */
extern gid_t *admin_groups; /* List of admin groups */
extern BOOL allow_domain_literals; /* As it says */
extern BOOL allow_mx_to_ip; /* Allow MX records to -> ip address */
-#ifdef EXPERIMENTAL_ARC
-extern struct arc_set *arc_received; /* highest ARC instance evaluation struct */
-extern int arc_received_instance; /* highest ARC instance number in headers */
-extern int arc_oldest_pass; /* lowest passing instance number in headers */
-extern const uschar *arc_state; /* verification state */
-extern const uschar *arc_state_reason;
-#endif
extern BOOL allow_utf8_domains; /* For experimenting */
extern uschar *authenticated_fail_id; /* ID that failed authentication */
extern uschar *authenticated_id; /* ID that was authenticated */
diff --git a/src/src/miscmods/Makefile b/src/src/miscmods/Makefile
index 3013a88da..64a66276f 100644
--- a/src/src/miscmods/Makefile
+++ b/src/src/miscmods/Makefile
@@ -31,6 +31,7 @@ miscmods.a: $(OBJ)
# Note that the sources from pdkim/ are linked into the build.../miscmods/ dir
# by scripts/Makelinks.
+arc.o arc.so: $(HDRS) pdkim.h arc.c
dkim.o dkim.so: $(HDRS) dkim.h dkim.c dkim_transport.c \
crypt_ver.h pdkim.h pdkim_hash.h pdkim.c \
signing.h signing.c
diff --git a/src/src/arc.c b/src/src/miscmods/arc.c
similarity index 92%
rename from src/src/arc.c
rename to src/src/miscmods/arc.c
index a065ca8e3..db546e1ab 100644
--- a/src/src/arc.c
+++ b/src/src/miscmods/arc.c
@@ -8,20 +8,25 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
-#include "exim.h"
+#include "../exim.h"
#if defined EXPERIMENTAL_ARC
# if defined DISABLE_DKIM
# error DKIM must also be enabled for ARC
# else
-# include "functions.h"
-# include "miscmods/pdkim.h"
-# include "miscmods/signing.h"
+# include "../functions.h"
+# include "pdkim.h"
+# include "signing.h"
-# ifdef SUPPORT_DMARC
-# include "miscmods/dmarc.h"
-# endif
+/* Globals */
+struct arc_set *arc_received = NULL; /* highest ARC instance eval struct */
+int arc_received_instance = 0; /* highest ARC instance num in hdrs */
+int arc_oldest_pass = 0; /* lowest passing inst num in hdrs */
+const uschar *arc_state = NULL; /* verification state */
+const uschar *arc_state_reason = NULL;
+
+/******************************************************************************/
#define ARC_SIGN_OPT_TSTAMP BIT(0)
#define ARC_SIGN_OPT_EXPIRE BIT(1)
@@ -134,20 +139,26 @@ arc_parse_line() gathering only the 'i' tag (instance) information.
/******************************************************************************/
/* We need a module init function, to check on the dkim module being present
-(and we may as well stack it's modinfo ptr)
-
-For now (until we do an arc module), called from exim.c main().
+(and we may as well stash it's modinfo ptr)
*/
-BOOL
-arc_init(void)
+
+static BOOL
+arc_init(void * dummy)
{
uschar * errstr = NULL;
if ((arc_dkim_mod_info = misc_mod_find(US"dkim", &errstr)))
return TRUE;
-log_write(0, LOG_MAIN|LOG_PANIC, "arc: %s", errstr);
+log_write(0, LOG_MAIN, "arc: %s", errstr);
return FALSE;
}
+static void
+arc_smtp_reset(void)
+{
+arc_state = arc_state_reason = NULL;
+arc_received_instance = 0;
+}
+
/******************************************************************************/
@@ -708,11 +719,7 @@ blob * pubkey;
const uschar * hashes;
const uschar * srvtype =
(((fn_t *) arc_dkim_mod_info->functions)[DKIM_DNS_PUBKEY])
- (string_sprintf("%.*s._domainkey.%.*s",
- (int)al->s.len, al->s.data, (int)al->d.len, al->d.data),
- &pubkey, &hashes);
-
-/*XXX do we need a blob-string printf %handler? Other types of blob? */
+ (string_sprintf("%b._domainkey.%b", &al->s, &al->d), &pubkey, &hashes);
if (!srvtype)
{ *errstr = US"pubkey dns lookup fail"; return NULL; }
@@ -734,8 +741,7 @@ if (hashes)
if (Ustrncmp(ele, al->a_hash.data, al->a_hash.len) == 0) break;
if (!ele)
{
- DEBUG(D_acl) debug_printf("pubkey h=%s vs sig a=%.*s\n",
- hashes, (int)al->a.len, al->a.data);
+ DEBUG(D_acl) debug_printf("pubkey h=%s vs sig a=%b\n", hashes, &al->a);
*errstr = US"no usable sig for this pubkey hash list";
return NULL;
}
@@ -886,10 +892,9 @@ if (!(b = arc_ams_setup_vfy_bodyhash(ams)))
DEBUG(D_acl)
{
debug_printf("ARC i=%d AMS Body bytes hashed: %lu\n"
- " Body %.*s computed: ",
+ " Body %b computed: %.*H\n",
as->instance, b->signed_body_bytes,
- (int)ams->a_hash.len, ams->a_hash.data);
- debug_printf("%.*H\n", b->bh.len, b->bh.data);
+ &ams->a_hash, b->bh.len, b->bh.data);
}
/* We know the bh-tag blob is of a nul-term string, so safe as a string */
@@ -1072,7 +1077,6 @@ for (as2 = ctx->arcset_chain;
al = as2->hdr_aar;
if (!(s = al->relaxed))
- /*XXX dkim module */
al->relaxed = s = arc_relax_header_n(al->complete->text,
al->complete->slen, TRUE);
len = Ustrlen(s);
@@ -1081,7 +1085,6 @@ for (as2 = ctx->arcset_chain;
al = as2->hdr_ams;
if (!(s = al->relaxed))
- /*XXX dkim module */
al->relaxed = s = arc_relax_header_n(al->complete->text,
al->complete->slen, TRUE);
len = Ustrlen(s);
@@ -1090,11 +1093,9 @@ for (as2 = ctx->arcset_chain;
al = as2->hdr_as;
if (as2->instance == as->instance)
- /*XXX dkim module */
s = arc_relax_header_n(al->rawsig_no_b_val.data,
al->rawsig_no_b_val.len, FALSE);
else if (!(s = al->relaxed))
- /*XXX dkim module */
al->relaxed = s = arc_relax_header_n(al->complete->text,
al->complete->slen, TRUE);
len = Ustrlen(s);
@@ -1109,8 +1110,8 @@ for (as2 = ctx->arcset_chain;
exim_sha_finish(&hhash_ctx, &hhash_computed);
DEBUG(D_acl)
{
- debug_printf("ARC i=%d AS Header %.*s computed: ",
- as->instance, (int)hdr_as->a_hash.len, hdr_as->a_hash.data);
+ debug_printf("ARC i=%d AS Header %b computed: ",
+ as->instance, &hdr_as->a_hash);
debug_printf("%.*H\n", hhash_computed.len, hhash_computed.data);
}
@@ -1161,13 +1162,17 @@ return NULL;
/******************************************************************************/
/* Do ARC verification. Called from DATA ACL, on a verify = arc
-condition. No arguments; we are checking globals.
+condition. Set arc_state, and compare with given list of acceptable states.
+
+Arguments:
+ condlist list of resulta to test for OK/FAIL return;
+ NULL for default list
-Return: The ARC state, or NULL on error.
+Return: OK/FAIL, or DEFER on error
*/
-const uschar *
-acl_verify_arc(void)
+static int
+acl_verify_arc(const uschar * condlist)
{
const uschar * res;
@@ -1246,7 +1251,27 @@ if ((res = arc_verify_seals(&arc_verify_ctx)))
res = US"pass";
out:
- return res;
+ {
+ int csep = 0;
+ uschar * cond;
+
+ if (!(arc_state = res))
+ return DEFER;
+
+ DEBUG(D_acl) debug_printf_indent("ARC verify result %s %s%s%s\n", arc_state,
+ arc_state_reason ? "(":"", arc_state_reason, arc_state_reason ? ")":"");
+
+ if (!condlist) condlist = US"none:pass";
+ while ((cond = string_nextinlist(&condlist, &csep, NULL, 0)))
+ if (Ustrcmp(res, cond) == 0) return OK;
+ return FAIL;
+ }
+}
+
+static BOOL
+arc_is_pass(void)
+{
+return arc_state && Ustrcmp(arc_state, "pass") == 0;
}
/******************************************************************************/
@@ -1348,9 +1373,8 @@ arc_line * al = (arc_line *)(as+1);
header_line * h = (header_line *)(al+1);
g = string_catn(g, ARC_HDR_AAR, ARC_HDRLEN_AAR);
-g = string_fmt_append(g, " i=%d; %s; smtp.remote-ip=%s;\r\n\t",
- instance, identity, sender_host_address);
-g = string_catn(g, US ar->data, ar->len);
+g = string_fmt_append(g, " i=%d; %s; smtp.remote-ip=%s;\r\n\t%b",
+ instance, identity, sender_host_address, ar);
h->slen = g->ptr - aar_off;
h->text = g->s + aar_off;
@@ -1503,7 +1527,6 @@ for(col = 3; rheaders; rheaders = rheaders->prev)
/* Accumulate header for hashing/signing */
hdata = string_cat(hdata,
- /*XXX dkim module */
arc_relax_header_n(htext, rheaders->h->slen, TRUE)); /*XXX hardwired */
break;
}
@@ -1518,7 +1541,6 @@ g = string_catn(g, US";\r\n\tb=;", 7);
/* Include the pseudo-header in the accumulation */
-/*XXX dkim module */
s = arc_relax_header_n(g->s + ams_off, g->ptr - ams_off, FALSE);
hdata = string_cat(hdata, s);
@@ -1633,17 +1655,14 @@ for (arc_set * as = Ustrcmp(status, US"fail") == 0
badline_str = US"aar";
if (!(l = as->hdr_aar)) goto badline;
h = l->complete;
- /*XXX dkim module */
hdata = string_cat(hdata, arc_relax_header_n(h->text, h->slen, TRUE));
badline_str = US"ams";
if (!(l = as->hdr_ams)) goto badline;
h = l->complete;
- /*XXX dkim module */
hdata = string_cat(hdata, arc_relax_header_n(h->text, h->slen, TRUE));
badline_str = US"as";
if (!(l = as->hdr_as)) goto badline;
h = l->complete;
- /*XXX dkim module */
hdata = string_cat(hdata, arc_relax_header_n(h->text, h->slen, !!as->next));
}
@@ -1670,11 +1689,7 @@ badline:
/**************************************/
-/*XXX not static currently as the smtp tpt calls us */
-/* Really returns pdkim_bodyhash* - but there's an ordering
-problem for functions.h so call it void* */
-
-void *
+static pdkim_bodyhash *
arc_ams_setup_sign_bodyhash(void)
{
blob canon = {.data = US"relaxed", .len = 7}; /*XXX hardwired */
@@ -1687,11 +1702,18 @@ return arc_set_bodyhash(TRUE, &canon, &hash, -1);
-void
+/* Module API: initilise, and set up a bodyhash for AMS */
+
+static void
arc_sign_init(void)
{
+blob canon = {.data = US"relaxed", .len = 7}; /*XXX hardwired */
+blob hash = {.data = US"sha256", .len = 6}; /*XXX hardwired */
+
memset(&arc_sign_ctx, 0, sizeof(arc_sign_ctx));
headers_rlist = NULL;
+
+(void) arc_ams_setup_sign_bodyhash();
}
@@ -1735,7 +1757,9 @@ return TRUE;
-/* ARC signing. Called from the smtp transport, if the arc_sign option is set.
+/* Module API: ARC signing.
+
+Called from the smtp transport, if the arc_sign option is set.
The dkim_exim_sign() function has already been called, so will have hashed the
message body for us so long as we requested a hash previously.
@@ -1751,7 +1775,7 @@ Return value
but not the plainheaders.
*/
-gstring *
+static gstring *
arc_sign(const uschar * signspec, gstring * sigheaders, uschar ** errstr)
{
const uschar * identity, * selector, * privkey, * opts, * s;
@@ -1868,10 +1892,7 @@ g = arc_sign_append_aar(g, &arc_sign_ctx, identity, instance, &ar);
- ? oversigning?
- Covers the data
- we must have requested a suitable bodyhash previously
-XXX so where was that done? I don't see it!
-XXX ah, ok - the smtp tpt calls arc_ams_setup_sign_bodyhash() directly, early
- -> should pref use a better named call to make the point, but that
- can wait until arc becomes a module
+ [done in arc_sign_init()]
*/
b = arc_ams_setup_sign_bodyhash();
@@ -1975,7 +1996,8 @@ badline:
-/* A header line has been identified by DKIM processing.
+/* Module API: A header line has been identified by DKIM processing;
+feed it to ARC processing.
Arguments:
g Header line
@@ -1985,7 +2007,7 @@ Return:
NULL for success, or an error string (probably unused)
*/
-const uschar *
+static const uschar *
arc_header_feed(gstring * g, BOOL is_vfy)
{
return is_vfy ? arc_header_vfy_feed(g) : arc_header_sign_feed(g);
@@ -1997,7 +2019,7 @@ return is_vfy ? arc_header_vfy_feed(g) : arc_header_sign_feed(g);
/* Construct the list of domains from the ARC chain after validation */
-uschar *
+const uschar *
fn_arc_domains(void)
{
arc_set * as;
@@ -2033,7 +2055,6 @@ authres_arc(gstring * g)
{
if (arc_state)
{
- arc_line * highest_ams;
int start = 0; /* Compiler quietening */
DEBUG(D_acl) start = gstring_length(g);
@@ -2043,11 +2064,10 @@ if (arc_state)
g = string_fmt_append(g, " (i=%d)", arc_received_instance);
if (arc_state_reason)
g = string_append(g, 3, US"(", arc_state_reason, US")");
- g = string_catn(g, US" header.s=", 10);
- highest_ams = arc_received->hdr_ams;
- g = string_catn(g, highest_ams->s.data, highest_ams->s.len);
- g = string_fmt_append(g, " arc.oldest-pass=%d", arc_oldest_pass);
+ g = string_fmt_append(g, " header.s=%b arc.oldest-pass=%d",
+ &arc_received->hdr_ams->s,
+ arc_oldest_pass);
if (sender_host_address)
g = string_append(g, 2, US" smtp.remote-ip=", sender_host_address);
@@ -2064,62 +2084,87 @@ return g;
# ifdef SUPPORT_DMARC
-/* Append a DMARC history record pair for ARC, to the given history set */
-gstring *
-arc_dmarc_hist_append(gstring * g)
+/* Module API: obtain ARC info for DMARC history.
+Arguments:
+ gp pointer for return of arcset info string
+Return:
+ status string, or NULL if none
+*/
+
+static const uschar *
+arc_arcset_string(gstring ** gp)
{
if (arc_state)
{
- BOOL first = TRUE;
- int i = Ustrcmp(arc_state, "pass") == 0 ? ARES_RESULT_PASS
- : Ustrcmp(arc_state, "fail") == 0 ? ARES_RESULT_FAIL
- : ARES_RESULT_UNKNOWN;
- g = string_fmt_append(g, "arc %d\n", i);
- g = string_fmt_append(g, "arc_policy %d json[",
- i == ARES_RESULT_PASS ? DMARC_ARC_POLICY_RESULT_PASS
- : i == ARES_RESULT_FAIL ? DMARC_ARC_POLICY_RESULT_FAIL
- : DMARC_ARC_POLICY_RESULT_UNUSED);
+ gstring * g = NULL;
+
/*XXX would we prefer this backwards? */
- for (arc_set * as = arc_verify_ctx.arcset_chain; as;
- as = as->next, first = FALSE)
+ for (arc_set * as = arc_verify_ctx.arcset_chain; as; as = as->next)
{
arc_line * line = as->hdr_as;
if (line)
{
- blob * d = &line->d;
- blob * s = &line->s;
-
- if (!first)
- g = string_catn(g, US",", 1);
-
- g = string_fmt_append(g, " (\"i\":%u," /*)*/
- " \"d\":\"%.*s\","
- " \"s\":\"%.*s\"",
- as->instance,
- d->data ? (int)d->len : 0, d->data && d->len ? d->data : US"",
- s->data ? (int)s->len : 0, s->data && s->len ? s->data : US""
- );
+ g = string_append_listele_fmt(g, ',', " (\"i\":%u" /*)*/
+ ", \"d\":\"%#b\""
+ ", \"s\":\"%#b\"",
+ as->instance, &line->d, &line->s);
+
if ((line = as->hdr_aar))
{
blob * ip = &line->ip;
if (ip->data && ip->len)
- g = string_fmt_append(g, ", \"ip\":\"%.*s\"", (int)ip->len, ip->data);
+ g = string_fmt_append(g, ", \"ip\":\"%#b\"", ip);
}
-
+ /*(*/
g = string_catn(g, US")", 1);
}
}
- g = string_catn(g, US" ]\n", 3);
+ *gp = g;
}
-else
- g = string_fmt_append(g, "arc %d\narc_policy %d json:[]\n",
- ARES_RESULT_UNKNOWN, DMARC_ARC_POLICY_RESULT_UNUSED);
-return g;
+return arc_state;
}
# endif
+/******************************************************************************/
+/* Module API */
+
+static void * arc_functions[] = {
+ [ARC_VERIFY] = acl_verify_arc,
+ [ARC_HEADER_FEED] = arc_header_feed,
+ [ARC_STATE_IS_PASS] = arc_is_pass,
+ [ARC_SIGN_INIT] = arc_sign_init,
+ [ARC_SIGN] = arc_sign,
+# ifdef SUPPORT_DMARC
+ [ARC_ARCSET_INFO] = arc_arcset_string,
+# endif
+};
+
+static var_entry arc_variables[] = {
+ { "arc_domains", vtype_string_func, (void *) &fn_arc_domains },
+ { "arc_oldest_pass", vtype_int, &arc_oldest_pass },
+ { "arc_state", vtype_stringptr, &arc_state },
+ { "arc_state_reason", vtype_stringptr, &arc_state_reason },
+};
+
+misc_module_info arc_module_info =
+{
+ .name = US"arc",
+# if SUPPORT_SPF==2
+ .dyn_magic = MISC_MODULE_MAGIC,
+# endif
+ .init = arc_init,
+ .smtp_reset = arc_smtp_reset,
+ .authres = authres_arc,
+
+ .functions = arc_functions,
+ .functions_count = nelem(arc_functions),
+
+ .variables = arc_variables,
+ .variables_count = nelem(arc_variables),
+};
+
# endif /* DISABLE_DKIM */
#endif /* EXPERIMENTAL_ARC */
/* vi: aw ai sw=2
diff --git a/src/src/miscmods/spf_api.h b/src/src/miscmods/arc_api.h
similarity index 65%
copy from src/src/miscmods/spf_api.h
copy to src/src/miscmods/arc_api.h
index 117a7ae6a..cf24a4cb3 100644
--- a/src/src/miscmods/spf_api.h
+++ b/src/src/miscmods/arc_api.h
@@ -6,13 +6,14 @@
/* See the file NOTICE for conditions of use and distribution. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* API definitions for the spf module */
+/* API definitions for the arcmodule */
/* Function table entry numbers */
-#define SPF_PROCESS 0
-#define SPF_GET_RESPONSE 2
-#define SPF_OPEN 3
-#define SPF_CLOSE 4
-#define SPF_FIND 5
+#define ARC_VERIFY 0
+#define ARC_HEADER_FEED 1
+#define ARC_STATE_IS_PASS 2
+#define ARC_SIGN_INIT 3
+#define ARC_SIGN 4
+#define ARC_ARCSET_INFO 5
diff --git a/src/src/miscmods/dkim_transport.c b/src/src/miscmods/dkim_transport.c
index 0500da2be..e2d1705e3 100644
--- a/src/src/miscmods/dkim_transport.c
+++ b/src/src/miscmods/dkim_transport.c
@@ -109,6 +109,32 @@ return TRUE;
+/* Prepend ARC-signing headers to given set of headers
+
+Arguments:
+ signspec Three-element colon-sep list: identity, selector, privkey.
+ Optional fourth element: comma-sep list of options.
+ Already expanded
+ sigheaders Any signature headers already generated, eg. by DKIM, or NULL
+ errstr Error string
+
+Return value
+ Set of headers to prepend to the message, including the supplied sigheaders
+ but not the plainheaders.
+*/
+
+static gstring *
+dkt_arc_sign(const uschar * signspec, gstring * sigheaders, uschar ** errstr_p)
+{
+const misc_module_info * mi = misc_mod_findonly(US"arc");
+typedef gstring * (*fn_t)(const uschar *, gstring *, uschar **);
+if (mi)
+ return (((fn_t *) mi->functions)[ARC_SIGN]) (signspec, sigheaders, errstr_p);
+*errstr_p = US"failed to find arc module";
+return NULL;
+}
+
+
/* This function is a wrapper around transport_write_message().
It is only called from the smtp transport if DKIM or Domainkeys support
@@ -153,11 +179,6 @@ if (!rc) return FALSE;
/* Get signatures for headers plus spool data file */
-#ifdef EXPERIMENTAL_ARC
-arc_sign_init(); /*XXX perhaps move this call back to the smtp tpt
- around where it currently calls arc_ams_setup_sign_bodyhash() ? */
-#endif
-
/* The dotstuffed status of the datafile depends on whether it was stored
in wireformat. */
@@ -174,7 +195,7 @@ if (!(dkim_signature = dkim_exim_sign(deliver_datafile,
if (dkim->arc_signspec) /* Prepend ARC headers */
{
uschar * e = NULL;
- if (!(dkim_signature = arc_sign(dkim->arc_signspec, dkim_signature, &e)))
+ if (!(dkim_signature = dkt_arc_sign(dkim->arc_signspec, dkim_signature, &e)))
{
*err = e;
return FALSE;
@@ -275,10 +296,6 @@ if (!rc)
goto CLEANUP;
}
-#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. */
@@ -299,7 +316,8 @@ else
#ifdef EXPERIMENTAL_ARC
if (dkim->arc_signspec) /* Prepend ARC headers */
{
- if (!(dkim_signature = arc_sign(dkim->arc_signspec, dkim_signature, USS err)))
+ if (!(dkim_signature = dkt_arc_sign(dkim->arc_signspec, dkim_signature,
+ USS err)))
goto CLEANUP;
dlen = dkim_signature->ptr;
}
diff --git a/src/src/miscmods/dmarc.c b/src/src/miscmods/dmarc.c
index d977d29fe..e192bda1b 100644
--- a/src/src/miscmods/dmarc.c
+++ b/src/src/miscmods/dmarc.c
@@ -360,7 +360,32 @@ g = string_fmt_append(g, "align_dkim %d\nalign_spf %d\naction %d\n",
#if DMARC_API >= 100400
# ifdef EXPERIMENTAL_ARC
-g = arc_dmarc_hist_append(g);
+ {
+ const misc_module_info * mi = misc_mod_findonly(US"arc");
+ const uschar * s;
+ gstring * g2 = NULL;
+ typedef const uschar * (*fn_t)(gstring **);
+
+ if (mi && (s = (((fn_t *) mi->functions)[ARC_ARCSET_INFO]) (&g2)))
+ {
+ int i = Ustrcmp(s, "pass") == 0 ? ARES_RESULT_PASS
+ : Ustrcmp(s, "fail") == 0 ? ARES_RESULT_FAIL
+ : ARES_RESULT_UNKNOWN;
+
+ g = string_fmt_append(g, "arc %d\n"
+ "arc_policy %d json[%#Y ]\n",
+ i,
+ i == ARES_RESULT_PASS ? DMARC_ARC_POLICY_RESULT_PASS
+ : i == ARES_RESULT_FAIL ? DMARC_ARC_POLICY_RESULT_FAIL
+ : DMARC_ARC_POLICY_RESULT_UNUSED,
+ g2
+ );
+ }
+ else
+ string_fmt_append(g, "arc %d\narc_policy %d json:[]\n",
+ ARES_RESULT_UNKNOWN, DMARC_ARC_POLICY_RESULT_UNUSED);
+ }
+
# else
g = string_fmt_append(g, "arc %d\narc_policy %d json:[]\n",
ARES_RESULT_UNKNOWN, DMARC_ARC_POLICY_RESULT_UNUSED);
diff --git a/src/src/miscmods/pdkim/pdkim.c b/src/src/miscmods/pdkim/pdkim.c
index cdbdfc5e0..7c2f34217 100644
--- a/src/src/miscmods/pdkim/pdkim.c
+++ b/src/src/miscmods/pdkim/pdkim.c
@@ -935,13 +935,19 @@ return;
static int
pdkim_header_complete(pdkim_ctx * ctx)
{
-if (ctx->cur_header->ptr > 1)
- gstring_trim_trailing(ctx->cur_header, '\r');
-(void) string_from_gstring(ctx->cur_header);
+gstring * g = ctx->cur_header;
+const misc_module_info * mi;
+typedef const uschar * (*fn_t)(gstring *, BOOL);
+
+if (gstring_length(g) > 1)
+ gstring_trim_trailing(g, '\r');
+(void) string_from_gstring(g);
#ifdef EXPERIMENTAL_ARC
-/* Feed the header line to ARC processing */
-(void) arc_header_feed(ctx->cur_header, !(ctx->flags & PDKIM_MODE_SIGN));
+/* Feed the header line also to ARC processing */
+if ((mi = misc_mod_findonly(US"arc")))
+ (((fn_t *) mi->functions)[ARC_HEADER_FEED])
+ (g, !(ctx->flags & PDKIM_MODE_SIGN));
#endif
if (++ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
@@ -951,7 +957,7 @@ if (ctx->flags & PDKIM_MODE_SIGN)
for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
/* Add header to the signed headers list (in reverse order) */
- sig->headers = pdkim_prepend_stringlist(sig->headers, ctx->cur_header->s);
+ sig->headers = pdkim_prepend_stringlist(sig->headers, g->s);
/* VERIFICATION ----------------------------------------------------------- */
/* DKIM-Signature: headers are added to the verification list */
@@ -959,9 +965,9 @@ else
{
#ifdef notdef
DEBUG(D_acl) debug_printf("DKIM >> raw hdr: %.*Z\n",
- ctx->cur_head->ptr, CUS ctx->cur_header->s);
+ ctx->cur_head->ptr, CUS g->s);
#endif
- if (strncasecmp(CCS ctx->cur_header->s,
+ if (strncasecmp(CCS g->s,
DKIM_SIGNATURE_HEADERNAME,
Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
{
@@ -973,7 +979,7 @@ else
DEBUG(D_acl) debug_printf(
"DKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
- sig = pdkim_parse_sig_header(ctx, ctx->cur_header->s);
+ sig = pdkim_parse_sig_header(ctx, g->s);
if (!(last_sig = ctx->sig))
ctx->sig = sig;
@@ -985,18 +991,18 @@ else
if (dkim_collect_input && --dkim_collect_input == 0)
{
- ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
- ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0';
+ ctx->headers = pdkim_prepend_stringlist(ctx->headers, g->s);
+ g->s[g->ptr = 0] = '\0';
return PDKIM_ERR_EXCESS_SIGS;
}
}
/* all headers are stored for signature verification */
- ctx->headers = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->s);
+ ctx->headers = pdkim_prepend_stringlist(ctx->headers, g->s);
}
BAIL:
-ctx->cur_header->s[ctx->cur_header->ptr = 0] = '\0'; /* leave buffer for reuse */
+g->s[g->ptr = 0] = '\0'; /* leave buffer for reuse */
return PDKIM_OK;
}
diff --git a/src/src/miscmods/spf_api.h b/src/src/miscmods/spf_api.h
index 117a7ae6a..0e1907d9a 100644
--- a/src/src/miscmods/spf_api.h
+++ b/src/src/miscmods/spf_api.h
@@ -12,7 +12,7 @@
/* Function table entry numbers */
#define SPF_PROCESS 0
-#define SPF_GET_RESPONSE 2
-#define SPF_OPEN 3
-#define SPF_CLOSE 4
-#define SPF_FIND 5
+#define SPF_GET_RESPONSE 1
+#define SPF_OPEN 2
+#define SPF_CLOSE 3
+#define SPF_FIND 4
diff --git a/src/src/receive.c b/src/src/receive.c
index 541e9320d..ae4e1ff7e 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -4135,11 +4135,16 @@ if (LOGGING(dkim))
typedef gstring * (*fn_t)(gstring *);
if (mi)
g = (((fn_t *) mi->functions)[DKIM_VDOM_FIRSTPASS]) (g);
- }
+
# ifdef EXPERIMENTAL_ARC
-if (LOGGING(dkim) && arc_state && Ustrcmp(arc_state, "pass") == 0)
- g = string_catn(g, US" ARC", 4);
+ {
+ mi = misc_mod_findonly(US"arc");
+ typedef BOOL (*fn_t)(void);
+ if (mi && (((fn_t *) mi->functions)[ARC_STATE_IS_PASS]) ())
+ g = string_catn(g, US" ARC", 4);
+ }
# endif
+ }
#endif
if (LOGGING(receive_time))
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index e75894850..e76790fea 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -1701,10 +1701,7 @@ bmi_run = 0;
bmi_verdicts = NULL;
#endif
dnslist_domain = dnslist_matched = NULL;
-#ifdef EXPERIMENTAL_ARC
-arc_state = arc_state_reason = NULL;
-arc_received_instance = 0;
-#endif
+
dsn_ret = 0;
dsn_envid = NULL;
deliver_host = deliver_host_address = NULL; /* Can be set by ACL */
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 36b5e61fc..594b42e1f 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -32,7 +32,7 @@ optionlist smtp_transport_options[] = {
LOFF(address_retry_include_sender) },
{ "allow_localhost", opt_bool, LOFF(allow_localhost) },
#ifdef EXPERIMENTAL_ARC
- { "arc_sign", opt_stringptr, LOFF(arc_sign) },
+ { "arc_sign", opt_stringptr, LOFF(arc_sign) },
#endif
{ "authenticated_sender", opt_stringptr, LOFF(authenticated_sender) },
{ "authenticated_sender_force", opt_bool, LOFF(authenticated_sender_force) },
@@ -4104,8 +4104,8 @@ else
#ifndef DISABLE_DKIM
{
- typedef void (*fn_t)(void);
misc_module_info * mi;
+
# ifdef MEASURE_TIMING
struct timeval t0;
gettimeofday(&t0, NULL);
@@ -4113,27 +4113,30 @@ else
if ((mi = misc_mod_find(US"dkim", NULL)))
{
+ typedef void (*fn_t)(void);
(((fn_t *) mi->functions)[DKIM_TRANSPORT_INIT]) ();
# ifdef EXPERIMENTAL_ARC
- uschar * s = ob->arc_sign;
- if (s)
{
- if (!(ob->dkim.arc_signspec = s = expand_string(s)))
- {
- if (!f.expand_string_forcedfail)
+ uschar * s = ob->arc_sign;
+ if (s)
+ if (!(ob->dkim.arc_signspec = s = expand_string(s)))
{
- message = US"failed to expand arc_sign";
- sx->ok = FALSE;
- goto SEND_FAILED;
+ if (!f.expand_string_forcedfail)
+ {
+ message = US"failed to expand arc_sign";
+ sx->ok = FALSE;
+ goto SEND_FAILED;
+ }
+ }
+ else if (*s && (mi = misc_mod_find(US"arc", NULL)))
+ {
+ typedef void (*fn_t)(void);
+ (((fn_t *) mi->functions)[ARC_SIGN_INIT]) ();
+
+ /* Ask dkim code to hash the body for ARC */
+ ob->dkim.force_bodyhash = TRUE;
}
- }
- else if (*s)
- {
- /* Ask dkim code to hash the body for ARC */
- (void) arc_ams_setup_sign_bodyhash();
- ob->dkim.force_bodyhash = TRUE;
- }
}
# endif /*ARC*/
}
--
## subscription configuration (requires account):
##
https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at
http://www.exim.org/
## Please use the Wiki with this list -
http://wiki.exim.org/