-
Notifications
You must be signed in to change notification settings - Fork 0
/
Traps.pm
126 lines (101 loc) · 2.61 KB
/
Traps.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# ---- klass Traps ----
# spam traps
package DDgrey::Traps;
use strict;
use integer;
use Data::Dumper; # DEBUG
use DDgrey::Perl6::Parameters;
use Socket;
use DDgrey::Config;
use parent qw(Exporter);
our @EXPORT_OK=qw($traps);
our $traps;
our $loaded={};
# ---- constructor ----
sub init($class){
# return: new traps list
# effect: may raise exception
defined($traps) and return $traps;
my $self={};
bless($self,$class);
$self->reload(0);
$traps=$self;
return $self;
};
# ---- methods ----
sub reload_if_changed($self,$missing_ok){
# effekt: re-reads list of spamtraps if changed
# if missing_ok, a missing traps file will only result in a warning
for my $f (@{$main::config->{traps}}){
my @stat=stat($f);
!defined($stat[9]) and !defined($loaded->{$f}) and next;
if(
defined($stat[9]) and !defined($loaded->{$f}) or
!defined($stat[9]) and defined($loaded->{$f}) or
$stat[9] > $loaded->{$f}
){
main::lm("reloading due to change in $f","traps");
return $self->reload($missing_ok);
};
};
};
sub reload($self,$missing_ok){
# effect: re-reads list of spamtraps
# if missing_ok, a missing traps file will only result in a warning
%{$self}=();
for my $t (@{$main::config->{soft_trap}}){
$self->{$t}='soft';
};
for my $t (@{$main::config->{hard_trap}}){
$self->{$t}='hard';
};
# read from file
for my $f (@{$main::config->{traps}}){
$loaded->{$f}=time();
main::lm("reading traps from $f","traps");
if(!open F,$f){
$missing_ok or main::error("can't open file $f");
main::lm("can't open file $f","traps","warning");
$loaded->{$f}=undef;
return;
};
while(defined(my $in=<F>)){
chomp($in);
$in=~/^\s*(?:$|\#)/ and next;
if($in=~/^\s*(\S*)\s*\:\s*(hard|soft)\s*(?:$|\#)/){
$self->{$1}=$2;
}
else{
main::lm("unknown line in traps file ($in)","traps","warning");
};
};
close F;
};
};
sub check($self,$ip,$from,$to){
# effect: reports ip, from, to and report if mail is sent to spamtrap
if(defined($self->{$to})){
# log
my $report=DDgrey::Report->new({
reporter=>'traps',
event=>$self->{$to}.'_trap',
'ip'=>$ip,
'e_from'=>$from,
'e_to'=>$to,
});
$main::debug > 1 and main::lm("sending report ".$report->unicode(),"traps");
$main::dispatcher->report($report);
};
};
# ---- package init ----
# re-read traps file one a minute
push @main::on_done,sub{
__PACKAGE__->init();
$main::select->register_interval(
($main::debug ? 5 : 60),
sub{
$traps->reload_if_changed(1);
}
);
};
return 1;