NAME
Mail::Colander::Session
SYNOPSIS
use Mail::Colander::Session;
# The session is used during the SMTP dialog to collect data, and
# then by Mail::Colander/Data::Annotation to evaluate conditions and
# rules based on that data, via Data::Annotation::Overlay. The
# accessors are of interest for actually "using" this module.
# set after the TCP handshake, available since "connect"
my $peer_ip = $session->peer_ip;
my $peer_port = $session->peer_port;
my $ip_port = $session->peer_ip_port; # like "10.20.30.40:2222"
# set after HELO/EHLO
my $peer_identity = $session->peer_identity;
# set after MAIL (FROM)
my $from = $session->reverse_path;
# set/updated after each RCPT (TO)
my $to = $session->forward_path;
# set/updated after each DATA-PART and DATA
my $size = $session->mail_min_size;
# set after DATA
my $eml_as_string = $session->mail_data;
DESCRIPTION
This module encapsulate a session that is then easily consumed through Data::Annotation::Overlay, which eventually means that it can be easily consumed in Data::Annotation rules.
Some methods in the interface are not really supposed to be called by the consumer; they are named after each (E)SMTP command and are called by Mail::Colander::Server during the exchange with a connecting peer. These methods make sure to save the relevant data in the accessors, so that they can be later consumed as described above.
As an example, at TCP session setup the "peer_ip"/"peer_port"/peer_ip_port accessors become available; this means that it's possible to use them in a chain for the connect
event:
# ... chain for Data::Annotation, named "connect"...
connect:
default: reject
rules:
- condition:
is_element_of:
- '.peer_ip'
- type: data
value:
- '127.0.0.1'
- '10.20.30.40'
- '172.16.17.18'
return: accept
Each following (E)SMTP command triggers some addition of data to the session, which can be consumed in the corresponding chain. E.g. after the HELO
or EHLO
, the peer identity is available and it can be used to do some filtering and/or set some variables in the overlay:
EHLO:
default: reject
rules:
- condition:
and:
- eq: [ '.peer_ip', '=127.0.0.1' ]
- eq: [ '.peer_identity', '=localhost.localdomain' ]
record:
set:
'.caller': localhost
return: accept
- condition:
and:
- eq: [ '.peer_ip', '=10.20.30.40' ]
- eq: [ '.peer_identity', '=foo.example.com' ]
record:
set:
'.caller': foo
return: accept
- condition:
and:
- eq: [ '.peer_ip', '=10.20.30.40' ]
- eq: [ '.peer_identity', '=bar.example.com' ]
record:
set:
'.caller': bar
return: accept
- condition:
and:
- eq: [ '.peer_ip', '=172.16.17.18' ]
- eq: [ '.peer_identity', '=galook.example.com' ]
record:
set:
'.caller': galook
return: accept
Setting variables (like caller
above) allows implementing dispatch tables later in the analysis, to make things more readable.
When the DATA
part has been completed, everything is available and the corresponding Data::Annotation chain condition can leverage all attributes. This is also an occasion where it's handy to implement a dispatch table:
DATA:
default: reject
rules:
- condition:
eq: [ '.caller', '=localhost' ]
return: { goto: 'localhost' }
- condition:
eq: [ '.caller', '=foo' ]
return: { goto: 'foo' }
...
localhost:
default: reject # default for this chain
rules:
- condition:
and:
- '<': [ '.mail_size', '=2500' ]
- eq: [ '.reverse_path', '=foo@example.com' ]
- '=~': [ '.subject', '=(?mxs:\A ciao)' ]
- is_subset_of:
- '.forward_path'
- type: data
value:
- 'bar@example.com'
- 'foo@bar.com'
return: accept
...
INTERFACE
Constructor
Accessors
These methods are normally consumed in Data::Annotation/Mail::Colander during the evaluation of conditions, by means of a Data::Annotation::Overlay mediator. The sections below indicate where it is meaningful to consume each accessor.
last_op
my $name = $session->last_op;
The last operation that was called for setting a value, see "Methods for tracking messages".
mail_data
my $eml_as_string = $session->mail_data;
The mail data, as a string. AVailable for chain DATA
.
mail_min_size
my $size = $session->mail_min_size;
The minimum size of the email, updated as new data comes in. This is useful in the DATA-PART
chain as it allows to check if the message is getting too big before it has all been received.
mail_size
my $size = $session->mail_size;
The definitive size of the message, available for chain DATA
.
message
my $message = $session->message;
The received message, as a Mail::Colander::Message. This also sets additional accessors directly mapped from the underlying object, namely:
bare_addresses
bcc
cc
from
header_all
header_first
recipients
subject
to
peer_ip
my $ip_address = $session->peer_ip;
The IP address of the peer, available for chain connect
and following.
peer_ip_port
my $ip_colon_port = $session->peer_ip_port;
The IP:port string of the peer, available for chain connect
and following.
peer_port
my $port_number = $session->peer_port;
The port number of the peer, available for chain connect
and following.
Methods for tracking messages
These methods are normally consumed by Mail::Colander::Server. They are called after Net::Server::Mail::ESMTP has done its job, and their first call parameter is always the Net::Server::Mail::ESMTP object that is handling the dialog, then specific parameters.
DATA
$session->DATA($nsm, $eml_as_string);
DATA_INIT
$session->DATA($nsm);
DATA_PART
$session->DATA($nsm, $ref_to_chunk_as_string);
EHLO
$session->EHLO($nsm, $peer_identity, $extensions);
HELO
$session->HELO($nsm, $peer_identity);
$session->MAIL($nsm, $reverse_path);
QUIT
$session->QUIT($nsm);
RCPT
$session->RCPT($nsm, $forward_path);
RST
$session->RST($nsm);
Other methods for setting values
reset
$session->reset;
Reset the state of the session.
reset_transaction
$session->reset_transaction;
Reset the state of the current transaction.
ANYTHING ELSE (INCLUDING AUTHOR, COPYRIGHT AND LICENSE)
See documentation for Mail::Colander.