Mail-Colander
view release on metacpan or search on metacpan
lib/Mail/Colander/Session.pod view on Meta::CPAN
# 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;
=head1 DESCRIPTION
This module encapsulate a session that is then easily consumed through
L<Data::Annotation::Overlay>, which eventually means that it can be
easily consumed in L<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 L<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
L</peer_ip>/L</peer_port>/L<peer_ip_port> accessors become available;
this means that it's possible to use them in a chain for the C<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 C<HELO> or C<EHLO>, the I<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 C<caller> above) allows implementing dispatch
tables later in the analysis, to make things more readable.
When the C<DATA> part has been completed, everything is available and
the corresponding L<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:
( run in 0.891 second using v1.01-cache-2.11-cpan-39bf76dae61 )