#!/usr/bin/env python3 import socket import sys SRS_DOMAIN = "srs.warenform.de" SOCKET_HOST = "127.0.0.1" SOCKET_PORT = 10003 TIMEOUT = 5 MAX_RESPONSE = 4096 def read_netstring(sock): length_bytes = bytearray() while True: char = sock.recv(1) if not char: raise ValueError("Incomplete netstring length") if char == b":": break if char < b"0" or char > b"9" or len(length_bytes) >= 8: raise ValueError("Invalid netstring length") length_bytes.extend(char) if not length_bytes: raise ValueError("Empty netstring length") length = int(length_bytes) if length > MAX_RESPONSE: raise ValueError("Netstring response too large") data = bytearray() while len(data) < length + 1: chunk = sock.recv(length + 1 - len(data)) if not chunk: raise ValueError("Incomplete netstring response") data.extend(chunk) if data[-1:] != b",": raise ValueError("Invalid netstring terminator") return bytes(data[:-1]).decode("utf-8") def verify_srs(address): request = f"reverse {address}".encode("utf-8") packet = str(len(request)).encode("ascii") + b":" + request + b"," with socket.create_connection( (SOCKET_HOST, SOCKET_PORT), timeout=TIMEOUT ) as sock: sock.settimeout(TIMEOUT) sock.sendall(packet) response = read_netstring(sock) if response.startswith("OK "): original = response[3:] if not original or "@" not in original: raise ValueError("Invalid reverse result") return "OK" if response.startswith("NOTFOUND "): return "REJECT 550 5.1.1 Invalid SRS address" raise ValueError(f"Unexpected socketmap response: {response}") def check_recipient(recipient): if "@" not in recipient: return "DUNNO" localpart, domain = recipient.rsplit("@", 1) if domain.lower() != SRS_DOMAIN: return "DUNNO" if not localpart.upper().startswith(("SRS0=", "SRS1=")): return "REJECT 550 5.1.1 Invalid SRS address" try: return verify_srs(recipient) except (OSError, UnicodeError, ValueError) as exc: print(f"SRS verification error: {exc}", file=sys.stderr) return "DEFER 451 4.3.0 SRS verification unavailable" def main(): while True: attributes = {} for line in sys.stdin: line = line.rstrip("\r\n") if not line: break if "=" in line: key, value = line.split("=", 1) attributes[key] = value else: return recipient = attributes.get("recipient", "") action = check_recipient(recipient) print(f"action={action}\n", flush=True) if __name__ == "__main__": main()