1. ZMailer SMTP-server policy filtering rules

	At the end of this is actually the default boiler-plate file from
	the distribution pretty much as is.

	In addition to that, policy-builder.sh script adds a set of other
	things before policy filter is ready for use:

		DB/smtp-policy.src		The boilerplate
		DB/localnames		   ('= _local_names')
		DB/smtp-policy.relay	   ('= _full_rights')
		DB/smtp-policy.mx	   ('= _relaytarget')
		DB/smtp-policy.spam	   ('= _bulk_mail')
		DB/smtp-policy.spam.manual ('= _bulk_mail')

	IF YOU WANT, YOU CAN MODIFY YOUR BOILER PLATE AS WELL AS YOUR
	INSTALLED POLICY-BUILDER.SH SCRIPT.  (Doing 'make install' will
	overwrite policy-builder.sh, but not  smtp-policy.src)


	Basically these various source files (when existing) are used to
	combine knowledge of valid users around us:

	- localnames	Who we are -- ok for receiving; does not
			grant outgoing relay capability.


	- smtp-policy.relay
			Who can use us as outbound relay.

			Use here
				[ip.number]/maskwidth
			for listing those senders (networks) we
			absolutely trust.  Additionally you may give
			(at the same line) some attributes as parameters
			for this key entry:
				fulltrustnet +
				trustrecipient +
			First pair will accept any source address,
			and any recipient addresses that are fed to
			the server;  the second will verify the source
			address, but after that it will accept any
			recipient addresses.

			You may also enter domains which are looked
			up for the hostname of reversed IP address,
			but it is not very wise; IP-reversal is not
			trustworthy data.  It may also cause double-
			entry/level descendance problems when two
			domain-suffixes have same ending suffix (or
			are the same)..  (Name/keyspace problem)

			We can set the "always_accept" flag at the
			source IP test, and never after.

	- smtp-policy.mx	Who really are our MX clients.
			Use this when you really know them, and don't
			want just to trust that if recipient has MX
			to you, it would be ok...
			You can substitute this knowledge with a fuzzy
			feeling by using 'acceptifmx +' attribute at
			the generic boilerplate.

			List here domain names.

			You CAN also list here all POSTMASTER addresses
			you accept email routed to:

				postmaster@local.domain
				postmaster@client.domain

			these are magic addresses that email is accepted
			to, even when everything else is blocked.

	- smtp-policy.spam	Those users & domains that are
			absolutely no-no for senders, or recipients
			no matter what earlier analysis has shown.
			(Except for those that we absolutely trust..)



	Short usage instructions:
		- Fill in/modify related files
		- execute  MAILBIN/policy-builder.sh  script

	Testing instructions:

		You can run the smtpserver in a mode where you can
		claim to be from any address in the outside world
		you wish:

			$MAILBIN/smtpserver -i -d 1 -T '[1.2.3.4]'

		The mode must be interactive (-i), and supplying
		debug mode (-d 1) to it is good help.

		Actual claimed connection source address is to be
		given inside square brackets as a SMTP IP address
		literal.

		Now you can try things like:

			220 ...
			EHLO foo
			...
			MAIL FROM:<>
			...
			RCPT TO:<address@local.domain>
			...
			RCPT TO:<address@elsewere.domain>
			...

		(Substitute some real domains into those RCPT TO
		 lines -- "local.domain" is a hint about what to
		 pick for it..)

		Depending what kind of address you have supplied
		to the -T parameter, they get either accepted, or
		rejected.


2. RBL-type blocking lists

	Per default the system DOES NOT use RBL-type blocking lists.
	There are two ways how to take them into use: 

	-  You can start rejecting at the connection setup and then at
	   MAIL FROM (and RCPT TO). 

	   However many (especially M$ environment) SMTP clients won't
	   react on that properly, and will just keep repeating the delivery
	   attempts. 

	-  You can delay the rejections until RCPT addresses are given. 


2.1 Immediate rejection by RBL

	Like mentioned above, this method has a problem with many clients
	who don't believe that HELO can give 500-series response. 

	Method is as follows: 

	Pick your choice of databases to the second variant ``_RBL0'' label
	by joining your selection from various things exemplified here below
	by using ``:'' character as glue in between: 

	     ``+'' alias ``rbl.maps.vix.com'' 
	     ``relays.mail-abuse.org'' 
	     ``dul.maps.vix.com'' 
	     ``relays.orbs.org'' 
	     ``ok.orbs.org:relays.orbs.org'' <-- THIS IS A PAIR! 

	For the ``ok.orbs.org:relays.orbs.org'' the ZMailer 2.99.52patch2
	has special support, but it isn't entirely fool-proof thing...
	(Due to false OKs in the OK zone while NETBLOCK type things
	 exist at the RELAYS zone.)

	An example for the resulting attribute pair: (RBL+DUL+RSS) 

	  #| Second RBL variant: Early block with RBL+DUL+RSS
	  _RBL0   test-dns-rbl  +:dul.maps.vix.com:relays.mail-abuse.org
	  _RBL1   # Nothing

2.2 Delayed rejection by RBL

	Delay the rejection report to ``RCPT TO'' verbs by using the
	``Third RBL variant'': 

	  #| Third RBL variant: Late block with RBL+DUL+RSS
	  _RBL0   rcpt-dns-rbl      +:dul.maps.vix.com:relays.mail-abuse.org
	  _RBL1   test-rcpt-dns-rbl +

	The sample boilerplace will use these as defaults unless you choose
	to explicitely have ``test-rcpt-dns-rbl -'' at some of the recipient
	domains you list at ``smtp-policy.mx'' file: 

	  #sample.domain.with.rbl
	  sample.domain.no.rbl    test-rcpt-dns-rbl -

3. smtp-policy.src boiler-plate

#| File:  $MAILVAR/db/smtp-policy.src
#|
#|   Policy based filter database boilerplate for smtpserver
#|   This file is compiled into actual database by command:
#|         $MAILBIN/policy-builder.sh
#|
#| Syntax:
#|
#| key	[attribute value]... [= _tag]
#| 
#| Where:
#|
#| 'key' is 
#|   - a domain name optionally preceded by a dot (.)
#|   - "user@" / "user@domain" names.
#|   - an IP address expression in canonical [nn.nn.nn.nn]/prefix form.
#|	Unspecified bits must be 0. (Network IPv6 addresses containing
#|       IPv4-mapped addresses are translated into plain IPv4.)
#|   - any arbitrary word referred as '_tag' at the right side
#|     '_tag' may be any key of this database
#| 'attribute' and 'value' are tokens. They are used by policytest() to
#|     make decisions.  Attribute names, and understood value tokens are:
#|
#|	'='		'_any_token_with_starting_underscore' (aliasing)
#|	'rejectnet'	{ '+', '-' }
#|	'freezenet'	{ '+', '-' }
#|	'rejectsource'	{ '+', '-' }
#|	'freezesource'	{ '+', '-' }
#|	'relaycustomer'	{ '+', '-' }
#|	'relaycustnet'	{ '+', '-' }
#|	'relaytarget'	{ '+', '-' }
#|	'freeze'	{ '+', '-' }
#|	'senderokwithdns' { '+', '-' }
#|	'acceptifmx'	{ '+', '-' }
#|	'acceptifdns'	{ '+', '-' }
#|	'sendernorelay' { '+', '-' }
#|	'test-dns-rbl'	{ '+', '-', "suffix.one:suffix.two" }
#|	  Sample suffixes: rbl.maps.vix.com  relays.mail-abuse.org
#|			   dul.maps.vix.com
#|			   ok.orbs.org:relays.orbs.org  <-- that is a PAIR!
#|	'rcpt-dns-rbl'	{ '+', '-', "suffix.one:suffix.two" }
#|	'test-rcpt-dns-rbl' { '+', '-', "suffix.one:suffix.two" }
#|	'message'	"quoted constant string message"
#|	'localdomain'	{ '+', '-' }
#|	'maxinsize'	nnn
#|	'maxoutsize'	nnn
#|	'fulltrustnet'	{ '+', '-' }
#|	'trustrecipients' { '+', '-' }
#|	'trust-whoson'	{ '+', '-' }
#|
#| Semantics:
#|
#| The policytest() functions called by smtpserver to check the client host,
#| the sender's and recipients' addresses.  policytest() looks for name, and
#| address of client host as well as full and partial user address, and domain
#| part of sender and recipient addresses in this database.  The retrieved
#| attributes are used to make decissions on acepting or rejecting the incoming
#| mail.
#|
#| If looking for 'foo.bar.edu' and exact match failed, the database looks keys
#| in sequence:  '.foo.bar.edu', '.bar.edu', '.edu', and '.'.
#|
#| The order of entries in this file is indifferent.
#|
#| When searching an IP address the entry with the most common (leftside) bits
#| is returned. So you can have a [0.0.0.0]/0 entry what specifies the default
#| addributes for all unlisted IP addresses. (Both IPv4 and IPv6)
#|
#| '=' is a special attribute.
#| The notation '= _tag' means "See also at '_tag'". If server() doesn't
#| find the requested attribute of the object, it will replace object name
#| with '_tag' and restarts search.
#| 

#| Here is an example configuration, assumed the following decision
#| chains of smtpserver/policytest.c routines:
#|
#| Connection establishment:  (IP address tested)
#|
#|  if (IP address of SMTP client has 'REJECTNET +' attribute) then
#|   any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (IP address of SMTP client has 'FREEZENET +' attribute) then
#|   we present happy face, but always put the messages into a freezer..
#|   [state->always_freeze = 1; return FREEZE;]
#|  if (IP address of SMTP client has 'RELAYCUSTNET +' attribute) then
#|   sender accepted, recipients not checked
#|   [state->always_accept = 1; return ACCEPT;]
#|  if (IP address of SMTP client has 'TEST-DNS-RBL +' attribute) then
#|   we use RealtimeBlockingList DNS database.  If we get match from
#|   there, we do: [state->always_reject = 1; return REJECT;]
#|  else
#|   return ACCEPT
#|
#| Connection extablishment; connection source DOMAIN test
#| (This is done on the reverser information of the IP address
#|  of the session source.)
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (IP address of SMTP client has 'REJECTNET +' attribute) then
#|   any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (IP address of SMTP client has 'FREEZENET +' attribute) then
#|   we present happy face, but always put the messages into a freezer..
#|   [state->always_freeze = 1; return FREEZE;]
#|  else
#|   return ACCEPT
#|
#| HELO/EHLO parameter string:
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (HELO-name of SMTP client has 'REJECTNET +' attribute) then
#|   any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (HELO-name of SMTP client has 'FREEZENET +' attribute) then
#|   we present happy face, but always put the messages into a freezer..
#|   [state->always_freeze = 1; return FREEZE;]
#|  default: return ACCEPT
#|
#| MAIL FROM address:
#|
#|  set state->rcpt_nocheck  = 0;
#|  set state->sender_reject = 0;
#|  set state->sender_freeze = 0;
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (sender's address has 'REJECTSOURCE +' attribute) then
#|   sender rejected, any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (sender's address has 'FREEZESOURCE +' attribute) then
#|   we accept with the happy face, but place it into a freezer
#|   [state->always_freeze = 1; return FREEZE;]
#|  when (sender's address is not in policy-db, continue with sender's domain)
#|
#|  if (sender's domain is not in policy-db) then
#|    return ACCEPT
#|
#|  if (sender's domain has 'REJECTSOURCE +' attribute) then
#|   sender rejected, any further conversation refused
#|   [state->sender_reject = 1; return REJECT;]
#|  if (sender's domain has 'FREEZESOURCE +' attribute) then
#|   we accept with the happy face, but place it into a freezer
#|   [state->sender_freeze = 1; return FREEZE;]
#|  if (sender's domain has 'RELAYCUSTOMER +' attribute) then
#|   DANGER ! DANGER !
#|   We will accept all destination addresses for this MAIL FROM,
#|   except those that are explicitely blocked, of course..
#|   [state->rcpt_nocheck = 1; return ACCEPT;]
#|  if (sender's domain has 'SENDEROKWITHDNS +' attribute) then
#|    verify that is DNS data for the target domain.  If yes, return ACCEPT;
#|    if not, return SOFTREJECT
#|  if (sender's domain has 'SENDEROKWITHDNS -' attribute) then
#|    verify that is DNS data for the target domain.  If yes, return ACCEPT;
#|    if not, return REJECT
#|  else
#|    return ACCEPT
#|
#| RCPT TO address:
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->sender_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->sender_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (recipient address has 'RELAYTARGET +' attribute) then
#|    return ACCEPT
#|  if (recipient address has 'RELAYTARGET -' attribute) then
#|    return REJECT
#|  if (recipient address has 'FREEZE +' attribute) then
#|    we accept with the happy face, but place it into a freezer
#|    [status->sender_freeze = 1; return FREEZE;]
#|
#|  if (recipient's domain has 'RELAYTARGET +' attribute) then
#|    return ACCEPT
#|  if (recipient's domain has 'RELAYTARGET -' attribute) then
#|    return REJECT
#|  if (recipient's domain has 'FREEZE +' attribute) then
#|    we accept with the happy face, but place it into a freezer
#|    [status->sender_freeze = 1; return FREEZE;]
#|
#|  If (state->rcpt_nocheck  == 1) return ACCEPT;
#|
#|  If (recipient's domain has 'ACCEPTIFMX +' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return SOFTREJECT
#|  If (recipient's domain has 'ACCEPTIFMX -' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return REJECT
#|  If (recipient's domain has 'ACCEPTIFDNS +' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return SOFTREJECT
#|  If (recipient's domain has 'ACCEPTIFDNS -' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return REJECT
#|  Else
#|    return ACCEPT
#| 
#| ------
#|

#|-----------
#|
#| Default handling boilerplates:
#|
#|   "We are not relaying between off-site hosts, except when ..."
#|
#| You MUST uncomment one of these default-defining pairs, or the blocking
#| of relay hijack will not work at all !
#|
#| -- 1st alternate: No MX target usage, no DNS existence verify
#|    Will accept for reception only those domains explicitely listed
#|    in  'smtp-policy.mx'  and  'localnames'  files.  Will not do
#|    verifications on validity/invalidity of source domains:  <foo@bar>
#
# .			relaycustomer - relaytarget -
# [0.0.0.0]/0		relaycustomer - relaytarget -
#
#| -- 2nd alternate: No MX target usage, DNS existence verify
#|    Like the 1st alternate, except will verify the sender (mail from:<..>)
#|    address for existence of the DNS MX and/or A/AAAA data -- e.g. validity.
#|    If RBL parameters are set below, will use them.
#
# .			relaycustomer - relaytarget - senderokwithdns + = _RBL1
# [0.0.0.0]/0		relaycustomer - relaytarget - senderokwithdns + = _RBL0
#
#| -- 3rd alternate: MX relay trust, DNS existence verify
#|    For the people who are in deep s*...  That is, those who for some
#|    reason have given open permissions for people to use their server
#|    as MX backup for their clients, but don't know all domains valid
#|    to go thru...  Substitutes accurate data to user's whimsical DNS
#|    maintenance activities.  Vulnerable to unauthorized inbound MX
#|    service abuse.
#|    If RBL parameters are set below, will use them.

.			relaycustomer - acceptifmx - senderokwithdns + = _RBL1
[0.0.0.0]/0		relaycustomer - acceptifmx - senderokwithdns + = _RBL0

#| -- 4th alternate: Sender & recipient DNS existence verify
#|    This is more of an example for the symmetry's sake, verifies that
#|    the source and destination domains are DNS resolvable, but does not
#|    block relaying -- DANGER! DANGER! WILL ROBINSON! DANGER!
#
# .			senderokwithdns - acceptifdns -
# [0.0.0.0]/0		senderokwithdns - acceptifdns -
#
#|
#| -----------------------------------
#|
#| RBL type test rules:

#| First RBL variant: NONE OF THE RBL TESTS
_RBL0           # Nothing at early phase
_RBL1           # Nothing at late phase

#| Second RBL variant: Early block with RBL+DUL+RSS
#_RBL0          test-dns-rbl      +:dul.maps.vix.com:relays.mail-abuse.org
#_RBL1          # Nothing at late phase

#| Third RBL variant: Late block with RBL+DUL+RSS
#_RBL0          rcpt-dns-rbl      +:dul.maps.vix.com:relays.mail-abuse.org
#_RBL1          test-rcpt-dns-rbl +

#|  (The "+" at the DNS zone defines is treated as shorthand to
#|   "rbl.maps.vix.com")
#|
#|  The Third RBL variant means that all target domains can all by themselves
#|  choose if they use RBL to do source filtering.  The ``= _RBL1'' test
#|  *must* be added to all domain instances where the check is wanted.
#|  (Including the last-resort domain default of ".")
#|  (Or inverting: If some recipient domain is *not* wanting RBL-type tests,
#|   that domain shall have  ``test-rcpt-dns-rbl -'' attribute pair given for
#|   it at the input datasets -- consider  smtp-policy.mx  file!)
#|
#| These rules mean that locally accepted hostnames MUST be listed in
#| the database with  'relaytarget +' attribute.  ("acceptifmx *" allows
#| reception if the local system is amonst the MXes.)
#|
#|-----------
#|
#| If your system has ``whoson'' server (see contrib/whoson-*.tgz),
#| you can activate it by adding  'trust-whoson +' attribute pair to
#| the wild-card IP address test:  [0.0.0.0]/0  of your choise.
#|
#|-----------
#|
#| For outbound relaying control for fixed IP address networks, see
#| comments in file:  smtp-policy.relay
#|
#|-----------
#|
#| Generally we refuse SMTP connections from host in private address space
#| and refuse mails to or from <user@[nn.nn.nn.nn]> if nn.nn.nn.nn is a
#| private IP address...
#|
_private_address    message "We reject your network" rejectnet + message "We don't accept email from this source address" rejectsource + relaycustomer - relaytarget -
#[172.16.0.0]/12         = _private_address
#[192.168.0.0]/16        = _private_address
#[10.0.0.0]/8            = _private_address
#|
#| ...but hosts in the address range 192.168.16.0-192.168.17.255 may be
#| our SMTP clients.
#|
#[192.168.16.0]/23	rejectnet - = _private_address

#| Hosts of our organization can do anything...
#|
_our_network	= _full_rights

#|    Boilerplate macroes for various things.
#|    If RBL parameters are set above, will use them.

_full_rights	rejectnet - relaycustnet + relaytarget +               = _RBL1
_localnames	rejectnet - relaycustnet - localdomain + relaytarget + = _RBL1
_relaytarget	relaytarget +                                          = _RBL1

#
#sztaki.hu		= _full_rights
#.sztaki.hu		= _full_rights
#[192.84.225.0]/24	= _our_network
#[192.84.226.0]/23	= _our_network
#[192.84.228.0]/23	= _our_network
#|
#| ... except that no use to relaying for dial-up hosts
#|
#.dial.sztaki.hu		relaytarget - = _full_rights
#|
#| ... and we have a misconfigured SMTP client somewhere
#|
#[192.84.225.1]/32	message "Your network is not liked message source" rejectnet + = _our_network
#|
#|
#| We are MX for some UUCP nodes;  The actual list of domains should
#| be gotten from some listing, and inserted here, or generated from
#| a file into compatible format, and appended into the database
#|
#.uucp.iif.hu		relaytarget +
#|
#| Thanks, no bulk mails! Drop them when used as sources, also reject
#| when asked to send for them.
#|
_bulk_mail	message "Your domain is not liked source for email" rejectsource + message "Your IP address is not liked source for email" rejectnet + message "This is not accepted relay target" relaytarget -
#|
#| The actual list of domains, and perhaps user addresses should
#| be gotten from some active Anti-SPAM database
#|
#nobody.com		= _bulk_mail
#.nobody.com		= _bulk_mail
#nodomain.com		= _bulk_mail
#.nodomain.com		= _bulk_mail
#|
#| Some source users we reject always: (frequent spammers..)
#| (see comment above about Anti-SPAM databases)
#| (Do note that these are SMTP ENVELOPE items, not RFC-822 items!)
#|
#friend@		= _bulk_mail
#friends@		= _bulk_mail

#----------------------------------
