Skip to main content

Implement Sender Rewriting Scheme

info

The implementation code is available in our code repository.

The Sender Rewriting Scheme (SRS) can be easily implemented in the Halon MTA using HSL.

Forward rewriting

To enable SRS you should rewrite the sender to be a part of the local-part of your SRS domain. Open up the Pre-delivery script and add the following code for the transport you want to enable it for. You will also need to change the SRS domain and the secret string.

Pre-delivery context
import { srs_forward } from "extras://srs";

$transportid = $message["transportid"];
$sender = $message["sender"];
$senderlocalpart = $message["senderaddress"]["localpart"];
$senderdomain = $message["senderaddress"]["domain"];
$options = [];

if ($transportid === "outbound") {
// SRS
if ($sender and str_lower($senderlocalpart[0:5]) !== "srs0=") {
$options["sender"] = ["localpart" => srs_forward($senderlocalpart, $senderdomain, ["secret" => "mysecret"]), "domain" => "srs.example.com"];
}
}

Try($options);

Reverse rewriting

Depending on where you expect to receive the SRS bounces you need to implement the following code in the relevant RCPT TO script to rewrite the envelope recipient back to the original address again. You will also need to change the SRS domain and the secret string.

RCPT TO context
import { srs_reverse } from "extras://srs";

$transactionid = $transaction["id"];
$sender = $transaction["sender"];
$recipientlocalpart = $arguments["address"]["localpart"];
$recipientdomain = $arguments["address"]["domain"];

if (!$sender and str_lower($recipientlocalpart[0:5]) === "srs0=" and $recipientdomain == "srs.example.com") {
$srs = srs_reverse($recipientlocalpart, ["secret" => "mysecret"]);
if ($srs) {
$context[$transactionid]["srs"][] = str_lower($srs["localpart"]."@".$srs["domain"]);
Accept(["recipient" => $srs]);
} else {
Reject("Invalid SRS");
}
}

And then finally implement the following code in the relevant EOD script when queueing the recipients to rewrite the recipient in the "To" header back to the original address again.

EOD context
$transactionid = $transaction["id"];
$sender = $transaction["senderaddress"];
$recipients = $transaction["recipients"];
$mail = $arguments["mail"];
$metadata = [];

// Queue message for all recipients
$snapshot = $mail->snapshot();
foreach ($recipients as $recipient) {
if (array_includes($recipient["recipient"], $context[$transactionid]["srs"] ?? []))
$mail->setHeader("To", $recipient["recipient"]);
$mail->queue($sender, $recipient["address"], $recipient["transportid"], ["metadata" => $metadata]);
$mail->restore($snapshot);
}

Accept();