File Coverage

File:bin/abuse_check
Coverage:51.9%

linestmtbrancondsubtimecode
1#!/usr/bin/env perl
2# -----------------------------------------------------------------------
3# example_abuse_check.pl  --  demonstrate Email::Abuse::Investigator
4#
5# Usage:
6#   perl example_abuse_check.pl spam.eml
7#   perl example_abuse_check.pl < spam.eml
8# -----------------------------------------------------------------------
9
3
3
5846
5
use 5.010;
10
11
3
3
3
6
2
25
use strict;
12
3
3
3
4
2
55
use warnings;
13
3
3
3
539
24456
6
use autodie qw(:all);
14
15
3
3
3
29462
285
6
use utf8;
16
3
3
3
595
1542
8
use open qw(:std :encoding(UTF-8));
17
3
3
3
24858
796
7
use lib '.';                                    # find Email/Abuse/Investigator.pm nearby
18
3
3
3
1472
7
620
use Email::Abuse::Investigator;
19
20# ---- Read the raw email ------------------------------------------------
21
3
293281
my $raw;
22
3
6
if (@ARGV) {
23        # Validate path: reject NUL bytes, bare newlines, and directory-traversal
24        # sequences before opening.  This also makes the path taint-safe under -T.
25
3
10
        my ($safe_path) = $ARGV[0] =~ /\A([^\x00\r\n]+)\z/
26                or die "Invalid characters in path '$ARGV[0]'\n";
27
3
54
        die "Path traversal attempt in '$safe_path'\n"
28                if $safe_path =~ m{(?:^|/)\.\.(?:/|$)};
29
2
5
        open my $fh, '<:raw', $safe_path or die "Cannot open $safe_path: $!";
30
0
0
        local $/;
31
0
0
        $raw = <$fh>;
32
0
0
        close $fh;
33} else {
34
0
0
        binmode STDIN, ':raw';
35
0
0
        local $/;
36
0
0
        $raw = <STDIN>;
37}
38
0
0
die 'No email data supplied' unless $raw && length $raw;
39
40# ---- Analyse -----------------------------------------------------------
41
0
0
my $analyser = Email::Abuse::Investigator->new(
42        verbose => 1,
43        timeout => 15,
44        # List your own outbound relay IPs/CIDRs here so they are skipped
45        # when walking the Received: chain for the true origin:
46        # trusted_relays => ['192.0.2.1', '198.51.100.0/24'],
47);
48
0
0
$analyser->parse_email($raw);
49
50# ---- Full analyst report -----------------------------------------------
51
0
0
print $analyser->report();
52
53# ---- Send-ready abuse report text and contacts -------------------------
54
0
0
my @contacts = $analyser->abuse_contacts();
55
0
0
if (@contacts) {
56
0
0
        print "\n";
57
0
0
        print '=' x 72, "\n";
58
0
0
        print "  ABUSE REPORT TEXT (send this to each contact below)\n";
59
0
0
        print '=' x 72, "\n\n";
60
0
0
        print $analyser->abuse_report_text();
61
62
0
0
        print "\n";
63
0
0
        print '=' x 72, "\n";
64
0
0
        print "  SEND TO:\n";
65
0
0
        print '=' x 72, "\n";
66
0
0
        for my $c (@contacts) {
67
0
0
                printf "  %-45s  %s\n", $c->{address}, $c->{role};
68        }
69
0
0
        print "\n";
70} else {
71
0
0
        print "\n(No abuse contacts could be determined.)\n";
72}
73
74
0
0
exit 0;