1 | #!/usr/bin/perl |
---|
2 | # |
---|
3 | # $Id: dspam_notify,v 1.06 2011/11/03 11:58:15 sbajic Exp $ |
---|
4 | |
---|
5 | use Net::SMTP; |
---|
6 | |
---|
7 | # Enter the location of you dspam.conf, dspam binary and path to dspam_admin/dspam_stats. |
---|
8 | $DSPAMCONF = '@sysconfdir@/dspam.conf'; |
---|
9 | $DSPAM_BINARY = '@bindir@/@dspam_transformed@'; |
---|
10 | $BINDIR = '@bindir@'; |
---|
11 | |
---|
12 | # Who will the notifications be sent from? |
---|
13 | $FROM_EMAIL = 'dspam@example.org'; |
---|
14 | $FROM_NAME = 'DSPAM Filter'; |
---|
15 | |
---|
16 | # What will the notification subject be? |
---|
17 | $SUBJECT = 'Daily Spam Quarantine Summary'; |
---|
18 | |
---|
19 | # What text to display in the body? |
---|
20 | $BODY = qq!<p>This report has been sent to you from the Anti-Spam service hosted at example.org. Below is a list of items in your quarantine area. You can view or release a message by clicking on the links (right). If you no longer wish to receive these reports then you may change the option on the 'Preferences' page.</p>!; |
---|
21 | |
---|
22 | # Quarantine URL |
---|
23 | $DSPAM_URL = 'https://dspam.example.org'; |
---|
24 | |
---|
25 | # Maximum of entries to show in mail |
---|
26 | $MAX_ITEMS = 200; |
---|
27 | |
---|
28 | # Address of your SMTP server? localhost should be fine. |
---|
29 | $SERVER = 'localhost'; |
---|
30 | |
---|
31 | # Port of your SMTP server? 25 should be fine |
---|
32 | $PORT = '25'; |
---|
33 | |
---|
34 | # Enable User Preference Checking (Very CPU Intensive!!!) Not Recommended for more than 500 email accounts. |
---|
35 | $PREF_CHECK = 0; |
---|
36 | |
---|
37 | ###################################### |
---|
38 | # No need to config below this point.# |
---|
39 | ###################################### |
---|
40 | |
---|
41 | |
---|
42 | #Build the Quarantine URL |
---|
43 | $QUARANTINE_URL = $DSPAM_URL . '/dspam.cgi?template=quarantine'; |
---|
44 | |
---|
45 | # Autodetect scale and preference extension support |
---|
46 | $LARGE_SCALE = 0; |
---|
47 | $DOMAIN_SCALE = 0; |
---|
48 | $PREFERENCES_EXTENSION = 0; |
---|
49 | do { |
---|
50 | my $x = `$DSPAM_BINARY --version`; |
---|
51 | $PREFERENCES_EXTENSION = 1 if ($x =~ /--enable-preferences-extension/); |
---|
52 | $LARGE_SCALE = 1 if ($x =~ /--enable-large-scale/); |
---|
53 | $DOMAIN_SCALE = 1 if ($x =~ /--enable-domain-scale/) ; |
---|
54 | }; |
---|
55 | |
---|
56 | # Date Formatting |
---|
57 | my ($SEC,$MIN,$HOUR,$MDAY,$MON,$YEAR,$WDAY,$YDAY,$ISDST) = localtime(time); |
---|
58 | |
---|
59 | # Array containing Days of the week abreviations |
---|
60 | @WEEKDAYS = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); |
---|
61 | |
---|
62 | # Array containing Month abreviations |
---|
63 | @MONTHS = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); |
---|
64 | |
---|
65 | $D = (localtime)[6]; |
---|
66 | $M = (localtime)[4]; |
---|
67 | |
---|
68 | $DAY_ABR = $WEEKDAYS[$D]; |
---|
69 | $MONTH_ABR = $MONTHS[$M]; |
---|
70 | $DAY_NUM = $MDAY; |
---|
71 | $YEAR += 1900; |
---|
72 | |
---|
73 | $TODAY = $DAY_ABR . " " . $MONTH_ABR . " " . sprintf("%2s", $DAY_NUM); |
---|
74 | |
---|
75 | # Get the location of DSPAM home and if AllowOverride is set for dailyQuarantineSummary |
---|
76 | $DSPAMHOME = ""; |
---|
77 | $ALLOW_OVERRIDE = ""; |
---|
78 | $DEFAULT_PREF = ""; |
---|
79 | open(DCONF, $DSPAMCONF) || die("Could not open " . $DSPAMCONF . " file!"); |
---|
80 | while(<DCONF>) { |
---|
81 | chomp; |
---|
82 | my($directive, $value) = split(/\s+/); |
---|
83 | $DSPAMHOME = $value if ($directive eq "Home"); |
---|
84 | $ALLOW_OVERRIDE = "on" if ($directive eq "AllowOverride" && $value eq "dailyQuarantineSummary"); |
---|
85 | if ($directive eq "Preference") { |
---|
86 | if ($value =~ /^\s*[\"\']?dailyQuarantineSummary[\t ]*=[\t ]*on[\"\']?/) { |
---|
87 | $DEFAULT_PREF = "on"; |
---|
88 | } else { |
---|
89 | $DEFAULT_PREF = "off"; |
---|
90 | } |
---|
91 | } |
---|
92 | last if($DSPAMHOME ne "" && $ALLOW_OVERRIDE ne "" && $DEFAULT_PREF ne ""); |
---|
93 | } |
---|
94 | close(DCONF); |
---|
95 | $ALLOW_OVERRIDE = "off" if($ALLOW_OVERRIDE eq ""); |
---|
96 | $DEFAULT_PREF = "off" if($DEFAULT_PREF eq ""); |
---|
97 | if (! -d $DSPAMHOME) { |
---|
98 | die("Could not determine DSPAM home!"); |
---|
99 | } |
---|
100 | |
---|
101 | # Create list of users having TP bigger then zero |
---|
102 | open(IN, "$BINDIR/dspam_stats|"); |
---|
103 | while(<IN>) { |
---|
104 | chomp; |
---|
105 | s/:/ /g; |
---|
106 | my($username, $tp, $tn, $fp, $fn, $sc, $nc) = (split(/\s+/))[0,2,4,6,8,10,12]; |
---|
107 | if ($tp eq "") { |
---|
108 | $_ = <IN>; |
---|
109 | s/:/ /g; |
---|
110 | ($tp, $tn, $fp, $fn, $sc, $nc) = (split(/\s+/))[2,4,6,8,10,12]; |
---|
111 | } |
---|
112 | push(@RECIPIENT_LIST, $username) if $tp != 0; |
---|
113 | } |
---|
114 | close(IN); |
---|
115 | |
---|
116 | # Get default user preference for dailyQuarantineSummary |
---|
117 | if ($PREF_CHECK == 1 && $PREFERENCES_EXTENSION == 1) { |
---|
118 | open(PIPE, "$BINDIR/dspam_admin agg pref 'default'|"); |
---|
119 | while(<PIPE>) { |
---|
120 | chomp; |
---|
121 | my($directive, $value) = split(/\=/); |
---|
122 | if ($directive eq "dailyQuarantineSummary") { |
---|
123 | $DEFAULT_PREF = $value; |
---|
124 | last; |
---|
125 | } |
---|
126 | } |
---|
127 | close(PIPE); |
---|
128 | } |
---|
129 | |
---|
130 | # Gather Recipient Quarantine Info |
---|
131 | foreach $RECIPIENT (@RECIPIENT_LIST) { |
---|
132 | |
---|
133 | # Get User Preference from dspam_admin |
---|
134 | if ($ALLOW_OVERRIDE eq "on") { # Check for Allow Overides |
---|
135 | open(PIPE, "$BINDIR/dspam_admin li pref " . quotemeta($RECIPIENT) . "|"); |
---|
136 | while(<PIPE>) { |
---|
137 | chomp; |
---|
138 | my($directive, $value) = split(/\=/); |
---|
139 | if ($directive eq "dailyQuarantineSummary") { |
---|
140 | if ($value ne "on" && $value ne "off") { |
---|
141 | $USER_PREF = $DEFAULT_PREF; # User Preference in valid, use default preference |
---|
142 | } else { |
---|
143 | $USER_PREF = $value; |
---|
144 | } |
---|
145 | last; |
---|
146 | } |
---|
147 | } |
---|
148 | close(PIPE); |
---|
149 | } else { |
---|
150 | $USER_PREF = $DEFAULT_PREF; # Overrides off, use default preference |
---|
151 | } |
---|
152 | |
---|
153 | # Build path to Quarantine .mbox |
---|
154 | if ($DOMAIN_SCALE == 1) { # Format Quarantine path for Domain Scale |
---|
155 | my($u, $D) = (split(/@/, $RECIPIENT)); |
---|
156 | $MBOX = $DSPAMHOME . "/data/" . $D . "/" . $u . "/" . $u . ".mbox"; |
---|
157 | } elsif ($LARGE_SCALE == 1) { # Format Quarantine path for Large Scale |
---|
158 | $u = substr($RECIPIENT, 0, 1); |
---|
159 | $s = substr($RECIPIENT, 1, 1); |
---|
160 | $MBOX = $DSPAMHOME . "/data/" . $u . "/" . $s . "/" . $RECIPIENT . "/" . $RECIPIENT . ".mbox"; |
---|
161 | } else { # Format Quarantine path for Normal Scale |
---|
162 | $MBOX = $DSPAMHOME . "/data/" . $RECIPIENT . "/" . $RECIPIENT . ".mbox"; |
---|
163 | } |
---|
164 | |
---|
165 | # Get total amount of quarantine messages and their signature |
---|
166 | $NEW = 0; |
---|
167 | $TOTAL = 0; |
---|
168 | $SIG = ''; |
---|
169 | @Q_SIG = (); |
---|
170 | @Q_SUBJECT = (); |
---|
171 | if ($USER_PREF ne "off" && -e $MBOX) { # Check if .mbox file exists and user pref |
---|
172 | open(MBOX, "<$MBOX") || die("Could not open " . $MBOX . " file!"); |
---|
173 | while(<MBOX>) { |
---|
174 | s/\r?\n//; |
---|
175 | next if ($_ !~ /^From QUARANTINE/); |
---|
176 | $TOTAL++; # Count Total messages in Quarantine |
---|
177 | $NEW++ if ($_ =~ /^From QUARANTINE $TODAY/); # Count New messages in Quarantine |
---|
178 | $QSUBJECT = '<None Specified>'; |
---|
179 | while(<MBOX>) { |
---|
180 | s/\r?\n//; |
---|
181 | last if ($_ eq ""); |
---|
182 | my($key, $val) = split(/\: ?/, $_, 2); |
---|
183 | if ($key =~ /^Subject$/i) { |
---|
184 | $val =~ s/^\s+//; |
---|
185 | $val =~ s/\s+$//; |
---|
186 | $QSUBJECT = $val if ($val ne ""); |
---|
187 | } |
---|
188 | if ($key =~ /^X\-DSPAM\-Signature$/) { |
---|
189 | push(@Q_SIG, $val); |
---|
190 | $QSUBJECT =~ s/</</g; |
---|
191 | $QSUBJECT =~ s/>/>/g; |
---|
192 | $QSUBJECT = substr($QSUBJECT, 0, 50) . "..." if (length($QSUBJECT)>50); |
---|
193 | push(@Q_SUBJECT, $QSUBJECT); |
---|
194 | last; |
---|
195 | } |
---|
196 | } |
---|
197 | } |
---|
198 | close(MBOX); |
---|
199 | } |
---|
200 | push(@Q_SUBJECT_ITEMS, join("\n", @Q_SUBJECT)); |
---|
201 | push(@Q_SIG_ITEMS, join("\n", @Q_SIG)); |
---|
202 | push(@Q_NEW_ITEMS, $NEW); # Send Count to Array for later use |
---|
203 | push(@Q_TOTAL_ITEMS, $TOTAL); # Send Count to Array for later use |
---|
204 | @Q_SUBJECT = (); |
---|
205 | @Q_SIG = (); |
---|
206 | } |
---|
207 | |
---|
208 | |
---|
209 | # Send some emails |
---|
210 | @Q_ROW_COLOR=('CCCCCC','FFFFFF'); |
---|
211 | $SMTP = Net::SMTP->new( # Establish SMTP Connection |
---|
212 | Host => $SERVER . ":" . $PORT, |
---|
213 | Timeout => 30) || die ("Could not connect to SMTP server " . $SERVER . ":" . $PORT . "; $!"); |
---|
214 | for ($I = 0; $I <= $#RECIPIENT_LIST; $I++) { # Loop through Recipients List and send the message |
---|
215 | if (@Q_TOTAL_ITEMS[$I] != 0) { # Don't send reminders to users with empty quarantines |
---|
216 | $SMTP->mail($FROM_EMAIL); |
---|
217 | $SMTP->to($RECIPIENT_LIST[$I]); |
---|
218 | $SMTP->data(); |
---|
219 | $SMTP->datasend("From: $FROM_NAME <$FROM_EMAIL>\n"); |
---|
220 | $SMTP->datasend("To: $RECIPIENT_LIST[$I]\n"); |
---|
221 | $SMTP->datasend("Subject: $SUBJECT\n"); |
---|
222 | $SMTP->datasend("Mime-Version: 1.0\n"); |
---|
223 | $SMTP->datasend("Content-Type: text/html; charset=UTF-8\n"); |
---|
224 | $SMTP->datasend("\n"); |
---|
225 | $SMTP->datasend("<HTML>\n"); |
---|
226 | $SMTP->datasend("<HEAD>\n"); |
---|
227 | $SMTP->datasend("<TITLE>DSPAM Quarantine Summary for $RECIPIENT_LIST[$I]</TITLE>\n"); |
---|
228 | $SMTP->datasend("<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=utf-8'>\n"); |
---|
229 | $SMTP->datasend("</HEAD>\n"); |
---|
230 | $SMTP->datasend("<BODY>\n"); |
---|
231 | $SMTP->datasend($BODY ."\n"); |
---|
232 | $SMTP->datasend("<TABLE>\n"); |
---|
233 | $SMTP->datasend("<TR><TD>Quarantine Summary for</TD><TD>$RECIPIENT_LIST[$I]</TD></TR>\n"); |
---|
234 | $SMTP->datasend("<TR><TD>Date</TD><TD>$TODAY, $YEAR</TD></TR>\n"); |
---|
235 | $SMTP->datasend("<TR><TD COLSPAN='2'> </TD></TR>\n"); |
---|
236 | $SMTP->datasend("<TR><TD>New Messages</TD><TD>@Q_NEW_ITEMS[$I]</TD></TR>\n"); |
---|
237 | $SMTP->datasend("<TR><TD>Total Messages</TD><TD>@Q_TOTAL_ITEMS[$I]</TD></TR>\n"); |
---|
238 | $SMTP->datasend("</TABLE>\n"); |
---|
239 | $SMTP->datasend("<BR>\n"); |
---|
240 | $SMTP->datasend("<TABLE>\n"); |
---|
241 | @Q_SUBJECT = split(/\n/,@Q_SUBJECT_ITEMS[$I]); |
---|
242 | @Q_SIG = split(/\n/,@Q_SIG_ITEMS[$I]); |
---|
243 | for ($J = 0; $J <= $#Q_SIG; $J++) { |
---|
244 | my $QCOMMAND = $QUARANTINE_URL . "&user=" . $RECIPIENT_LIST[$I] . "&signatureID=" . @Q_SIG[$J]; |
---|
245 | my $QROW_COLOR = 0; |
---|
246 | $QROW_COLOR = 1 if(($J % 2) != 0); |
---|
247 | $SMTP->datasend("<TR>"); |
---|
248 | if ($J >= $MAX_ITEMS) { |
---|
249 | $SMTP->datasend("<TD COLSPAM='3' STYLE='background-color:" . @Q_ROW_COLOR[$QROW_COLOR] . ";'>To display more then " . $MAX_ITEMS . " messages, please visit the DSPAM Control Center.</TD>\n"); |
---|
250 | $SMTP->datasend("</TR>\n"); |
---|
251 | last; |
---|
252 | } |
---|
253 | $SMTP->datasend("<TD STYLE='background-color:" . @Q_ROW_COLOR[$QROW_COLOR] . ";'>" . @Q_SUBJECT[$J] . "</TD>"); |
---|
254 | $SMTP->datasend("<TD STYLE='background-color:" . @Q_ROW_COLOR[$QROW_COLOR] . ";'><A HREF='" . $QCOMMAND . "&command=viewMessage' TARGET='_blank'>View</A></TD>"); |
---|
255 | $SMTP->datasend("<TD STYLE='background-color:" . @Q_ROW_COLOR[$QROW_COLOR] . ";'><A HREF='" . $QCOMMAND . "&command=processFalsePositive' TARGET='_blank'>Release</A></TD>"); |
---|
256 | $SMTP->datasend("</TR>\n"); |
---|
257 | } |
---|
258 | $SMTP->datasend("</TABLE>\n"); |
---|
259 | $SMTP->datasend("<BR>\n"); |
---|
260 | $SMTP->datasend("Please remember to check <A HREF='$QUARANTINE_URL' TARGET='_blank'>Your Quarantine</A> regularly.\n"); |
---|
261 | $SMTP->datasend("</BODY>\n"); |
---|
262 | $SMTP->datasend("</HTML>\n"); |
---|
263 | $SMTP->dataend(); |
---|
264 | } |
---|
265 | } |
---|
266 | $SMTP->quit; # Close SMTP Connection |
---|