4.12.1.24 Interfaces to Third-Party Programs

A set of functions is defined for interfacing with other filters via TCP. Currently implemented are interfaces with SpamAssassin spamd daemon and with ClamAV anti-virus.

These functions can be used only in eom handler.

Both interfaces work much the same way: the remote filter is connected and the message is passed to it. If the remote filter confirms that the message matches its requirements, the function returns true. Notice that in practice that means that such a message should be rejected or deferred.

The address of the remote filter is supplied as the first argument in the form of a standard URL:

 
proto://path[:port]

The proto part specifies the connection protocol. It should be ‘tcp’ for the TCP connection and ‘file’ or ‘socket’ for the connection via UNIX socket. In the latter case the proto part can be omitted. When using TCP connection, the path part gives the remote host name or IP address and the optional port specifies the port number or service name to use. For example:

 
# connect to ‘remote.filter.net’ on port 3314:
tcp://remote.filter.net:3314

# the same, using symbolic service name (must be defined in
# ‘/etc/services’):
tcp://remote.filter.net:spamd

# Connect via a local UNIX socket (equivalent forms):
/var/run/filter.sock
file:///var/run/filter.sock
socket:///var/run/filter.sock

The description of the interface functions follows.

Built-in Function: boolean sa (string url, number prec)
Built-in Function: boolean sa (string url,   number prec, number report)

Pass the message to the SpamAssassin daemon (spamd) at url. Return true if SpamAssassin considers it a spam, false otherwise. The second arguments, prec, gives the precision, in decimal digits, to be used when converting SpamAssassin diagnostic data and storing them into mailfromd variables. The floating point SpamAssassin data are converted to the integer mailfromd variables using the following relation:

 
var = int(sa-var * prec)

where sa-var stands for the SpamAssassin value and var stands for the corresponding mailfromd one. int() means taking the integer part.

Optional third argument, report, controls what kind of data is returned in the sa_keywords variable. See below for its description.

The function returns additional information via the following variables:

sa_score

The spam score, converted to integer as described above. To convert it to a floating-point representation, use sa_format_score function (see section sa_format_score). See also the example below.

sa_threshold

The threshold, converted to integer form.

sa_keywords

If report is not supplied or is null, this variable contains a string of comma-separated SpamAssassin keywords identifying this message, e.g.:

 
ADVANCE_FEE_1,AWL,BAYES_99

Otherwise, if report is not null, the value of this variable is a spam report message. It is a multi-line textual message, containing detailed description of spam scores in a tabular form. It consists of the following parts:

  1. A preamble.
  2. Content preview.

    The words ‘Content preview’, followed by a colon and an excerpt of the message body.

  3. Content analysis details.

    It has the following form:

     
    Content analysis details: (score points, max required)
    

    where score and max are spam score and threshold in floating point.

  4. Score table.

    The score table is formatted in three columns:

    pts

    The score, as a floating point number with one decimal digit.

    rule name

    SpamAssassin rule name that contributed this score.

    description

    Textual description of the rule

    The score table can be extracted from sa_keywords using sa_format_report_header function (see section sa_format_report_header), as illustrated in the example below.

The sa function can signal the following exceptions: e_failure if the connection fails, e_url if the supplied URL is invalid and e_range if the supplied port number is out of the range 1–65535.

The simplest way to use the function is:

 
prog eom
do
  if sa("tcp://192.168.10.1:3333", 3)
    reject 550 5.7.0
         "Spam detected, score %sa_score with threshold %sa_threshold"
  fi
done

Here is a more advanced example:

 
prog eom
do
  set prec 3
  if sa("tcp://192.168.10.1:3333", %prec, 1)
    add "X-Spamd-Status" "SPAM"
  else
    add "X-Spamd-Status" "OK"
  fi
  add "X-Spamd-Score" sa_format_score(%sa_score, %prec)
  add "X-Spamd-Threshold" sa_format_score(%sa_threshold, %prec)
  add "X-Spamd-Keywords" sa_format_report_header(%sa_keywords)
done

Built-in Function: boolean clamav (string url)

Pass the message to the ClamAV daemon at url. Return true if it detects a virus in it. Return virus name in clamav_virus_name global variable.

The clamav function can signal the following exceptions: e_failure if connection failed, e_url if the supplied URL is invalid and e_range if the supplied port number is out of the range 1–65535.

An example usage:

 
prog eom
do
  if clamav("tcp://192.168.10.1:6300")
    reject 550 5.7.0 "Infected with %clamav_virus_name"
  fi
done