Implement Sender Rewriting Scheme
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.
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.
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.
$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();