NAME

Net::Milter - Masquerade as the MTA to communicate with email filters through a milter interface.

SYNOPSIS

use Net::Milter;
my $milter = new Net::Milter;
$milter->open('127.0.0.1',5513,'tcp');

my ($milter_version,$returned_actions_ref,$returned_protocol_ref) = 
$milter->protocol_negotiation();

my (@results) = $milter->send_header('From','martin@localhost');
foreach (@results) {
  if ($$_{action} eq 'reject')  {exit;}
}

Also see example in scripts directory.

DESCRIPTION

Perl module to provide a pure Perl implementation of the MTA part the milter interface. The goal of this module is to allow other email systems to easily integrate with the various email filters that accept content via milter.

This implementation of milter is developed from the description provided by Todd Vierling, cvs.sourceforge.net/viewcvs.py/pmilter/pmilter/doc/milter-protocol.txt?rev=1.2 and from examining the tcp output from Sendmail.

Attributes

action_types

Reference to an array of the set of actions defined within Sendmail's milter code.

content_types

Reference to an array of the set of content types which may be witheld.

Methods

new

Constructor, creates a new blank Net::Milter object.

open

Open a socket to a milter filter. Takes three arguments, the last argument, can be 'tcp' or 'unix' depending if the connection is to be made to a TCP socket or through a UNIX file system socket. For TCP sockets, the first two argument are the IP address and the port number; for UNIX sockets the first argument is the file path, the second the timeout value. Accepted synonyms for tcp and unix are inet and local respecively.

e.g.

$milter->open('127.0.0.1',5513,'tcp');

to open a connection to port 5513 on address 127.0.0.1, or

$milter->open('/tmp/file.sck',10,'unix'); 

to open a connection to /tmp/file.sck with a timeout of 10 seconds.

The method creates the attribute, 'socket' containing an IO::Handle object.

protocol_negotiation

Talk to the milter filter, describing the list of actions it may perform, and any email content that wont be sent. Accepts as argument the hash of allowable actions and withheld content. The hash keys are : Allowable actions by the filter :

SMFIF_ADDHDRS - Add message headers.
SMFIF_CHGBODY - Alter the message body.
SMFIF_ADDRCPT - Add recipients to the message.
SMFIF_DELRCPT - Delete recipients from the message.
SMFIF_CHGHDRS - Change or delete message headers.

The default is to allow all actions, setting the value to be '0' of any of these keys in the argument hash informs the filter not perform the action.

e.g.

$milter->protocol_negotiation(
    SMFIF_ADDHDRS => 0,
    SMFIF_CHGBODY => 1
    );

informs the filter is is able to change the contents of the message body, but it may not add message headers.

Withheld content :

SMFIP_NOCONNECT - Do not expect the connection details.
SMFIP_NOHELO - Do not expect the HELO string.
SMFIP_NOMAIL - Do not expect the MAIL FROM string.
SMFIP_NORCPT - Do not expect the RCPT TO string.
SMFIP_NOBODY - Do not expect the email body.
SMFIP_NOHDRS - Do not expect any email headers.
SMFIP_NOEOH - Do not expect an end of headers signal.

The default is to inform the filter to expect everything, setting the value of the key to '1' informs the filter to not expect the content.

e.g.

$milter->protocol_negotiation(
    SMFIF_ADDHDRS => 0,
    SMFIF_CHGBODY => 1,
    SMFIP_NOEHO => 1,
    SMFIP_NOCONNECT => 1
);

informs the filter is is able to change the contents of the message body, but it may not add message headers, it will not receive an end of headers signal, nor will it receive the conection details.

The method returns three parameters, the protocol version, an array reference containing all the names of the actions the filter understands it is able to perform, and an array reference containing the names of the content it understands it wont be sent.

send_abort

Send an abort signal to the mail filter. Accepts nothing, returns nothing.

send_body

Send the body of the email to the mail filter. NOTE the filter will only accept upto 65535 bytes of body at a time. Feed the body to the filter piece by piece by repeat calls to send_body with each body chunk until all the body is sent. Accepts the message body, returns reference to an array of return codes (see RETURN CODE section).

send_end_body

Send an end of body signal, i.e. no more body information will follow. Returns a reference to an array of return codes (see RETURN CODE section).

send_connect

Send the SMTP connect information to the mail filter. Accepts the hostname, the family ('unix' for file sockets, 'tcp4' for tcp connections (v4), 'tcp6' for version 6 tcp connections), the sending connection port, the IP address of the sender. Returns a reference to an array of return codes (see RETURN CODE section).

e.g.

    $milter->send_connect(
			  'host.domain',
			  'tcp4',
			  '12345',
			  '127.0.0.1'
			  );

The machine host.domain with IP address 127.0.0.1 connected to us from port 12345 using TCP version 4.

send_helo

Send the HELO (or EHLO) string provided by the connecting computer. Accepts the HELO string as an argument. Returns a reference to an array of return codes (see RETURN CODE section).

send_header

Send a single header name and contents to the filter, accepts two arguments, the header name and the header contents. Returns a reference to an array of return codes (see RETURN CODE section).

send_mail_from

Send the MAIL FROM string to the filter, accepts the MAIL FROM data as an argument. Returns a reference to an array of return codes (see RETURN CODE section).

send_end_headers

Send an end of headers signal, i.e. no more header information will follow. Returns a reference to an array of return codes (see RETURN CODE section).

send_rcpt_to

Send the RCPT TO string to the filter, accepts an array of RCPT TO recipients as argument. Returns a reference to an array of return codes (see RETURN CODE section).

send_quit

Quit the milter communication, accepts nothing, returns nothing.

send_macros

Send Sendmail macro information to the filter. The method accepts a hash of the Sendmail macro names, returns a reference to an array of return codes (see RETURN CODE section).

The potential macro names (hash keys) are :

_ - email address of the Sendmail user.
j - canonical hostname of the recipeint machine.
{daemon_name} - name of the daemon from DaemonPortOptions.
{if_name} - hostname of the incoming connection.
{if_addr} - IP address of the incoming connection.
{tls_version} - TLS/SSL version used for connection.
{cipher} - cipher suite used for the connection.
{cipher_bits} - keylength of the encryption algorith.
{cert_subject} - distinguished name of the presented certificate.
{cert_issuer} - name of the certificate authority.
i - queue ID.
{auth_type} - SMTP authentication mechanism.
{auth_authen} - client's authenticated username.
{auth_ssf} - keylength of encryption algorithm.
{auth_author} - authorization identity.
{mail_mailer} - mailer from SMTP MAIL command.
{mail_host} - host from SMTP MAIL command.
{mail_addr} - address from SMTP MAIL command.
{rcpt_mailer} - mailer from SMTP RCPT command.
{rcpt_host} - host from SMTP RCPT command.
{rcpt_addr} - address from SMTP RCPT command.

Yes I know most of this is redundant, since other methods repeat this information, but this is what the spec says.

e.g. $milter->send_macros( mail_addr => '127.0.0.1', mail_host => 'localhost', rcpt_addr => '127.0.0.1', rcpt_addr => 'postmaster@localhost.localdomain' );

For further explanation of macros see :

http://people.freenet.de/slgig/op_en/macros.html and http://www.sendmail.com/idemo/prod_guide/switch/switchdemo/helplets/en/Macros.html

RETURN CODES

Many methods return an array of hash references. Each hash describes one response from the filter, a filter may return more than one response to any sent data, such as 'add a header','modify body', 'continue'. The hash keys are :

command - the response from the filter
explanation - verbose explanation of the required action
action - action to perform, may be add, delete, accept, replace, continue or reject
header - the name of header the action refers to (may be equal to 'body' to refer to the message body)
value - the value relating to the action

TIPS

Call the various methods in the order that they would be called if accepting a SMTP stream, ie send_connect(), send_helo(), send_mail_from(), send_rcpt_to(), send_header(), send_end_headers(), send_body(). Some milter filters expect this and refuse to return values when expected. Equally continuing to send data when a filter has rejected or accepted a message may confuse it, and refuse to return values for subsequent data, so always check the codes returned.

SEE ALSO

This module is the Yang to Ying's Sendmail::Milter, which can act as the other end of the communication.

NAMING

I choose not to put this module in the Sendmail namespace, as it has nothing to do with Sendmail itself, neither is it anything to do with SMTP, its a net protocol, hence the Net namespace.

AUTHOR

Martin Lee, Star Technology Group (mlee@startechgroup.co.uk)

Copyright (c) 2003 Star Technology Group Ltd.