Auto-whitelist management
authorJamie Cameron <jcameron@webmin.com>
Mon, 31 Mar 2008 21:45:34 +0000 (21:45 +0000)
committerJamie Cameron <jcameron@webmin.com>
Mon, 31 Mar 2008 21:45:34 +0000 (21:45 +0000)
spam/defaultacl
spam/delete_awl.cgi [new file with mode: 0644]
spam/edit_awl.cgi [new file with mode: 0644]
spam/images/awl.gif [new file with mode: 0644]
spam/index.cgi
spam/lang/en
spam/spam-lib.pl

index e0a08dc..c45a25b 100644 (file)
@@ -1 +1 @@
-avail=white,score,report,user,header,priv,setup,procmail,db
+avail=white,score,report,user,header,priv,setup,procmail,db,awl
diff --git a/spam/delete_awl.cgi b/spam/delete_awl.cgi
new file mode 100644 (file)
index 0000000..5752ea8
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/local/bin/perl
+# Delete auto-whitelist entries
+
+require './spam-lib.pl';
+&error_setup($text{'dawl_err'});
+&can_use_check("awl");
+&ReadParse();
+
+# Check stuff
+&open_auto_whitelist_dbm() || &error($text{'dawl_eopen'});
+@d = split(/\0/, $in{'d'});
+@d || &error($text{'dawl_enone'});
+
+# Delete from hash
+foreach $d (@d) {
+       delete($awl{$d});
+       delete($awl{$d."|totscore"});
+       }
+
+&close_auto_whitelist_dbm();
+&redirect("edit_awl.cgi?search=".&urlize($in{'search'}));
+
diff --git a/spam/edit_awl.cgi b/spam/edit_awl.cgi
new file mode 100644 (file)
index 0000000..e5e2dd4
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/local/bin/perl
+# Display entries in the auto-whitelist
+
+require './spam-lib.pl';
+&can_use_check("awl");
+&ui_print_header(undef, $text{'awl_title'}, "");
+&ReadParse();
+
+# Open the DBM, or give up
+$ok = &open_auto_whitelist_dbm();
+if ($ok == 0) {
+       &ui_print_endpage(&text('awl_cannot',
+                               &get_auto_whitelist_file()));
+       }
+elsif ($ok < 0) {
+       &ui_print_endpage(&text('awl_empty', &get_auto_whitelist_file()));
+       }
+
+# Show search form
+@keys = sort { $a cmp $b } keys %awl;
+print &ui_form_start("edit_awl.cgi");
+print "<b>$text{'awl_search'}</b>\n";
+print &ui_textbox("search", $in{'search'}, 30),"\n",
+      &ui_submit($text{'awl_ok'});
+print &ui_form_end();
+if ($in{'search'}) {
+       @keys = grep { /\Q$in{'search'}\E/i } @keys;
+       print &text('awl_searching',
+                   "<i>".&html_escape($in{'search'})."</i>"),"<p>\n";
+       }
+
+# Show table
+print &ui_form_start("delete_awl.cgi", "post");
+print &ui_hidden("search", $in{'search'});
+@links = ( &select_all_link("d", 1), &select_invert_link("d", 1) );
+@tds = ( "width=5" );
+print &ui_links_row(\@links);
+print &ui_columns_start([ "",
+                         $text{'awl_email'},
+                         $text{'awl_ip'},
+                         $text{'awl_score'} ], \@tds);
+foreach $k (@keys) {
+       ($email, $ip, $rest) = split(/\|/, $k);
+       next if ($rest eq "totscore");
+       if ($ip eq "ip=none") {
+               $ip = $text{'awl_none'};
+               }
+       elsif ($ip =~ /^ip=(\S+)$/) {
+               $ip = $1;
+               }
+       else {
+               $ip = $text{'awl_unknown'};
+               }
+       print &ui_checked_columns_row([ $email, $ip, $awl{$k} ],
+                                     \@tds, "d", $k);
+       }
+print &ui_columns_end();
+print &ui_links_row(\@links);
+print &ui_form_end([ [ undef, $text{'awl_delete'} ] ]);
+&close_auto_whitelist_dbm();
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/spam/images/awl.gif b/spam/images/awl.gif
new file mode 100644 (file)
index 0000000..611ae7b
Binary files /dev/null and b/spam/images/awl.gif differ
index 3e61469..b55ec46 100755 (executable)
@@ -130,6 +130,7 @@ else {
                push(@pages, 'setup') if ($spam_enabled == 0);
                push(@pages, 'procmail') if ($delivery_enabled == 1);
                push(@pages, 'db') if (!$module_info{'usermin'});
+               push(@pages, 'awl') if (&get_auto_whitelist_file());
                @pages = grep { &can_use_page($_) } @pages;
                $sfolder = $module_info{'usermin'} ? &spam_file_folder()
                                                   : undef;
index af9a840..9d99df8 100644 (file)
@@ -338,3 +338,20 @@ db_eldapport=Missing or invalid LDAP server port number
 db_eldapdn=Missing or invalid base DN - no spaces are allowed
 db_eldapattr=Missing or invalid SpamAssassin attribute
 db_eldapuid=Missing or invalid username attribute
+
+awl_title=Manage Auto-Whitelist
+awl_search=Search whitelist for:
+awl_ok=Search
+awl_searching=Showing auto-whitelist entries matching $1 ..
+awl_email=Email address
+awl_ip=Sender's IP or network
+awl_score=Score to apply
+awl_none=None
+awl_unknown=Unknown
+awl_delete=Remove Selected Entries
+awl_cannot=Usermin could not open your auto-whitelist file <tt>$1</tt>, perhaps because it is in an un-supported format.
+awl_empty=Your auto-whitelist file <tt>$1</tt> does not contain any entries. It will be populated by SpamAsssassin as mail is processed by the system.
+
+dawl_err=Failed to delete from auto-whitelist
+dawl_eopen=Could not open whitelist
+dawl_enone=No addresses to delete selected
index ca2b419..f93564a 100644 (file)
@@ -4,6 +4,7 @@
 do '../web-lib.pl';
 &init_config();
 do '../ui-lib.pl';
+use Fcntl;
 
 $local_cf = $config{'local_cf'};
 $warn_procmail = $config{'warn_procmail'};
@@ -516,6 +517,7 @@ sub can_use_page
 local %avail_icons;
 if ($module_info{'usermin'}) {
        %avail_icons = map { $_, 1 } split(/,/, $config{'avail_icons'});
+       $avail_icons{'awl'} = 1;        # Always usable
        }
 else {
        %avail_icons = map { $_, 1 } split(/,/, $access{'avail'});
@@ -931,5 +933,59 @@ $get_ldap_user_cache{$user} = $uinfo;
 return $uinfo;
 }
 
+# get_auto_whitelist_file()
+# Returns the base path to the auto whitelist DBM, if any. 
+sub get_auto_whitelist_file
+{
+local $conf = &get_config();
+local $awp = &find("auto_whitelist_path", $conf);
+if (!$awp) {
+       $awp = &find_default("auto_whitelist_path",
+               "~/.spamassassin/auto-whitelist");
+       }
+if ($awp !~ /^\//) {
+       # Make absolute
+       return undef if (!$module_info{'usermin'});
+       $awp =~ s/^(\~|\$HOME)\//$remote_user_info[7]\//;
+       if ($awp !~ /^\//) {
+               $awp = "$remote_user_info[7]/$awp";
+               }
+       }
+# Does it exist?
+if (!-r $awp) {
+       local @real = glob("$awp.*");
+       $awp = undef if (!@real);
+       }
+return $awp;
+}
+
+# open_auto_whitelist_dbm()
+# Ties the %awl hash to the autowhitelist DBM file. Returns 1 if successful, or
+# 0 if it could not be opened, or -1 if empty.
+sub open_auto_whitelist_dbm
+{
+local $awp = &get_auto_whitelist_file();
+return 0 if (!$awp);
+local $anyok;
+foreach my $cls ('DB_File', 'GDBM_File', 'SDBM_File') {
+       $@ = undef;
+       eval "use $cls";
+       next if ($@);
+       tie(%awl, $cls, $awp, O_RDWR, 0755) || next;
+       if (scalar(keys %awl)) {
+               return 1;
+               }
+       $anyok = 1;
+       }
+return $anyok ? -1 : 0;
+}
+
+# close_auto_whitelist_dbm()
+# Disconnects the global %awl hash from the DBM file, flushing changes to disk
+sub close_auto_whitelist_dbm
+{
+untie(%awl);
+}
+
 1;