/****************************************************************/ /* */ /* A stage 2 filter for Weasel */ /* */ /* This filter checks the sender address as supplied in the */ /* MAIL FROM command. This address should have the form */ /* user@domain. We reject the address if 'domain' is one of */ /* our domains but 'user' is not a valid username. In */ /* other words, we are checking for senders who are */ /* pretending to be from our own domain. */ /* */ /* Note that the stage 1 filter called blockmyip.cmd does a */ /* similar job, except that it is checking the claimed */ /* HELO/EHLO address for a match with our address. If you */ /* wish, you could copy the relevant part of blockmyip.cmd */ /* into the present script, and do both checks at stage 2. */ /* */ /* Remark: in single-domain mode, Weasel does not actually */ /* know the name of its domain. In that case, what we are */ /* checking are the names in the "Local" list. To make */ /* this script work in single-domain mode, you must ensure */ /* that your domain name is included in that list. */ /* */ /* Author: Peter Moylan (peter@pmoylan.org) */ /* Last revised: 16 November 2020 */ /* */ /* Prerequisite: */ /* SelectTNI.cmd and INI_get.cmd, from the GenINI */ /* package, must be in your PATH */ /* */ /* Installation: */ /* 1. In Weasel Setup, make the stage 2 filter point to */ /* this script. */ /* 2. Note the remark above about single-domain mode. */ /* */ /****************************************************************/ Globals = "TNImode MultiDomain MailRoot Domains" CALL RxFuncAdd SysLoadFuncs, rexxutil, sysloadfuncs CALL SysLoadFuncs IF SysSearchPath('PATH', 'SelectTNI.cmd') = '' THEN DO SAY "ERROR: SelectTNI.cmd must be in your PATH" EXIT 1 END IF SysSearchPath('PATH', 'INI_get.cmd') = '' THEN DO SAY "ERROR: INI_get.cmd must be in your PATH" EXIT 1 END CALL ParseDomainInfo PARSE ARG NameFile SrcFile /* From NameFile, find the sender address. */ dummy = LineIn(NameFile) /* Client address */ dummy = LineIn(NameFile) /* HELO argument */ sender = LineIn(NameFile) /* MAIL FROM argument */ IF LEFT(sender,1) = '<' THEN PARSE VAR sender '<' sender IF RIGHT(sender,1) = '>' THEN PARSE VAR sender sender'>' PARSE UPPER VAR sender user'@'domain IF user = '$SYS' THEN RETURN 3 /* Any match with one of our domains? */ match = 0 k = 1 DO WHILE (LEFT(Domains,1) \= '00'X) & \match PARSE UPPER VAR Domains this '00'X Domains IF domain = this THEN match = 1 ELSE Domains = STRIP(Domains) END IF match = 0 THEN RETURN 0 /* If we have a domain name match, load the list of users. */ IF TNImode THEN DO IF MultiDomain THEN INIFile = MailRoot'\'domain'\DOMAIN.TNI' ELSE INIFile = "WEASEL.TNI" END ELSE DO IF MultiDomain THEN INIFile = MailRoot'\'domain'\DOMAIN.INI' ELSE INIFile = "WEASEL.INI" END Users = INI_get(INIFile) /* We have an extra user called '$SYS' in this list, but */ /* there's no harm in leaving it there. */ match = 0 k = 1 DO WHILE (LEFT(Users,1) \= '00'X) & \match PARSE UPPER VAR Users this '00'X Users IF user = this THEN match = 1 ELSE Users = STRIP(Users) END IF match THEN RETURN 0 ELSE RETURN 3 /****************************************************************/ /* */ /* BUILDING THE MAILROOT AND THE LIST OF DOMAINS */ /* */ /* This is an initialisation procedure that sets the global */ /* variables MultiDomain, MailRoot, and Domains. For the */ /* purposes of this program those variables have values that */ /* never change. */ /* */ /****************************************************************/ ParseDomainInfo: PROCEDURE expose (Globals) /* On exit, the global variable Domains contains a list of */ /* our domains, in string-of-strings format. In the */ /* single-domain case, we load the list from the "Local" */ /* list. All names are in upper case, to simplify name */ /* matching by the caller. */ /* This procedure also sets the global variables 'TNImode', */ /* 'MailRoot', and 'MultiDomain'. */ /* Figure out the mail root. */ TNImode = SelectTNI("Weasel") IF TNImode THEN INIFile = "WEASEL.TNI" ELSE INIFile = "WEASEL.INI" Nul = '00'X MailRoot = INI_get(INIFile, '$SYS', 'MailRoot') j = POS(Nul,MailRoot) IF j > 0 THEN MailRoot = LEFT(MailRoot, j-1) MailRoot = TRANSLATE(STRIP(MailRoot), '\', '/') /* Get the list of domain names. */ MultiDomain = C2D(INI_get(INIFile, '$SYS', 'MultiDomainEnabled')) IF MultiDomain = '' THEN MultiDomain = 0 IF MultiDomain THEN Domains = INI_get(INIFile, '$SYS', 'Domains') ELSE Domains = INI_get(INIFile, '$SYS', 'Local') Domains = TRANSLATE(STRIP(Domains)) RETURN /****************************************************************/ ShowNul: PROCEDURE /* For testing: returns the string argument with Nul */ /* characters replaced by z. */ PARSE ARG str RETURN TRANSLATE(str, 'x', '00'X) /****************************************************************/