Mail-Milter-Authentication
view release on metacpan or search on metacpan
lib/Mail/Milter/Authentication/Handler.pm view on Meta::CPAN
return;
}
sub top_connect_callback {
# On Connect
my ( $self, $hostname, $ip ) = @_;
$self->metric_count( 'connect_total' );
$self->status('connect');
$self->dbgout( 'CALLBACK', 'Connect', LOG_DEBUG );
$self->set_return( $self->smfis_continue() );
my $config = $self->config();
eval {
local $SIG{'ALRM'} = sub{ die "Timeout\n" };
if ( $config->{'connect_timeout'} ) {
alarm( $config->{'connect_timeout'} );
}
$self->{'ip_object'} = $ip;
$self->dbgout( 'ConnectFrom', $ip->ip(), LOG_DEBUG );
my $callbacks = $self->get_callbacks( 'connect' );
foreach my $handler ( @$callbacks ) {
my $start_time = $self->get_microseconds();
eval{ $self->get_handler($handler)->connect_callback( $hostname, $ip ); };
if ( my $error = $@ ) {
$self->log_error( 'Connect callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'connect', 'handler' => $handler } );
if ( $error =~ /Timeout/ ) {
alarm( 1 );
}
}
$self->metric_count( 'time_microseconds_total', { 'callback' => 'connect', 'handler' => $handler }, $self->get_microseconds() - $start_time );
}
alarm(0);
};
if ( my $error = $@ ) {
$self->log_error( 'Connect callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'connect' } );
}
$self->status('postconnect');
return $self->get_return();
}
sub top_helo_callback {
# On HELO
my ( $self, $helo_host ) = @_;
$self->status('helo');
$self->dbgout( 'CALLBACK', 'Helo', LOG_DEBUG );
$self->set_return( $self->smfis_continue() );
$helo_host = q{} if not $helo_host;
my $config = $self->config();
eval {
local $SIG{'ALRM'} = sub{ die "Timeout\n" };
if ( $config->{'command_timeout'} ) {
alarm( $config->{'command_timeout'} );
}
# Take only the first HELO from a connection
if ( !( $self->{'helo_name'} ) ) {
$self->{'helo_name'} = $helo_host;
my $callbacks = $self->get_callbacks( 'helo' );
foreach my $handler ( @$callbacks ) {
my $start_time = $self->get_microseconds();
eval{ $self->get_handler($handler)->helo_callback($helo_host); };
if ( my $error = $@ ) {
$self->log_error( 'HELO callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'helo', 'handler' => $handler } );
if ( $error =~ /Timeout/ ) {
alarm( 1 );
}
}
$self->metric_count( 'time_microseconds_total', { 'callback' => 'helo', 'handler' => $handler }, $self->get_microseconds() - $start_time );
}
}
else {
$self->dbgout('Multiple HELO callbacks detected and ignored', $self->{'helo_name'} . ' / ' . $helo_host, LOG_DEBUG );
}
alarm(0);
};
if ( my $error = $@ ) {
$self->metric_count( 'callback_error_total', { 'stage' => 'helo' } );
$self->log_error( 'HELO callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
}
$self->status('posthelo');
return $self->get_return();
}
sub top_envfrom_callback {
# On MAILFROM
#...
my ( $self, $env_from ) = @_;
$self->status('envfrom');
$self->dbgout( 'CALLBACK', 'EnvFrom', LOG_DEBUG );
$self->set_return( $self->smfis_continue() );
$env_from = q{} if not $env_from;
my $config = $self->config();
eval {
local $SIG{'ALRM'} = sub{ die "Timeout\n" };
if ( $config->{'command_timeout'} ) {
alarm( $config->{'command_timeout'} );
}
# Reset private data for this MAIL transaction
delete $self->{'auth_headers'};
delete $self->{'pre_headers'};
delete $self->{'add_headers'};
my $callbacks = $self->get_callbacks( 'envfrom' );
foreach my $handler ( @$callbacks ) {
my $start_time = $self->get_microseconds();
eval { $self->get_handler($handler)->envfrom_callback($env_from); };
if ( my $error = $@ ) {
$self->log_error( 'Env From callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'envfrom', 'handler' => $handler } );
if ( $error =~ /Timeout/ ) {
alarm( 1 );
}
}
$self->metric_count( 'time_microseconds_total', { 'callback' => 'envfrom', 'handler' => $handler }, $self->get_microseconds() - $start_time );
}
alarm(0);
};
if ( my $error = $@ ) {
$self->metric_count( 'callback_error_total', { 'stage' => 'envfrom' } );
$self->log_error( 'Env From callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
}
$self->status('postenvfrom');
return $self->get_return();
}
sub top_envrcpt_callback {
# On RCPTTO
#...
my ( $self, $env_to ) = @_;
$self->status('envrcpt');
$self->dbgout( 'CALLBACK', 'EnvRcpt', LOG_DEBUG );
$self->set_return( $self->smfis_continue() );
$env_to = q{} if not $env_to;
my $config = $self->config();
eval {
local $SIG{'ALRM'} = sub{ die "Timeout\n" };
if ( $config->{'command_timeout'} ) {
alarm( $config->{'command_timeout'} );
}
my $callbacks = $self->get_callbacks( 'envrcpt' );
foreach my $handler ( @$callbacks ) {
my $start_time = $self->get_microseconds();
eval{ $self->get_handler($handler)->envrcpt_callback($env_to); };
if ( my $error = $@ ) {
$self->log_error( 'Rcpt To callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'rcptto', 'handler' => $handler } );
if ( $error =~ /Timeout/ ) {
alarm( 1 );
}
}
$self->metric_count( 'time_microseconds_total', { 'callback' => 'rcptto', 'handler' => $handler }, $self->get_microseconds() - $start_time );
}
alarm(0);
};
if ( my $error = $@ ) {
$self->metric_count( 'callback_error_total', { 'stage' => 'rcptto' } );
$self->log_error( 'Rcpt To callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
}
$self->status('postenvrcpt');
return $self->get_return();
}
sub top_header_callback {
# On Each Header
my ( $self, $header, $value ) = @_;
$self->status('header');
$self->dbgout( 'CALLBACK', 'Header', LOG_DEBUG );
$self->set_return( $self->smfis_continue() );
$value = q{} if not $value;
my $config = $self->config();
eval {
local $SIG{'ALRM'} = sub{ die "Timeout\n" };
if ( $config->{'content_timeout'} ) {
$self->dbgout( 'Content Timeout set', $config->{'content_timeout'}, LOG_DEBUG );
alarm( $config->{'content_timeout'} );
}
if ( my $error = $@ ) {
$self->dbgout( 'inline error $error', '', LOG_DEBUG );
}
my $callbacks = $self->get_callbacks( 'header' );
foreach my $handler ( @$callbacks ) {
my $start_time = $self->get_microseconds();
eval{ $self->get_handler($handler)->header_callback( $header, $value ); };
if ( my $error = $@ ) {
$self->log_error( 'Header callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'header', 'handler' => $handler } );
if ( $error =~ /Timeout/ ) {
alarm( 1 );
}
}
lib/Mail/Milter/Authentication/Handler.pm view on Meta::CPAN
}
else {
# We have another entry
( $key, $value, $header ) = $self->_parse_auth_header_entry( $header );
my $entry = {
'class' => 'entry',
'key' => $key,
'value' => $value,
'children' => [],
};
$comment_on = \$entry;
push @{ ${$acting_on}->{ 'children' } }, $entry;
}
}
return;
}
sub _parse_auth_header_comment {
my ($self,$remain) = @_;
my $value = q{};
my $depth = 0;
while ( length $remain > 0 ) {
my $first = substr( $remain,0,1 );
$remain = substr( $remain,1 );
$value .= $first;
if ( $value eq '(' ) {
$depth++;
}
elsif ( $value eq ')' ) {
$depth--;
last if $depth == 0;
}
}
return($value,$remain);
}
sub _parse_auth_header_entry {
my ($self,$remain) = @_;
my $key;
my $value;
( $key, $remain ) = split( '=', $remain, 2 );
$remain = q{} if ! defined $remain;
( $value, $remain ) = split( ' ', $remain, 2 );
return ($key,$value,$remain);
}
sub top_abort_callback {
# On any out of our control abort
my ($self) = @_;
$self->status('abort');
$self->dbgout( 'CALLBACK', 'Abort', LOG_DEBUG );
$self->set_return( $self->smfis_continue() );
my $config = $self->config();
eval {
local $SIG{'ALRM'} = sub{ die "Timeout\n" };
if ( $config->{'command_timeout'} ) {
alarm( $config->{'command_timeout'} );
}
my $callbacks = $self->get_callbacks( 'abort' );
foreach my $handler ( @$callbacks ) {
my $start_time = $self->get_microseconds();
eval{ $self->get_handler($handler)->abort_callback(); };
if ( my $error = $@ ) {
$self->log_error( 'Abort callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'abort', 'handler' => $handler } );
if ( $error =~ /Timeout/ ) {
alarm( 1 );
}
}
$self->metric_count( 'time_microseconds_total', { 'callback' => 'abort', 'handler' => $handler }, $self->get_microseconds() - $start_time );
}
alarm(0);
};
if ( my $error = $@ ) {
$self->metric_count( 'callback_error_total', { 'stage' => 'abort' } );
$self->log_error( 'Abort callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
}
$self->status('postabort');
return $self->get_return();
}
sub top_close_callback {
# On end of connection
my ($self) = @_;
$self->status('close');
$self->dbgout( 'CALLBACK', 'Close', LOG_DEBUG );
$self->set_return( $self->smfis_continue() );
my $config = $self->config();
eval {
local $SIG{'ALRM'} = sub{ die "Timeout\n" };
if ( $config->{'content_timeout'} ) {
alarm( $config->{'content_timeout'} );
}
my $callbacks = $self->get_callbacks( 'close' );
foreach my $handler ( @$callbacks ) {
my $start_time = $self->get_microseconds();
eval{ $self->get_handler($handler)->close_callback(); };
if ( my $error = $@ ) {
$self->log_error( 'Close callback error ' . $error );
$self->exit_on_close();
$self->tempfail_on_error();
$self->metric_count( 'callback_error_total', { 'stage' => 'close', 'handler' => $handler } );
if ( $error =~ /Timeout/ ) {
alarm( 1 );
}
}
$self->metric_count( 'time_microseconds_total', { 'callback' => 'close', 'handler' => $handler }, $self->get_microseconds() - $start_time );
}
alarm(0);
};
if ( my $error = $@ ) {
$self->metric_count( 'callback_error_total', { 'stage' => 'close' } );
( run in 0.336 second using v1.01-cache-2.11-cpan-39bf76dae61 )