summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/src/arc.c30
-rw-r--r--src/src/expand.c9
-rw-r--r--src/src/functions.h1
3 files changed, 32 insertions, 8 deletions
diff --git a/src/src/arc.c b/src/src/arc.c
index 53d06de67..7ad00fc9f 100644
--- a/src/src/arc.c
+++ b/src/src/arc.c
@@ -93,6 +93,7 @@ static time_t now;
static time_t expire;
static hdr_rlist * headers_rlist;
static arc_ctx arc_sign_ctx = { NULL };
+static arc_ctx arc_verify_ctx = { NULL };
/******************************************************************************/
@@ -998,9 +999,10 @@ Return: The ARC state, or NULL on error.
const uschar *
acl_verify_arc(void)
{
-arc_ctx ctx = { NULL };
const uschar * res;
+memset(&arc_verify_ctx, 0, sizeof(arc_verify_ctx));
+
if (!dkim_verify_ctx)
{
DEBUG(D_acl) debug_printf("ARC: no DKIM verify context\n");
@@ -1014,7 +1016,7 @@ https://tools.ietf.org/html/draft-ietf-dmarc-arc-protocol-10#section-6
none, the ARC state is "none" and the algorithm stops here.
*/
-if ((res = arc_vfy_collect_hdrs(&ctx)))
+if ((res = arc_vfy_collect_hdrs(&arc_verify_ctx)))
goto out;
/* 2. If the form of any ARC set is invalid (e.g., does not contain
@@ -1032,7 +1034,7 @@ if ((res = arc_vfy_collect_hdrs(&ctx)))
then the chain state is "fail" and the algorithm stops here.
*/
-if ((res = arc_headers_check(&ctx)))
+if ((res = arc_headers_check(&arc_verify_ctx)))
goto out;
/* 4. For each ARC-Seal from the "N"th instance to the first, apply the
@@ -1074,7 +1076,7 @@ if ((res = arc_headers_check(&ctx)))
the algorithm is complete.
*/
-if ((res = arc_verify_seals(&ctx)))
+if ((res = arc_verify_seals(&arc_verify_ctx)))
goto out;
res = US"pass";
@@ -1772,6 +1774,26 @@ 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 *
+fn_arc_domains(void)
+{
+arc_set * as;
+gstring * g = NULL;
+
+if (!arc_state || Ustrcmp(arc_state, "pass") != 0)
+ return US"";
+
+for(as = arc_verify_ctx.arcset_chain; as; as = as->next)
+ {
+ blob * d = &as->hdr_as->d;
+ g = string_append_listele_n(g, ':', d->data, d->len);
+ }
+return g ? g->s : US"";
+}
+
+
/* Construct an Authenticate-Results header portion, for the ARC module */
gstring *
diff --git a/src/src/expand.c b/src/src/expand.c
index 25ae55983..42a5a5d5a 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -462,6 +462,7 @@ 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, &fn_arc_domains },
{ "arc_state", vtype_stringptr, &arc_state },
{ "arc_state_reason", vtype_stringptr, &arc_state_reason },
#endif
@@ -1934,13 +1935,13 @@ switch (vp->type)
case vtype_reply: /* Get reply address */
s = find_header(US"reply-to:", exists_only, newsize, TRUE,
headers_charset);
- if (s != NULL) while (isspace(*s)) s++;
- if (s == NULL || *s == 0)
+ if (s) while (isspace(*s)) s++;
+ if (!s || !*s)
{
*newsize = 0; /* For the *s==0 case */
s = find_header(US"from:", exists_only, newsize, TRUE, headers_charset);
}
- if (s != NULL)
+ if (s)
{
uschar *t;
while (isspace(*s)) s++;
@@ -1948,7 +1949,7 @@ switch (vp->type)
while (t > s && isspace(t[-1])) t--;
*t = 0;
}
- return (s == NULL)? US"" : s;
+ return s ? s : US"";
case vtype_string_func:
{
diff --git a/src/src/functions.h b/src/src/functions.h
index 5f9deab62..3432d7812 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -95,6 +95,7 @@ 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);