smtp_tls_reporting
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 invokedtype
- whether the data is for a successful TLS connection or a failure.0
- failure;1
- success
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