Next: , Previous: , Up: MFL   [Contents][Index]

4.23 Sender Verification Tests

The filter script language provides a wide variety of functions for sender address verification or polling, for short. These functions, which were described in SMTP Callout functions, can be used to implement any sender verification method. The additional data that can be needed is normally supplied by two global variables: ehlo_domain, keeping the default domain for the EHLO command, and mailfrom_address, which stores the sender address for probe messages (see Predefined variables).

For example, a simplest way to implement standard polling would be:

prog envfrom
do
  if stdpoll($1, ehlo_domain, mailfrom_address) == 0
    accept
  else
    reject 550 5.1.0 "Sender validity not confirmed"
  fi
done

However, this does not take into account exceptions that stdpoll can signal. To handle them, one will have to use catch, for example thus:

require status

prog envfrom
do
  try
  do
    if stdpoll($1, ehlo_domain, mailfrom_address) == 0
      accept
    else
      reject 550 5.1.0 "Sender validity not confirmed"
    fi
  done
  catch e_failure or e_temp_failure
  do
    switch $1
    do
    case failure:
      reject 550 5.1.0 "Sender validity not confirmed"
    case temp_failure:
      tempfail 450 4.1.0 "Try again later"
    done
  done
done

If polls are used often, one can define a wrapper function, and use it instead. The following example illustrates this approach:

func poll_wrapper(string email) returns number
do
  catch e_failure or e_temp_failure
  do
    return email
  done
  return stdpoll(email, ehlo_domain, mailfrom_address)
done

prog envfrom
do
  switch poll_wrapper($f)
  do
  case success:
    accept
  case not_found or failure:
    reject 550 5.1.0 "Sender validity not confirmed"
  case temp_failure:
    tempfail 450 4.1.0 "Try again later"
  done
done

Figure 4.1: Building Poll Wrappers

Notice the way envfrom handles success and not_found, which are not exceptions in the strict sense of the word.

The above paradigm is so common that mailfromd provides a special language construct to simplify it: the on statement. Instead of manually writing the wrapper function and using it as a switch condition, you can rewrite the above example as:

prog envfrom
do
  on stdpoll($1, ehlo_domain, mailfrom_address)
  do
  when success:
    accept
  when not_found or failure:
    reject 550 5.1.0 "Sender validity not confirmed"
  when temp_failure:
    tempfail 450 4.1.0 "Try again later"
  done
done

Figure 4.2: Standard poll example

As you see the statement is pretty similar to switch. The major syntactic difference is the use of the keyword when to introduce conditional branches.

General syntax of the on statement is:

on condition
do
  when x1 [or x2 …]:
    stmt1
  when y1 [or y2 …]:
    stmt2
    .
    .
    .
done

The condition is either a function call or a special poll statement (see below). The values used in when branches are normally symbolic exception names (see exception names).

When the compiler processes the on statement it does the following:

  1. Builds a unique wrapper function, similar to that described in Figure 4.1; The name of the function is constructed from the condition function name and an unsigned number, called exception mask, that is unique for each combination of exceptions used in when branches; To avoid name clashes with the user-defined functions, the wrapper name begins and ends with ‘$’ which normally is not allowed in the identifiers;
  2. Translates the on body to the corresponding switch statement;

A special form of the condition is poll keyword, whose syntax is:

poll [for] email
     [host host]
     [from domain]
     [as email]

The order of particular keywords in the poll statement is arbitrary, for example as email can appear before email as well as after it.

The simplest form, poll email, performs the standard sender verification of email address email. It is translated to the following function call:

  stdpoll(email, ehlo_domain, mailfrom_address)

The construct poll email host host, runs the strict sender verification of address email on the given host. It is translated to the following call:

  strictpoll(host, email, ehlo_domain, mailfrom_address)

Other keywords of the poll statement modify these two basic forms. The as keyword introduces the email address to be used in the SMTP MAIL FROM command, instead of mailfrom_address. The from keyword sets the domain name to be used in EHLO command. So, for example the following construct:

  poll email host host from domain as addr

is translated to

  strictpoll(host, email, domain, addr)

To summarize the above, the code described in Figure 4.2 can be written as:

prog envfrom
do
  on poll $f do
  when success:
    accept
  when not_found or failure:
    reject 550 5.1.0 "Sender validity not confirmed"
  when temp_failure:
    tempfail 450 4.1.0 "Try again later"
  done
done

Next: , Previous: , Up: MFL   [Contents][Index]