Skip to content

Commit

Permalink
Sign only our ARC headers when sealing failed chains
Browse files Browse the repository at this point in the history
  • Loading branch information
flowerysong committed Oct 18, 2024
1 parent 5f0254b commit 54d28a4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ All notable changes to this project will be documented in this file.
are excluded from the AMS, as required by RFC 8617.

### Fixed
- libopenarc - seals on failed chains only cover the latest ARC header set,
as required by RFC 8617 section 5.1.2.

## 1.0.0 - 2024-10-18

Expand Down
5 changes: 5 additions & 0 deletions libopenarc/arc-canon.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,11 @@ arc_canon_init(ARC_MESSAGE *msg, _Bool tmp, _Bool keep)

for (cur = msg->arc_canonhead; cur != NULL; cur = cur->canon_next)
{
if (cur->canon_hashbuf != NULL)
{
/* already initialized, nothing to do */
continue;
}
cur->canon_hashbuf = ARC_MALLOC(ARC_HASHBUFSIZE);
if (cur->canon_hashbuf == NULL)
{
Expand Down
32 changes: 32 additions & 0 deletions libopenarc/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3241,6 +3241,38 @@ arc_getseal(ARC_MESSAGE *msg, ARC_HDRFIELD **seal, char *authservid,
return ARC_STAT_OK;
}

/* RFC 8617 5.1.2 Marking and Sealing "cv=fail" (Invalid) Chains
*
* In the case of a failed Authenticated Received Chain, the
* header fields included in the signature scope of the AS header
* field b= value MUST only include the ARC Set header fields
* created by the MTA that detected the malformed chain, as if
* this newest ARC Set was the only set present.
*/
if (msg->arc_cstate == ARC_CHAIN_FAIL)
{
status = arc_add_canon(msg,
ARC_CANONTYPE_SEAL,
ARC_CANON_RELAXED,
msg->arc_signalg,
NULL,
NULL,
(ssize_t) -1,
&msg->arc_sealcanon);
if (status != ARC_STAT_OK)
{
arc_error(msg, "failed to initialize seal canonicalization object");
return status;
}
_Bool keep = ((msg->arc_library->arcl_flags & ARC_LIBFLAGS_KEEPFILES) != 0);
status = arc_canon_init(msg, keep, keep);
if (status != ARC_STAT_OK)
{
arc_error(msg, "arc_canon_init() failed");
return status;
}
}

/* copy required stuff */
msg->arc_domain = domain;
msg->arc_selector = selector;
Expand Down
16 changes: 16 additions & 0 deletions test/test_milter.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,22 @@ def test_milter_ar_override_multi(run_miltertest):
assert res['headers'][3] == ['ARC-Authentication-Results', 'i=2; example.com; arc=pass']


def test_milter_seal_failed(run_miltertest):
"""The seal for failed chains only covers the set from the sealer"""
res = run_miltertest()

# override the result to "fail"
headers = res['headers']
headers[0][1] = 'example.com; arc=fail'
res1 = run_miltertest(headers)

# mess with the seal
headers[1][1] = 'foo'
res2 = run_miltertest(headers)

assert res1['headers'] == res2['headers']


def test_milter_authresip(run_miltertest):
"""AuthResIP false disables smtp.remote-ip"""
res = run_miltertest()
Expand Down

0 comments on commit 54d28a4

Please sign in to comment.