This is an old revision of the document!
In VPOP3 8.8 and later, you can use Lua scripting to implement 'SRS' (Sender Rewriting Scheme') in VPOP3
This involves adding a couple of functions to rewrite outgoing return paths in 'relayout.lua' or 'mxout.lua' as appropriate and a couple of functions to redirect rewritten bounce message recipients in 'smtpsvr.lua'
The below is a basic implementation based on https://www.libsrs2.net/srs/srs.pdf
Use relayout.lua if VPOP3 is sending through a smart host, or mxout.lua if VPOP3 is sending using SMTP Direct
Edit 'mydomain' to be your domain, and 'mykey' to be a secret code for security hashing
mydomain = "pscs.co.uk"; mykey = "bobble"; function ModifyReturnPath(mailfrom, origmailfrom) local srch = "@" .. string.gsub(mydomain, "%.", "%%.") .. "$"; if not string.find(origmailfrom, srch) then local lastAt = origmailfrom:find("[^%@]+$") local localPart = origmailfrom:sub(1, (lastAt - 2)) -- Returns the substring before '@' symbol local domainPart = origmailfrom:sub(lastAt, #origmailfrom) local timestamp = math.floor((os.time()/ (60 * 60 * 24)) % 1024); local timestampMod32 = Mod32(math.floor(timestamp / 32)) .. Mod32(timestamp % 32); local hash = VPOP3.Base64(VPOP3.SHA1(origmailfrom .. timestampMod32 .. mykey)):sub(1,4); return "SRS0=" .. hash .. "=" .. timestampMod32 .. "=" .. domainPart .. "=" .. localPart .. "@" .. mydomain; end print("nosub " .. origmailfrom); end function Mod32(x) return string.sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", x + 1, x + 1); end
Edit 'mydomain' to be your domain, and 'mykey' to be a secret code for security hashing. These should be the same values as in the other script
function MapRecipient(rcpt, rcptlist, mailfrom) if mailfrom == "" then local srch = "^SRS[01]=([^=]+)=([^=]+)=([^=]+)=(.-)@" .. string.gsub(mydomain, "%.", "%%.") .. "$"; local hash, ts, domainPart, localPart; _, _, hash, ts, domainPart, localPart = rcpt:find(srch); if hash then local calcHash = VPOP3.Base64(VPOP3.SHA1(localPart .. "@" .. domainPart .. ts .. mykey)):sub(1,4); if calcHash == hash then local rcptTimestamp = UnMod32(ts:sub(1,1)) * 32 + UnMod32(ts:sub(2,2)); local timestamp = math.floor((os.time()/ (60 * 60 * 24)) % 1024); if timestamp < rcptTimestamp then timestamp = timestamp + 1024; end if timestamp - rcptTimestamp > 5 then return rcpt, "500 SRS Timestamp expired"; end return localPart .. "@" .. domainPart; else return rcpt, "500 SRS Hash invalid"; end end end end function UnMod32(x) return string.find("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", x) - 1; end