0
|
1 #! @PERL@ -wT |
|
2 |
|
3 # Display a message in a user's log directory |
|
4 |
|
5 # Copyright (c) 2008 by Rhyolite Software, LLC |
|
6 # |
|
7 # This agreement is not applicable to any entity which sells anti-spam |
|
8 # solutions to others or provides an anti-spam solution as part of a |
|
9 # security solution sold to other entities, or to a private network |
|
10 # which employs the DCC or uses data provided by operation of the DCC |
|
11 # but does not provide corresponding data to other users. |
|
12 # |
|
13 # Permission to use, copy, modify, and distribute this software without |
|
14 # changes for any purpose with or without fee is hereby granted, provided |
|
15 # that the above copyright notice and this permission notice appear in all |
|
16 # copies and any distributed versions or copies are either unchanged |
|
17 # or not called anything similar to "DCC" or "Distributed Checksum |
|
18 # Clearinghouse". |
|
19 # |
|
20 # Parties not eligible to receive a license under this agreement can |
|
21 # obtain a commercial license to use DCC by contacting Rhyolite Software |
|
22 # at sales@rhyolite.com. |
|
23 # |
|
24 # A commercial license would be for Distributed Checksum and Reputation |
|
25 # Clearinghouse software. That software includes additional features. This |
|
26 # free license for Distributed ChecksumClearinghouse Software does not in any |
|
27 # way grant permision to use Distributed Checksum and Reputation Clearinghouse |
|
28 # software |
|
29 # |
|
30 # THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL |
|
31 # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES |
|
32 # OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC |
|
33 # BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES |
|
34 # OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
|
35 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
|
36 # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
|
37 # SOFTWARE. |
|
38 # Rhyolite Software DCC 1.3.103-1.33 $Revision$ |
|
39 # @configure_input@ |
|
40 |
|
41 # This file must protected with an equivalent to httpd.conf lines |
|
42 # in the README file. |
|
43 |
|
44 |
|
45 use strict 'subs'; |
|
46 |
|
47 |
|
48 # get DCC parameters |
|
49 local(%msgs_cache, @msgs_num, $msg_first); |
|
50 do('@cgibin@/common') || die("could not get DCC configuration: $!\n"); |
|
51 |
|
52 |
|
53 |
|
54 # display the message literally if asked |
|
55 if ($query{literal}) { |
|
56 my($buf, $msg, $path); |
|
57 |
|
58 # punt to directory listing if no message specified |
|
59 punt2("no message specified for listing", $list_log_url) |
|
60 if (!$query{msg}); |
|
61 punt2("bad message $query{msg} specified for listing", $list_log_url) |
|
62 if ($query{msg} !~ /^([a-zA-Z\d][a-zA-Z\d]{5}[a-zA-Z\d.]{0,4})$/); |
|
63 $msg = $1; |
|
64 |
|
65 $path = msg2path($msg); |
|
66 if (!open(MSG, $path)) { |
|
67 html_head("Message $msg for $user"); |
|
68 print "<P class=warn>Cannot open $path: $!\n"; |
|
69 html_footer(); |
|
70 print "</BODY>\n</HTML>"; |
|
71 exit; |
|
72 } |
|
73 print "Content-type: text/plain\n"; |
|
74 print "Expires: Thu, 01 Dec 1994 16:00:00 GMT\n"; |
|
75 print "pragma: no-cache\n\n"; |
|
76 print $buf |
|
77 while (read(MSG, $buf, 4*1024)); |
|
78 exit; |
|
79 } |
|
80 |
|
81 |
|
82 # find the previous and next messages |
|
83 my($msg) = $query{msg}; |
|
84 get_log_msgs($msg, 0, 1); |
|
85 $msg = $msgs_num[$#msgs_num] if (!$msg && $#msgs_num >= 0); |
|
86 my($path) = msg2path($msg, ""); |
|
87 |
|
88 if (!$msg || !$msgs_cache{$msg}) { |
|
89 punt2("message $msg has disappeared", $list_log_url) |
|
90 } else { |
|
91 my($msg_num, $older_msg, $oldest_msg, $newer_msg, $newest_msg); |
|
92 |
|
93 $newest_msg = ""; |
|
94 if ($#msgs_num < 0) { |
|
95 $oldest_msg = ""; |
|
96 } else { |
|
97 $oldest_msg = $msgs_num[0]; |
|
98 } |
|
99 if (!defined($msg_first) || $msgs_num[$msg_first] ne $msg) { |
|
100 $msg_num = ""; |
|
101 $newer_msg = $newest_msg; |
|
102 $older_msg = $oldest_msg; |
|
103 } else { |
|
104 $msg_num = "#" . ($msg_first+1); |
|
105 if ($msg_first < $#msgs_num) { |
|
106 $newer_msg = $msgs_num[$msg_first+1] |
|
107 } else { |
|
108 $newer_msg = $newest_msg; |
|
109 } |
|
110 if ($msg_first > 0) { |
|
111 $older_msg = $msgs_num[$msg_first-1]; |
|
112 } else { |
|
113 $older_msg = $oldest_msg; |
|
114 } |
|
115 } |
|
116 |
|
117 $oldest_link = "$list_msg_link${url_ques}msg=$oldest_msg\">Oldest</A>"; |
|
118 $older_link = "$list_msg_link${url_ques}msg=$older_msg\">Older</A>"; |
|
119 $newer_link = "$list_msg_link${url_ques}msg=$newer_msg\">Newer</A>"; |
|
120 $newest_link = "$list_msg_link${url_ques}msg=$newest_msg\">Newest</A>"; |
|
121 html_head("Message $msg_num for $user"); |
|
122 common_buttons(); |
|
123 print <<EOF; |
|
124 <TR><TD>$newest_link |
|
125 <TD>$newer_link |
|
126 <TD>$older_link |
|
127 <TD>$oldest_link |
|
128 </TABLE> |
|
129 |
|
130 <H3>Message $msg_num for $user</H3> |
|
131 <P> |
|
132 $list_msg_link${url_ques}msg=$msg&literal=yes" |
|
133 TARGET="DCC literal log file">Literal log file</A> $path |
|
134 contents for reporting or analysis. |
|
135 EOF |
|
136 } |
|
137 |
|
138 # pass a greylist triple |
|
139 if ($query{greywhite}) { |
|
140 my($cksum, $sight); |
|
141 |
|
142 html_whine("bogus greywhite checksum \"$query{greywhite}\"") |
|
143 if ($query{greywhite} !~ /^([a-z0-9 ]+)$/); |
|
144 $cksum = $1; |
|
145 $sight = `@libexecdir@/dccsight -G '$cksum' 2>&1`; |
|
146 if ($sight =~ /^(Pass|Embargo Ended)\s*$/i){ |
|
147 print "\n<P>\ngreylist embargo ended"; |
|
148 } else { |
|
149 print "\n<P class=warn>\n@libexecdir@/dccsight -G '$cksum': $sight"; |
|
150 } |
|
151 } |
|
152 |
|
153 |
|
154 |
|
155 local($msg_date, $msg_helo, $msg_env_from, @msg_env_to, |
|
156 $msg_client_name, $msg_ip, $msg_mail_host, |
|
157 $msg_hdrs, $msg_body, $msg_cksums); |
|
158 @error = parse_log_msg($msg); |
|
159 if (defined $error[0]) { |
|
160 print "<P class=warn><STRONG>$error[0]:</STRONG> $error[1]\n"; |
|
161 html_footer(); |
|
162 print "</BODY>\n</HTML>\n"; |
|
163 exit; |
|
164 } |
|
165 |
|
166 |
|
167 print <<EOF; |
|
168 <P> |
|
169 <HR> |
|
170 <H4>Envelope</H4> |
|
171 <TABLE border=0 cellspacing=0 cellpadding=0> |
|
172 EOF |
|
173 |
|
174 print "<TR><TD> \n <TD>$msg_date\n"; |
|
175 print_envelope_link(1, "IP address", "IP", $msg_client_name, $msg_ip); |
|
176 print_envelope_link(scalar "helo" =~ /^($sub_hdrs)$/i, |
|
177 "HELO", "substitute HELO", "", $msg_helo); |
|
178 print_envelope_link(1, "env_From", "env_From", "", $msg_env_from); |
|
179 print_envelope_link(scalar "mail_host" =~ /^($sub_hdrs)$/i, |
|
180 "mail_host", "substitute mail_host", "", $msg_mail_host); |
|
181 map print_envelope_link(1, "env_To", "env_To", "", html_str_encode($_)), |
|
182 @msg_env_to; |
|
183 |
|
184 |
|
185 # make links for whitelisting the body checksusm |
|
186 $msg_cksums =~ s/(Body|Fuz1|Fuz2):\s+(\S{8}\s\S{8}\s\S{8}\s\S{8}\s)/make_hex_link($1,$2)/eig; |
|
187 |
|
188 # make whitelisting links for greylist checksums with active embargos |
|
189 while ($msg_cksums =~ /^\s+([a-z0-9]{8}(?: [a-z0-9]{8}){3}) Embargo[\s#0-9]*$/mi) { |
|
190 my($sum, $sight, $link, $text); |
|
191 |
|
192 $sum = $1; |
|
193 $sight = `@libexecdir@/dccsight -QG "$sum" 2>&1`; |
|
194 if ($sight =~ /Embargo.*/) { |
|
195 $link = make_greywhite_link($sum); |
|
196 $text = " <STRONG>select checksum to end greylist embargo of sender</STRONG>\n"; |
|
197 } else { |
|
198 $link = "$sum<!--inactive-->"; |
|
199 $text = " current value: " . html_str_encode($sight); |
|
200 } |
|
201 $msg_cksums =~ s/(^\s+)$sum(.*$)\n/$1$link$2\n$1$text/m; |
|
202 } |
|
203 |
|
204 print <<EOF; |
|
205 </TABLE> |
|
206 <P> |
|
207 <HR> |
|
208 <H4>Headers</H4> |
|
209 <PRE> |
|
210 $msg_hdrs |
|
211 </PRE> |
|
212 |
|
213 <HR> |
|
214 <H4>Body</H4> |
|
215 $msg_body |
|
216 |
|
217 <HR> |
|
218 <H4>Checksums</H4> |
|
219 <PRE>$msg_cksums</PRE> |
|
220 |
|
221 EOF |
|
222 html_footer(); |
|
223 print "</BODY>\n</HTML>\n"; |
|
224 |
|
225 exit; |
|
226 |
|
227 ############################################################################# |
|
228 |
|
229 |
|
230 sub print_envelope_link { |
|
231 my($enable, $label, $type, $text, $value) = @_; |
|
232 |
|
233 # skip the row if the value is absent |
|
234 return if (! $value); |
|
235 |
|
236 print "<TR><TD>"; |
|
237 print html_str_encode($label) if ($label); |
|
238 print ": \n <TD>"; |
|
239 if (! $enable) { |
|
240 print html_str_encode($text . $value); |
|
241 print "\n"; |
|
242 return; |
|
243 } |
|
244 |
|
245 if ($text) { |
|
246 print $text; |
|
247 print " "; |
|
248 } |
|
249 print $edit_link; |
|
250 print "${url_ques}type="; |
|
251 print url_encode($type); |
|
252 print "&val="; |
|
253 print url_encode($value); |
|
254 print "&msg=$query{msg}" if ($query{msg}); |
|
255 print "&auto=1#cur_key\">"; |
|
256 print html_str_encode($value); |
|
257 print "</A>\n"; |
|
258 } |
|
259 |
|
260 |
|
261 |
|
262 sub make_hex_link { |
|
263 my($type, $sum) = @_; |
|
264 my($str); |
|
265 |
|
266 # cannot whitelist missing fuz2 place keepers |
|
267 return "$type: $sum" if ($sum =~ /^[ 0]+$/); |
|
268 |
|
269 $str = "$edit_link${url_ques}type="; |
|
270 $str .= url_encode("hex $type"); |
|
271 $str .= "&val="; |
|
272 $str .= url_encode($sum); |
|
273 $str .= "&msg=$msg&auto=1#cur_key\">$type: $sum</A>"; |
|
274 |
|
275 return $str; |
|
276 } |
|
277 |
|
278 |
|
279 sub make_greywhite_link { |
|
280 my($sum) = @_; |
|
281 my($str); |
|
282 |
|
283 $str = "$list_msg_link${url_ques}msg=$msg&greywhite="; |
|
284 $str .= url_encode($sum); |
|
285 $str .= "\">$sum</A>"; |
|
286 |
|
287 return $str; |
|
288 } |