Mail-Colander

 view release on metacpan or  search on metacpan

lib/Mail/Colander/Server.pm  view on Meta::CPAN

}

sub _resolve ($in, $class) {
   return blessed($in) ? $in : _require_class_module($class)->new($in);
}

sub _argslist ($in) {
   ref($in) eq 'ARRAY' ? $in->@* : defined($in) ? $in->%* : ()
}

sub _sieve_call ($sieve, $command, $overlay) {
   my $outcome = try {
      my ($out, $data, $call_sequence)
         = $sieve->policy_for($command, $overlay);

      if ($log->is_debug && $call_sequence && $call_sequence->@*) {
         my $calls = join "\n", map { '  ' . $_->{chain} } $call_sequence->@*;
         $log->debug(
            join ' ', 
            "Colander check $command:",
            (
               join ' -> ',
                  map {
                     my ($chain, $rule) = $_->@{qw< chain rule >};

lib/Mail/Colander/Server.pm  view on Meta::CPAN

   # this is used to figure out whether something can be admitted or not
   my $sieve   = $args{sieve};

   # collect events inside a $session object that we can eventually
   # pass down to the $sieve
   my $sh = $stream->handle;
   my $session = Mail::Colander::Session->new(
      peer_ip   => $sh->peerhost,
      peer_port => $sh->peerport,
   );
   my $overlay = Data::Annotation::Overlay->new(
      under => $session,
      cache_existing => 0,
   );

   # first of all collect the peer IP address and figure out whether
   # it's worth bothering or not
   my $outcome = _sieve_call($sieve, connect => $overlay);
   if ($outcome) {
      $args{callback_for}{connect}->($session)
         if $args{callback_for}{connect};
   }
   else {
      $args{callback_for}{reject}->(connect => $session)
         if $args{callback_for}{reject};
      return;
   }

lib/Mail/Colander/Server.pm  view on Meta::CPAN

   for my $command (@cmds) {
      my $method  = $session->can($command =~ s{\W+}{_}rgmxs)
         or next; # no support, no party

      $smtp_in->set_callback(
         $command,
         sub {
            return unless eval { $session->$method(@_) };   # accumulate

            # call the $sieve if so instructed
            my $outcome = _sieve_call($sieve, $command, $overlay);
            if (! $outcome) {
               $args{callback_for}{reject}->($command, $session)
                  if $args{callback_for}{reject};
               $session->reset;
               return;
            }

            # if we are here we can hand over to the callbacks, if any,
            # or just return a true value.
            return 1 unless defined($args{callback_for}{$command});

lib/Mail/Colander/Session.pod  view on Meta::CPAN

              - 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:



( run in 0.940 second using v1.01-cache-2.11-cpan-49f99fa48dc )