Skip to content

TASK-5830: TLSRPT #791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions content/momentum/4/hooks/core-smtp-tls-reporting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
lastUpdated: "05/10/2025"
title: "smtp_tls_reporting"
description: "hook invoked after every TLS events for reporting purpose rfc8460 TLSRPT"
---

<a name="hooks.core.smtp_tls_reporting"></a>
## Name

smtp_tls_reporting - This hook is added in 5.1 and allows you inspect a SMTP TLS reporting data
point in JSON format.

## Synopsis

`#include "hooks/core/smtp_tls_reporting.h"`

`int core_smtp_tls_reporting(void closure, struct json_object *json)`


## Description

This hook is called upon:
- any TLSRPT (rfc8460) defined failures, before a TLS connection is attempted,
normally during TLS policy (including MTA-STS, TLSA/DANE) fetching stage.
- TLS negotiation failures or successes during outbound delivery when MTA-STS or TLSA/DANE is enabled.
**Currently, only enabled on domains with successfully fetched MTA-STS policies or DANE TLSA records **.

The JSON fields and values are defined in `tlsrpt.h`, with most of the field names the same as
defined in the RFC: https://datatracker.ietf.org/doc/html/rfc8460.

The following JSON fields are not defined in the RFC:
* `epoch` - epoch time of when the hook is invoked
* `type` - whether the data is for a successful TLS connection or a failure.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 'type' rather than maybe 'status' or 'success'?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

report type. I prefer to keep it, and the doc already passed to SMX. I'm reluctant to change is unless it's absolutely necessary.

`0` - failure; `1` - success
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, these end up on the same line in the preview.


**An example JSON for a success**:

```
{
"epoch": 1746712864,
"type": 1,
"policy": {
"policy-type": "sts",
"policy-domain": "test.bird.com",
"policy-string": [
"version: STSv1",
"mode: enforce",
"mx: mx.bird.com",
"mx: server.ectest.OMNITI.com",
"max_age: 604800"
]
},
"sending-mta-ip": "127.0.0.1",
"receiving-mx-hostname": "server.ectest.OMNITI.com",
"receiving-ip": "127.0.0.1"
}
```

**An example JSON for a failure**:

```
{
"epoch": 1746629177,
"type": 0,
"policy": {
"policy-type": "sts",
"policy-domain": "mismatch.cert.com",
"policy-string": [
"version: STSv1",
"mode: enforce",
"mx: test.bird.com",
"max_age: 86400"
]
},
"result-type": "certificate-host-mismatch",
"failure-reason-code": "4.7.5 [internal] SSL certificate subject does not match host",
"sending-mta-ip": "127.0.0.1",
"receiving-mx-hostname": "test.BIRD.com",
"receiving-ip": "127.0.0.1"
}
```


**Return Values**

This hook returns `int`, but for now the return value has no significance.


**Threading**

This hook could be called in any thread. Please avoid doing time consuming tasks in the hook's
implementation.


### Example: a Lua implementation of the hook to log the JSON into the `paniclog`

```
require("msys.core");
require("json")

local mod = {}

function mod:core_smtp_tls_reporting(js)
print("tls report: ", js) -- log the whole JSON
if js.type == 0 then -- failure
print(string.format("TLSRPT: %s@%s@%s", js.policy["policy-domain"],
js.policy["policy-type"], js["result-type"]))
else -- success
print(string.format("TLSRPT: %s@%s@%s", js.policy["policy-domain"],
js.policy["policy-type"], "OK"))
end
end

msys.registerModule("tlsrpt", mod);
```

**Example of the paniclog output from the above Lua hook**:
```
1746712864:scriptlet: tls report: { "epoch": 1746712864, "type": 1, "policy": { "policy-type": "sts", "policy-domain": "test.bird.com", "policy-string": [ "version: STSv1", "mode: enforce", "mx: mx.bird.com", "mx: server.ectest.OMNITI.com", "max_age: 604800" ] }, "sending-mta-ip": "127.0.0.1", "receiving-mx-hostname": "server.ectest.OMNITI.com", "receiving-ip": "127.0.0.1" }
1746712864:scriptlet: TLSRPT: test.bird.com@sts@OK
1746719856:scriptlet: tls report: { "epoch": 1746719856, "type": 0, "policy": { "policy-type": "sts", "policy-domain": "mismatch.cert.com", "policy-string": [ "version: STSv1", "mode: enforce", "mx: test.bird.com", "max_age: 86400" ] }, "result-type": "certificate-host-mismatch", "failure-reason-code": "4.7.5 [internal] SSL certificate subject does not match host", "sending-mta-ip": "127.0.0.1", "receiving-mx-hostname": "test.BIRD.com", "receiving-ip": "127.0.0.1" }
1746719856:scriptlet: TLSRPT: mismatch.cert.com@sts@certificate-host-mismatch
```
3 changes: 2 additions & 1 deletion content/momentum/4/hooks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ description: "This chapter includes hook point and C function reference material
| [ec_httpsrv_register_auth](/momentum/4/apis-ec-httpsrv-register-auth) | Register an HTTP handler for authenticating a URI |
| [ec_httpsrv_request_local_address](/momentum/4/apis-ec-httpsrv-request-local-address) | Returns the local IP address from the current session |
| [ec_httpsrv_request_peer_address](/momentum/4/apis-ec-httpsrv-request-peer-address) | Returns the remote peer address from the current session |
| [inbound_smtp_tls_post_accept](/momentum/4/hooks/inbound-smtp-tls-post-accept) | Modify the message state after the tls handshake in esmtp_tls_accept (available in 4.4.0 or higher) |
| [inbound_smtp_tls_post_accept](/momentum/4/hooks/inbound-smtp-tls-post-accept) | Modify the message state after the tls handshake in esmtp_tls_accept (available in 4.4.0 or higher) |
| [core_smtp_tls_reporting](/momentum/4/hooks/core-smtp-tls-reporting) | Report TLS events for TLSRPT (TLS reporting) |

This chapter includes hook point and C function reference material that is specific to Momentum 4.

Expand Down
Loading