File Coverage

blib/lib/Mail/Milter/Authentication/Handler/TrustedIP.pm
Criterion Covered Total %
statement 53 53 100.0
branch 6 6 100.0
condition 8 11 72.7
subroutine 14 14 100.0
pod 2 6 33.3
total 83 90 92.2


line stmt bran cond sub pod time code
1             package Mail::Milter::Authentication::Handler::TrustedIP;
2 27     27   14215 use strict;
  27         82  
  27         831  
3 27     27   145 use warnings;
  27         66  
  27         800  
4 27     27   142 use base 'Mail::Milter::Authentication::Handler';
  27         64  
  27         3440  
5             our $VERSION = '20191206'; # VERSION
6              
7 27     27   195 use Net::IP;
  27         69  
  27         4302  
8 27     27   186 use Sys::Syslog qw{:standard :macros};
  27         60  
  27         8653  
9 27     27   218 use Mail::AuthenticationResults::Header::Entry;
  27         77  
  27         843  
10 27     27   199 use Mail::AuthenticationResults::Header::SubEntry;
  27         58  
  27         642  
11 27     27   154 use Mail::AuthenticationResults::Header::Comment;
  27         62  
  27         9886  
12              
13             sub default_config {
14             return {
15 1     1 0 1278 'trusted_ip_list' => [],
16             };
17             }
18              
19             sub grafana_rows {
20 1     1 0 3301 my ( $self ) = @_;
21 1         2 my @rows;
22 1         7 push @rows, $self->get_json( 'TrustedIP_metrics' );
23 1         3 return \@rows;
24             }
25              
26             sub is_trusted_ip_address {
27 74     74 1 236 my ( $self, $ip_obj ) = @_;
28 74         550 my $config = $self->handler_config();
29 74 100       339 return 0 if not exists( $config->{'trusted_ip_list'} );
30 66         172 my $trusted = 0;
31 66         141 foreach my $trusted_ip ( @{ $config->{'trusted_ip_list'} } ) {
  66         321  
32 84         383 my $trusted_obj = Net::IP->new($trusted_ip);
33 84   100     74158 my $is_overlap = $ip_obj->overlaps($trusted_obj) || 0;
34 84 100 66     12297 if (
      66        
      66        
35             $is_overlap == $IP_A_IN_B_OVERLAP
36             || $is_overlap == $IP_B_IN_A_OVERLAP # Should never happen
37             || $is_overlap == $IP_PARTIAL_OVERLAP # Should never happen
38             || $is_overlap == $IP_IDENTICAL
39             )
40             {
41 6         32 $trusted = 1;
42             }
43             }
44 66         309 return $trusted;
45             }
46              
47             sub register_metrics {
48             return {
49 26     26 1 215 'trustedip_connect_total' => 'The number of connections from a trusted IP',
50             };
51             }
52              
53             sub connect_callback {
54 74     74 0 279 my ( $self, $hostname, $ip ) = @_;
55 74         409 $self->{'is_trusted_ip_address'} = 0;
56 74 100       422 if ( $self->is_trusted_ip_address($ip) ) {
57 6         125 $self->dbgout( 'TrustedIP', 'pass', LOG_DEBUG );
58 6         58 my $header = Mail::AuthenticationResults::Header::Entry->new()->set_key( 'x-trusted-ip' )->safe_set_value( 'pass' );
59 6         457 $self->add_c_auth_header( $header );
60 6         17 $self->{'is_trusted_ip_address'} = 1;
61 6         24 $self->metric_count( 'trustedip_connect_total' );
62             }
63 74         271 return;
64             }
65              
66             sub close_callback {
67 105     105 0 332 my ( $self ) = @_;
68 105         288 delete $self->{'is_trusted_ip_address'};
69 105         282 return;
70             }
71              
72             1;
73              
74             __END__
75              
76             =pod
77              
78             =encoding UTF-8
79              
80             =head1 NAME
81              
82             Mail::Milter::Authentication::Handler::TrustedIP
83              
84             =head1 VERSION
85              
86             version 20191206
87              
88             =head1 DESCRIPTION
89              
90             Detect a trusted IP address and act accordingly.
91              
92             =head1 CONFIGURATION
93              
94             "TrustedIP" : { | Config the the TruetedIP Module
95             | Check for TrustedIP Addresses
96             "trusted_ip_list" : [ | List of IP Addresses considered to be trusted
97             "100.200.100.2", | CIDR Ranges are valid syntax
98             "2001:44c2:3881:aa00::/56",
99             "2001:44b8:3021:123:dead:beef:abcd:1234"
100             ],
101             },
102              
103             =head1 AUTHOR
104              
105             Marc Bradshaw <marc@marcbradshaw.net>
106              
107             =head1 COPYRIGHT AND LICENSE
108              
109             This software is copyright (c) 2018 by Marc Bradshaw.
110              
111             This is free software; you can redistribute it and/or modify it under
112             the same terms as the Perl 5 programming language system itself.
113              
114             =cut