# HG changeset patch # User Heiko Schlittermann # Date 1497997838 -7200 # Node ID adf33377005cb68d794145aba4219c6a58f0373d # Parent e2559ee78cb36de009a7a86d652ad7ec7bb0041e Moved to git.schlittermann.de/exim/exigrey diff -r e2559ee78cb3 -r adf33377005c Makefile.PL --- a/Makefile.PL Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -use ExtUtils::MakeMaker; - -WriteMakefile( - NAME => 'Exim::Grey', - AUTHOR => ['Heiko Schlittermann '], - VERSION_FROM => 'lib/Exim/Grey.pm', - EXE_FILES => ['bin/exigrey'], - PREREQ_PM => { - 'DB_File::Lock' => '0.05', - }, - NO_META => 1, - NO_MYMETA => 1, -); diff -r e2559ee78cb3 -r adf33377005c README --- a/README Wed Jun 21 00:26:46 2017 +0200 +++ b/README Wed Jun 21 00:30:38 2017 +0200 @@ -1,19 +1,1 @@ -The documenation is currently only available from -http://www.schlittermann.de/doc/grey - - -Example configuration snippet ------------------------------ - -perl_startup = use Exim::Grey qw(unseen); -GREYLISTED = ${perl{unseen}{<$sender_address>:<$local_part@$domain>/$sender_host_address}{60}} - -acl_check_rcpt: - - ... - - defer - condition = GREYLISTED - condition = ${if <{$message_size}{1M}} - log_message = grey listed exigrey - +Project moved to git.git.schlittermann.de/exim/exigrey diff -r e2559ee78cb3 -r adf33377005c TODO --- a/TODO Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -auto whitelist [done] diff -r e2559ee78cb3 -r adf33377005c bin/exigrey --- a/bin/exigrey Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -#!perl -# © 2006,2007,2016 Heiko Schlittermann -# Quick and dirty. Absolutly no warranty. Not even for spelling ;-) - -use strict; -use warnings; -use Getopt::Long; -use File::Basename; -use File::Temp qw/tmpfile/; -use constant ME => basename $0; -use FindBin qw/$Bin/; -use POSIX qw/strftime mktime/; -use if $ENV{DEBUG} => 'Smart::Comments'; -use Pod::Usage; - -use Exim::Grey qw(:all); - -my $VERSION = '$Id$'; - -my $opt_list; -my $opt_stats; -my $opt_insert; -my $opt_help; -my $opt_clean; -my $opt_purge; -my $opt_dbs; -my $opt_remove; - -sub getDBs(@); -sub iterate(\%$); - -MAIN: { - - GetOptions( - 'list!' => \$opt_list, - 'insert!' => \$opt_insert, - 'remove!' => \$opt_remove, - 'stats!' => \$opt_stats, - 'clean!' => \$opt_clean, - 'purge!' => \$opt_purge, - 'dbs!' => \$opt_dbs, - 'help!' => sub { pod2usage(-verbose => 1, -exit => 0) }, - 'man!' => sub { pod2usage(-verbose => 2, -exit => 0, - noperldoc => system('perldoc -V 2>/dev/null >/dev/null')) }, - ) or pod2usage; - - if ($opt_list) { - foreach (@ARGV = getDBs(@ARGV)) { - my %h; - my $db = connectDB(\%h, $_); - print "# $db\n"; - iterate( - %h, - sub { - my ($item, $v0, $v1, $c, $flag) = @_; - printf "$item: $v0 $v1 $c (%s %s)%s\n", - strftime("%FT%T", localtime($v0)), - strftime("%FT%T", localtime($v1)), - $flag ? " $flag" : ""; - } - ); - print "\n" if @ARGV; - } - exit 0; - } - - if ($opt_stats) { - foreach (@ARGV = getDBs(@ARGV)) { - my %h; - my $db = connectDB(\%h, $_); - - my ($seen, $returned, $oldest_c, $oldest_u, $auto); - $seen = $returned = 0; - $oldest_c = $oldest_u = time(); - iterate( - %h, - sub { - my ($item, $v0, $v1, $c, $flags) = @_; - if ($flags // '' eq 'auto') { - ++$auto; - return; - } - ++$seen; - ++$returned if $v0 != $v1; # soon it can be $c - $oldest_c = $v0 if $v0 < $oldest_c; - $oldest_u = $v1 if $v1 < $oldest_u; - return; - } - ); - - $_ = <<__; - date: %s - db: $db (ls: %.1f MB / du: %.1f MB) - total: $seen (100%%) - returned: %*d (%3d%%) - not returned: %*d (%3d%%) -auto white listed: %*d - oldest (created): %.1f days (%s) - oldest (used): %.1f days (%s) -__ - printf $_, scalar(localtime), (-s $db) / (1024 * 1024), - ((stat $db)[12] * 512) / (1024 * 1024), - length($seen), $returned, - int(0.5 + 100 * ($returned / $seen)), # returned - length($seen), $seen - $returned, - int(0.5 + 100 * ($seen - $returned) / $seen), # not returned - length($seen), $auto, # auto white - ((time - $oldest_c) / 86400), scalar(localtime $oldest_c), - ((time - $oldest_u) / 86400), scalar(localtime $oldest_u); - print "\n" if @ARGV; - - } - exit 0; - } - - if ($opt_clean or $opt_purge) { - - my $cut = time() - (86400 * (@ARGV ? shift : 7)); - foreach (getDBs(@ARGV)) { - my %h; - my $tmp = tmpfile(); - my $db = connectDB(\%h, $_); - iterate( - %h, - sub { - my ($item, $v0, $v1, $c) = @_; - my $rv = defined $opt_purge ? \$v0 : \$v1; - print $tmp "$item\0" if $$rv <= $cut; - } - ); - - seek($tmp, 0, 0) or die "Can't seek tmpfile"; - - $/ = "\0"; - delete $h{$_} while <$tmp>; - printf "$. items %s from $db\n", $opt_purge ? "purged" : "deleted"; - - close($tmp); - - } - exit 0; - } - - if ($opt_dbs) { - print join("\n", getDBs(@ARGV)), "\n"; - exit 0; - } - - if ($opt_insert) { - print unseen(@ARGV); - exit 0; - } - - if ($opt_remove) { - my %default = getDefault(); - my $item = shift; - my $db = shift // $default{db}; - - my $key = "$item\0"; - - connectDB(\my %h, $db); - if (not exists $h{$key}) { - warn "$0: key `$key' not found\n"; - } - else { - $_ = $h{$key}; # delete from tied hashes - delete $h{$key}; # doesn't return anything always - chop; - print "$key: $_\n"; - } - exit 0; - } -} - -sub getDBs(@) { - grep { !/\.lock$/ } grep { -f -s } - map { m(^\.?/) ? glob($_) : glob(getDBDir() . "/$_") } @_ ? @_ : "*"; -} - -# Helper to iterate over our hash and call the passed -# "callback" function (item, v0, v1, count, flags) -sub iterate(\%$) { - my ($hash, $sub) = @_; - while (my ($k, $v) = each %$hash) { - chop($k, $v); -### $k -### $v - &$sub($k, (split(' ', $v), 0, 0)[0 .. 3]); # 0 for filling - } -} - -__END__ - -=head1 NAME - - exigrey - command line interface to exim greylist database - -=head1 SYNOPSIS - - exigrey --insert item [delay [db]] - exigrey --remove item - exigrey --list [db] - exigrey --stat [db-glob ...] - exigrey {--clean|--purge} [days [db-glob ...]] - exigrey {--man|--help} - -=head1 DESCRIPTION - -B is the command line interface to the greylist implementation -for Exim. It may be used to examine, cleanup and manipulate the -greylist database. - -=head1 OPTIONS - -=over - -=item B<--insert> I [I [I]] - -Insert a new item into the database. - -=item B<--remove> I [I] - -Remove the Item I from the database I. - -=item B<--list> [I] - -List the complete content of the database I. This -may take a while. - -=item B<--stat> [I] - -Print the statistics about the databases matching the I -pattern. - -=item B<--clean>|B<--purge> [I [I]...] - -Clean (unused) items or purge items unconditionally. - -=item B<--dbs> [I] - -List the matching database names. - -=back - -If a database name starts with F<./> or F, it's considered -a file name, otherwise it's looked for in F. - -=head1 AUTHOR - -Heiko Schlittermann L<> - -=cut - -# vim:ft=perl aw sts=4 sw=4: diff -r e2559ee78cb3 -r adf33377005c cron.daily.ex --- a/cron.daily.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#! /bin/bash - -command -v exigrey >/dev/null || exit 0 - -# only output if terminal is connected -test -t 0 || exec >/dev/null - -exigrey --clean 3 '*' -exigrey --purge 5 '*' diff -r e2559ee78cb3 -r adf33377005c debian/README.Debian --- a/debian/README.Debian Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -exigrey for Debian ------------------- - -More information: http://www.schlittermann.de/doc/grey - - -- Heiko Schlittermann Mon, 1 Jan 2007 20:17:51 +0100 diff -r e2559ee78cb3 -r adf33377005c debian/changelog --- a/debian/changelog Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -exigrey (0.21) stable; urgency=low - - * new upstream - - -- Heiko Schlittermann Mon, 21 Jan 2008 12:43:06 +0100 - -exigrey (0.19-1) stable; urgency=low - - * new upstream - - Locking - * perltidy - - -- Heiko Schlittermann Fri, 18 Jan 2008 22:59:36 +0100 - -exigrey (0.18-1) stable; urgency=low - - * new upstream - - Kosmetik - - * cron.daily.ex - - -- Heiko Schlittermann Tue, 16 Jan 2007 13:25:22 +0100 - -exigrey (0.17-1) stable; urgency=low - - * new upstream - - Kosmetik - - -- Heiko Schlittermann Tue, 16 Jan 2007 00:01:14 +0100 - -exigrey (0.16-1) stable; urgency=low - - * new upstream - - bug fix - - -- Heiko Schlittermann Sat, 13 Jan 2007 22:36:49 +0100 - -exigrey (0.15-1) stable; urgency=low - - * new upstream - - bug with counting resolved - - -- Heiko Schlittermann Wed, 03 Jan 2007 22:21:34 +0100 - -exigrey (0.14-1) stable; urgency=low - - * new upstream - - counter added - - -- Heiko Schlittermann Wed, 03 Jan 2007 18:15:21 +0100 - -exigrey (0.13-1) stable; urgency=low - - * new upstream - - wildcard behaviour - - -- Heiko Schlittermann Wed, 03 Jan 2007 17:23:33 +0100 - -exigrey (0.12-1) stable; urgency=low - - * new upstream - - more informative output - * cron.daily: output if TERMINAL - - -- Heiko Schlittermann Wed, 03 Jan 2007 13:05:04 +0100 - -exigrey (0.11-1) stable; urgency=low - - * new upstream - - purge - * added purge to cron.daily - - -- Heiko Schlittermann Wed, 03 Jan 2007 12:57:15 +0100 - -exigrey (0.10-1) stable; urgency=low - - * new upstream - - wildcards - - -- Heiko Schlittermann Wed, 03 Jan 2007 11:18:02 +0100 - -exigrey (0.9-1) stable; urgency=low - - * new features for cmd tool - * cron.daily - - -- Heiko Schlittermann Wed, 03 Jan 2007 10:21:33 +0100 - -exigrey (0.8-1) stable; urgency=low - - * new upstream - -bug fix - - -- Heiko Schlittermann Wed, 03 Jan 2007 00:15:29 +0100 - -exigrey (0.7-1) stable; urgency=low - - * new upstream: - - stats: size of database - - -- Heiko Schlittermann Wed, 03 Jan 2007 00:05:44 +0100 - -exigrey (0.6-1) stable; urgency=low - - * bug with umask fixed - - -- Heiko Schlittermann Tue, 02 Jan 2007 22:46:22 +0100 - -exigrey (0.5-1) stable; urgency=low - - * new upstream: - - autocreation of files/dirs - - default db location/name changed - - -- Heiko Schlittermann Tue, 02 Jan 2007 22:35:21 +0100 - -exigrey (0.4-3) stable; urgency=low - - * depends on exim4-daemon-heavy - - -- Heiko Schlittermann Tue, 02 Jan 2007 21:09:58 +0100 - -exigrey (0.4-2) stable; urgency=low - - * depends on perl - - -- Heiko Schlittermann Tue, 02 Jan 2007 20:53:44 +0100 - -exigrey (0.4-1) stable; urgency=low - - * new upstream (DB_File instead of BerkeleyDB) - - -- Heiko Schlittermann Tue, 02 Jan 2007 20:49:13 +0100 - -exigrey (0.3-1) stable; urgency=low - - * new upstream (--clean added) - - -- Heiko Schlittermann Tue, 02 Jan 2007 17:56:52 +0100 - -exigrey (0.2-1) stable; urgency=low - - * files and directories changed - bin: /usr/sbin/exigrey - lib: /usr/share/exim4/exigrey.pl - - -- Heiko Schlittermann Tue, 02 Jan 2007 16:01:03 +0100 - - -exigrey (0.1-3) stable; urgency=low - - * Initial release - - -- Heiko Schlittermann Mon, 1 Jan 2007 20:17:51 +0100 - diff -r e2559ee78cb3 -r adf33377005c debian/compat --- a/debian/compat Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -5 diff -r e2559ee78cb3 -r adf33377005c debian/control --- a/debian/control Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -Source: exigrey -Section: unknown -Priority: extra -Maintainer: Heiko Schlittermann -Build-Depends: debhelper (>= 5) -Standards-Version: 3.7.2 - -Package: exigrey -Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, perl, exim4-daemon-heavy, libdb-file-lock-perl -Description: greylist implementation for exim (perl) - Yet another greylist implementation for exim, using Exim's - perl_startup feature. - For info see http://www.schlittermann.de/grey. - diff -r e2559ee78cb3 -r adf33377005c debian/copyright --- a/debian/copyright Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -This package was debianized by Heiko Schlittermann on -Mon, 1 Jan 2007 20:17:51 +0100. - -It was downloaded from - -Upstream Author: - -Copyright: - -License: - - - - -The Debian packaging is (C) 2007, Heiko Schlittermann and -is licensed under the GPL, see `/usr/share/common-licenses/GPL'. - - -# Please also look if there are files or directories which have a -# different copyright/license attached and list them here. - diff -r e2559ee78cb3 -r adf33377005c debian/cron.d.ex --- a/debian/cron.d.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -# -# Regular cron jobs for the exigrey package -# -0 4 * * * root exigrey_maintenance diff -r e2559ee78cb3 -r adf33377005c debian/dirs --- a/debian/dirs Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -usr/bin -usr/sbin -etc/cron.daily diff -r e2559ee78cb3 -r adf33377005c debian/docs --- a/debian/docs Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -README diff -r e2559ee78cb3 -r adf33377005c debian/emacsen-install.ex --- a/debian/emacsen-install.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -#! /bin/sh -e -# /usr/lib/emacsen-common/packages/install/exigrey - -# Written by Jim Van Zandt , borrowing heavily -# from the install scripts for gettext by Santiago Vila -# and octave by Dirk Eddelbuettel . - -FLAVOR=$1 -PACKAGE=exigrey - -if [ ${FLAVOR} = emacs ]; then exit 0; fi - -echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR} - -#FLAVORTEST=`echo $FLAVOR | cut -c-6` -#if [ ${FLAVORTEST} = xemacs ] ; then -# SITEFLAG="-no-site-file" -#else -# SITEFLAG="--no-site-file" -#fi -FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile" - -ELDIR=/usr/share/emacs/site-lisp/${PACKAGE} -ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE} - -# Install-info-altdir does not actually exist. -# Maybe somebody will write it. -if test -x /usr/sbin/install-info-altdir; then - echo install/${PACKAGE}: install Info links for ${FLAVOR} - install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/info/${PACKAGE}.info.gz -fi - -install -m 755 -d ${ELCDIR} -cd ${ELDIR} -FILES=`echo *.el` -cp ${FILES} ${ELCDIR} -cd ${ELCDIR} - -cat << EOF > path.el -(setq load-path (cons "." load-path) byte-compile-warnings nil) -EOF -${FLAVOR} ${FLAGS} ${FILES} -rm -f *.el path.el - -exit 0 diff -r e2559ee78cb3 -r adf33377005c debian/emacsen-remove.ex --- a/debian/emacsen-remove.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#!/bin/sh -e -# /usr/lib/emacsen-common/packages/remove/exigrey - -FLAVOR=$1 -PACKAGE=exigrey - -if [ ${FLAVOR} != emacs ]; then - if test -x /usr/sbin/install-info-altdir; then - echo remove/${PACKAGE}: removing Info links for ${FLAVOR} - install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/info/exigrey.info.gz - fi - - echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR} - rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE} -fi diff -r e2559ee78cb3 -r adf33377005c debian/emacsen-startup.ex --- a/debian/emacsen-startup.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -;; -*-emacs-lisp-*- -;; -;; Emacs startup file, e.g. /etc/emacs/site-start.d/50exigrey.el -;; for the Debian exigrey package -;; -;; Originally contributed by Nils Naumann -;; Modified by Dirk Eddelbuettel -;; Adapted for dh-make by Jim Van Zandt - -;; The exigrey package follows the Debian/GNU Linux 'emacsen' policy and -;; byte-compiles its elisp files for each 'emacs flavor' (emacs19, -;; xemacs19, emacs20, xemacs20...). The compiled code is then -;; installed in a subdirectory of the respective site-lisp directory. -;; We have to add this to the load-path: -(let ((package-dir (concat "/usr/share/" - (symbol-name flavor) - "/site-lisp/exigrey"))) -;; If package-dir does not exist, the exigrey package must have -;; removed but not purged, and we should skip the setup. - (when (file-directory-p package-dir) - (setq load-path (cons package-dir load-path)) - (autoload 'exigrey-mode "exigrey-mode" - "Major mode for editing exigrey files." t) - (add-to-list 'auto-mode-alist '("\\.exigrey$" . exigrey-mode)))) - diff -r e2559ee78cb3 -r adf33377005c debian/exigrey-default.ex --- a/debian/exigrey-default.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -# Defaults for exigrey initscript -# sourced by /etc/init.d/exigrey -# installed at /etc/default/exigrey by the maintainer scripts - -# -# This is a POSIX shell fragment -# - -# Additional options that are passed to the Daemon. -DAEMON_OPTS="" diff -r e2559ee78cb3 -r adf33377005c debian/exigrey.doc-base.EX --- a/debian/exigrey.doc-base.EX Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -Document: exigrey -Title: Debian exigrey Manual -Author: -Abstract: This manual describes what exigrey is - and how it can be used to - manage online manuals on Debian systems. -Section: unknown - -Format: debiandoc-sgml -Files: /usr/share/doc/exigrey/exigrey.sgml.gz - -Format: postscript -Files: /usr/share/doc/exigrey/exigrey.ps.gz - -Format: text -Files: /usr/share/doc/exigrey/exigrey.text.gz - -Format: HTML -Index: /usr/share/doc/exigrey/html/index.html -Files: /usr/share/doc/exigrey/html/*.html - - diff -r e2559ee78cb3 -r adf33377005c debian/init.d.ex --- a/debian/init.d.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -#! /bin/sh -# -# skeleton example file to build /etc/init.d/ scripts. -# This file should be used to construct scripts for /etc/init.d. -# -# Written by Miquel van Smoorenburg . -# Modified for Debian -# by Ian Murdock . -# -# Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl -# - -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin -DAEMON=/usr/sbin/exigrey -NAME=exigrey -DESC=exigrey - -test -x $DAEMON || exit 0 - -# Include exigrey defaults if available -if [ -f /etc/default/exigrey ] ; then - . /etc/default/exigrey -fi - -set -e - -case "$1" in - start) - echo -n "Starting $DESC: " - start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ - --exec $DAEMON -- $DAEMON_OPTS - echo "$NAME." - ;; - stop) - echo -n "Stopping $DESC: " - start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ - --exec $DAEMON - echo "$NAME." - ;; - #reload) - # - # If the daemon can reload its config files on the fly - # for example by sending it SIGHUP, do it here. - # - # If the daemon responds to changes in its config file - # directly anyway, make this a do-nothing entry. - # - # echo "Reloading $DESC configuration files." - # start-stop-daemon --stop --signal 1 --quiet --pidfile \ - # /var/run/$NAME.pid --exec $DAEMON - #;; - force-reload) - # - # If the "reload" option is implemented, move the "force-reload" - # option to the "reload" entry above. If not, "force-reload" is - # just the same as "restart" except that it does nothing if the - # daemon isn't already running. - # check wether $DAEMON is running. If so, restart - start-stop-daemon --stop --test --quiet --pidfile \ - /var/run/$NAME.pid --exec $DAEMON \ - && $0 restart \ - || exit 0 - ;; - restart) - echo -n "Restarting $DESC: " - start-stop-daemon --stop --quiet --pidfile \ - /var/run/$NAME.pid --exec $DAEMON - sleep 1 - start-stop-daemon --start --quiet --pidfile \ - /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS - echo "$NAME." - ;; - *) - N=/etc/init.d/$NAME - # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 - echo "Usage: $N {start|stop|restart|force-reload}" >&2 - exit 1 - ;; -esac - -exit 0 diff -r e2559ee78cb3 -r adf33377005c debian/manpage.1.ex --- a/debian/manpage.1.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.\" First parameter, NAME, should be all caps -.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -.\" other parameters are allowed: see man(7), man(1) -.TH EXIGREY SECTION "Januar 1, 2007" -.\" Please adjust this date whenever revising the manpage. -.\" -.\" Some roff macros, for reference: -.\" .nh disable hyphenation -.\" .hy enable hyphenation -.\" .ad l left justify -.\" .ad b justify to both left and right margins -.\" .nf disable filling -.\" .fi enable filling -.\" .br insert line break -.\" .sp insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -exigrey \- program to do something -.SH SYNOPSIS -.B exigrey -.RI [ options ] " files" ... -.br -.B bar -.RI [ options ] " files" ... -.SH DESCRIPTION -This manual page documents briefly the -.B exigrey -and -.B bar -commands. -.PP -.\" TeX users may be more comfortable with the \fB\fP and -.\" \fI\fP escape sequences to invode bold face and italics, -.\" respectively. -\fBexigrey\fP is a program that... -.SH OPTIONS -These programs follow the usual GNU command line syntax, with long -options starting with two dashes (`-'). -A summary of options is included below. -For a complete description, see the Info files. -.TP -.B \-h, \-\-help -Show summary of options. -.TP -.B \-v, \-\-version -Show version of program. -.SH SEE ALSO -.BR bar (1), -.BR baz (1). -.br -The programs are documented fully by -.IR "The Rise and Fall of a Fooish Bar" , -available via the Info system. -.SH AUTHOR -exigrey was written by . -.PP -This manual page was written by Heiko Schlittermann , -for the Debian project (but may be used by others). diff -r e2559ee78cb3 -r adf33377005c debian/manpage.sgml.ex --- a/debian/manpage.sgml.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ - manpage.1'. You may view - the manual page with: `docbook-to-man manpage.sgml | nroff -man | - less'. A typical entry in a Makefile or Makefile.am is: - -manpage.1: manpage.sgml - docbook-to-man $< > $@ - - - The docbook-to-man binary is found in the docbook-to-man package. - Please remember that if you create the nroff version in one of the - debian/rules file targets (such as build), you will need to include - docbook-to-man in your Build-Depends control field. - - --> - - - FIRSTNAME"> - SURNAME"> - - Januar 1, 2007"> - - SECTION"> - heiko@schlittermann.de"> - - EXIGREY"> - - - Debian"> - GNU"> - GPL"> -]> - - - -
- &dhemail; -
- - &dhfirstname; - &dhsurname; - - - 2003 - &dhusername; - - &dhdate; -
- - &dhucpackage; - - &dhsection; - - - &dhpackage; - - program to do something - - - - &dhpackage; - - - - - - - - DESCRIPTION - - This manual page documents briefly the - &dhpackage; and bar - commands. - - This manual page was written for the &debian; distribution - because the original program does not have a manual page. - Instead, it has documentation in the &gnu; - Info format; see below. - - &dhpackage; is a program that... - - - - OPTIONS - - These programs follow the usual &gnu; command line syntax, - with long options starting with two dashes (`-'). A summary of - options is included below. For a complete description, see the - Info files. - - - - - - - - Show summary of options. - - - - - - - - Show version of program. - - - - - - SEE ALSO - - bar (1), baz (1). - - The programs are documented fully by The Rise and - Fall of a Fooish Bar available via the - Info system. - - - AUTHOR - - This manual page was written by &dhusername; &dhemail; for - the &debian; system (but may be used by others). Permission is - granted to copy, distribute and/or modify this document under - the terms of the &gnu; General Public License, Version 2 any - later version published by the Free Software Foundation. - - - On Debian systems, the complete text of the GNU General Public - License can be found in /usr/share/common-licenses/GPL. - - - -
- - - - diff -r e2559ee78cb3 -r adf33377005c debian/manpage.xml.ex --- a/debian/manpage.xml.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ - -.
will be generated. You may view the -manual page with: nroff -man .
| less'. A -typical entry in a Makefile or Makefile.am is: - -DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\ -manpages/docbook.xsl -XP=xsltproc -''-nonet - -manpage.1: manpage.dbk - $(XP) $(DB2MAN) $< - -The xsltproc binary is found in the xsltproc package. The -XSL files are in docbook-xsl. Please remember that if you -create the nroff version in one of the debian/rules file -targets (such as build), you will need to include xsltproc -and docbook-xsl in your Build-Depends control field. - ---> - - - FIRSTNAME"> - SURNAME"> - - Januar 1, 2007"> - - SECTION"> - heiko@schlittermann.de"> - - EXIGREY"> - - - Debian"> - GNU"> - GPL"> -]> - - - -
- &dhemail; -
- - &dhfirstname; - &dhsurname; - - - 2003 - &dhusername; - - &dhdate; -
- - &dhucpackage; - - &dhsection; - - - &dhpackage; - - program to do something - - - - &dhpackage; - - - - - - - - DESCRIPTION - - This manual page documents briefly the - &dhpackage; and bar - commands. - - This manual page was written for the &debian; distribution - because the original program does not have a manual page. - Instead, it has documentation in the &gnu; - Info format; see below. - - &dhpackage; is a program that... - - - - OPTIONS - - These programs follow the usual &gnu; command line syntax, - with long options starting with two dashes (`-'). A summary of - options is included below. For a complete description, see the - Info files. - - - - - - - - Show summary of options. - - - - - - - - Show version of program. - - - - - - SEE ALSO - - bar (1), baz (1). - - The programs are documented fully by The Rise and - Fall of a Fooish Bar available via the - Info system. - - - AUTHOR - - This manual page was written by &dhusername; &dhemail; for - the &debian; system (but may be used by others). Permission is - granted to copy, distribute and/or modify this document under - the terms of the &gnu; General Public License, Version 2 any - later version published by the Free Software Foundation. - - - On Debian systems, the complete text of the GNU General Public - License can be found in /usr/share/common-licenses/GPL. - - - -
- diff -r e2559ee78cb3 -r adf33377005c debian/menu.ex --- a/debian/menu.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -?package(exigrey):needs="X11|text|vc|wm" section="Apps/see-menu-manual"\ - title="exigrey" command="/usr/bin/exigrey" diff -r e2559ee78cb3 -r adf33377005c debian/postinst --- a/debian/postinst Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -#!/bin/sh -# postinst script for exigrey -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `configure' -# * `abort-upgrade' -# * `abort-remove' `in-favour' -# -# * `abort-remove' -# * `abort-deconfigure' `in-favour' -# `removing' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - configure) - if test -e /etc/exim4/exim4.conf; then - a=$(exim4 -bP perl_startup) || true - if expr "$a" : "/etc/exim4/exigrey" >/dev/null; then - perl -i.$(date -I) -pe \ - 's/perl_startup.*/perl_startup = do "/usr/share/exim4/exigrey.pl"' \ - /etc/exim4/exim4.conf - fi - fi - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff -r e2559ee78cb3 -r adf33377005c debian/postinst.ex --- a/debian/postinst.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -#!/bin/sh -# postinst script for exigrey -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `configure' -# * `abort-upgrade' -# * `abort-remove' `in-favour' -# -# * `abort-remove' -# * `abort-deconfigure' `in-favour' -# `removing' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - configure) - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff -r e2559ee78cb3 -r adf33377005c debian/postrm --- a/debian/postrm Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -#!/bin/sh -# postrm script for exigrey -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `remove' -# * `purge' -# * `upgrade' -# * `failed-upgrade' -# * `abort-install' -# * `abort-install' -# * `abort-upgrade' -# * `disappear' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - purge) - # try to find the db file in the default place - dir=`exim4 -be '$spool_directory'` || exit 0 - test -d "$dir/grey" || exit 0 - rm -f "$dir/grey/"* || true - rmdir "$dir/grey" || true - left=`find "$dir/grey" 2>/dev/null | wc` || true - test -n "$x" && echo "Some files are left in $dir/grey!" >&2 - ;; - - remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff -r e2559ee78cb3 -r adf33377005c debian/postrm.ex --- a/debian/postrm.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -#!/bin/sh -# postrm script for exigrey -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `remove' -# * `purge' -# * `upgrade' -# * `failed-upgrade' -# * `abort-install' -# * `abort-install' -# * `abort-upgrade' -# * `disappear' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff -r e2559ee78cb3 -r adf33377005c debian/preinst.ex --- a/debian/preinst.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -#!/bin/sh -# preinst script for exigrey -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `install' -# * `install' -# * `upgrade' -# * `abort-upgrade' -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - install|upgrade) - ;; - - abort-upgrade) - ;; - - *) - echo "preinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff -r e2559ee78cb3 -r adf33377005c debian/prerm.ex --- a/debian/prerm.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -#!/bin/sh -# prerm script for exigrey -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `remove' -# * `upgrade' -# * `failed-upgrade' -# * `remove' `in-favour' -# * `deconfigure' `in-favour' -# `removing' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - remove|upgrade|deconfigure) - ;; - - failed-upgrade) - ;; - - *) - echo "prerm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff -r e2559ee78cb3 -r adf33377005c debian/rules --- a/debian/rules Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -#!/bin/sh - -echo "NOT YET. Debian package generation needs to be re-done" -exit 1 - -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - - - -CFLAGS = -Wall -g - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif - -configure: configure-stamp -configure-stamp: - dh_testdir - # Add here commands to configure the package. - - touch configure-stamp - - -build: build-stamp - -build-stamp: configure-stamp - dh_testdir - - # Add here commands to compile the package. - $(MAKE) prefix=/usr exim=exim4 - #docbook-to-man debian/exigrey.sgml > exigrey.1 - - touch $@ - -clean: - dh_testdir - dh_testroot - rm -f build-stamp configure-stamp - - # Add here commands to clean up after the build process. - -$(MAKE) clean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - # Add here commands to install the package into debian/exigrey. - $(MAKE) \ - prefix=/usr \ - exim=exim4 \ - DESTDIR=$(CURDIR)/debian/exigrey \ - install - - install -m755 cron.daily.ex $(CURDIR)/debian/exigrey/etc/cron.daily/exigrey - - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples -# dh_install -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installpam -# dh_installmime -# dh_python -# dh_installinit - dh_installcron -# dh_installinfo - dh_installman - dh_link - dh_strip - dh_compress - dh_fixperms -# dh_perl -# dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure diff -r e2559ee78cb3 -r adf33377005c debian/watch.ex --- a/debian/watch.ex Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -# Example watch control file for uscan -# Rename this file to "watch" and then you can run the "uscan" command -# to check for upstream updates and more. -# See uscan(1) for format - -# Compulsory line, this is a version 3 file -version=3 - -# Uncomment to examine a Webpage -# -#http://www.example.com/downloads.php exigrey-(.*)\.tar\.gz - -# Uncomment to examine a Webserver directory -#http://www.example.com/pub/exigrey-(.*)\.tar\.gz - -# Uncommment to examine a FTP server -#ftp://ftp.example.com/pub/exigrey-(.*)\.tar\.gz debian uupdate - -# Uncomment to find new files on sourceforge, for debscripts >= 2.9 -# http://sf.net/exigrey/exigrey-(.*)\.tar\.gz - - diff -r e2559ee78cb3 -r adf33377005c lib/Exim/Grey.pm --- a/lib/Exim/Grey.pm Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,346 +0,0 @@ -package Exim::Grey; -# for usage please see at the end - -use strict; -use warnings; -use base 'Exporter'; -use Carp; - -our @EXPORT_OK = qw(unseen seen getDBDir connectDB getDefault); -our %EXPORT_TAGS = (all => \@EXPORT_OK,); -our $VERSION = '2.0'; - -our $verbose; - -sub verbose { - return if not $verbose; - print STDERR __PACKAGE__ . ': ' . map { s/\0//gr } @_, "\n"; -} - -sub exim_bool { $_[0] ? 'yes' : 'no' } - -# You may choose, but DB_File's footprint is smaller. -# perl -MDB_File -e 'tie %h, ...': real 0m0.063s -# perl -MBerkeleyDB -e 'tie %h, ...': real 0m0.112s -# And DB_File is part of the Perl core distribution (?) -# use BerkeleyDB; -# use DB_File; -# -# But we need locking! DB_File::Lock isn't part of the corelist. -use DB_File::Lock; - -my %DEFAULT = ( - delay => 600, - db => 'seen', -); - -# some helper functions -sub getDBDir(); -sub findExim(;$); -sub connectDB($$); -sub getDefault() { %DEFAULT } - -# dbm file is relativ to $spool_directory/grey, EXCEPT its name -# starts with "/". - -sub unseen_ { - my $item = shift; - my $delay = shift // $DEFAULT{delay}; - my $db = shift // $DEFAULT{db}; - my $now = time(); - my ($auto) = $item =~ /.*?\/(.+?)$/ # remember the / from the item - and $item =~ s/\/.*?$//; # and remove it from the item - my $rc; - - connectDB(\my %h, $db); - - return 1 # not unseen, ergo known - if defined $auto and is_whitelisted($auto, \%h); - - my $key = "$item\0"; # for compatibility with Exim's dbm functions - - # We do not know anything about the client -> unknown. - # But remember that key with the associated "auto" subkey - if (not exists $h{$key}) { - $h{$key} = serialize(t0 => $now, t1 => $now, count => 0, auto => [defined $auto ? $auto : ()]); - - verbose "unseen: $item" if $verbose; - return 1; - } - - my %entry = deserialize($h{$key}); - - # we know the client, but last contact was recently (too fast) - # should we add it to our list auto entries too? - if ($now - $entry{t0} < $delay) { - return 1; - } - - # we know the client, was patiently enough - whitelist(\%h, uniq($auto, $entry{auto})) if defined $auto; - $entry{count}++; - $h{$key} = $_ = serialize(%entry); - verbose "seen: $_" if $verbose; - return 0; -} - -sub unseen { exim_bool unseen_ @_ } -sub seen { exim_bool !unseen_ @_ } - -# According to a thought from "David Woodhouse " -# on exim-users@exim.org (Thu, 08 May 2008 13:10:21 +0100, -# Message-Id: <1210248621.25560.1088.camel@pmac.infradead.org>) we -# should have the ability to "auto whitelist" hosts which are known -# for retries, because there is no benefit in greylisting them. -# -# Most safe approach would be something based on message id. -# If we see the message id a second time it indicates successful retry. -# But we do not see the message id the first time we reject the message. - -# This function has to be called twice per message delivery attempt -# <$sender_host_address> <$sender_helo_name> -# (Where is something like <$sender_address>+<$local_part@$domain> -# If we see the same message a second time (same message means here: -# same greylist criteria - -sub whitelist { - my ($h, @items) = (shift, uniq(@_)); - my $now = time; - warn __PACKAGE__ . ": whitelist: @items\n" - if $verbose; - $h->{"$_\0"} = "$now $now 1 auto\0" - foreach uniq(@items); -} - -sub uniq { - my %h = map { $_, undef } @_; - return keys %h; -} - -sub is_whitelisted { - my ($item, $h) = @_; - my $key = "$item\0"; - - warn __PACKAGE__ . 'is ' - . (exists $h->{$key} ? '' : 'not') - . "whitelisted: $item\n" if $verbose; - - return 0 if not exists $h->{$key}; - - my ($t0, undef, $cnt, $flag) = split /[ \0]/, $h->{$key}; - $h->{$key} = join(' ' => $t0, time, ++$cnt, $flag ? $flag : ()) . "\0"; - - - return 1; -} - -# Get the directory where we could store the database file(s) -# If we're running under exim it's easy, otherwise we've to find exim -# and then ask... -sub getDBDir() { - my ($spooldir, $dbdir); - eval { $spooldir = Exim::expand_string('$spool_directory') }; - if (not defined $spooldir) { - my $exim = findExim(); - chomp($spooldir = `$exim -be '\$spool_directory'`); - die "Can't find spooldir" if not defined $spooldir; - } - -d ($dbdir = "$spooldir/grey") and return $dbdir; - - my ($mode, $owner, $group) = (stat $spooldir)[2, 4, 5]; - { - local $) = $group; - local $> = $owner; - $mode &= 0777; - mkdir $dbdir, $mode or die "Can't create $dbdir: $!"; - } - return $dbdir; -} - -sub findExim(;$) { - my $path = shift || $ENV{PATH}; - my $exim; - foreach (split /:/, $ENV{PATH}) { - -x ($exim = "$_/exim") and return $exim; - -x ($exim = "$_/exim4") and return $exim; - } - die "Can't find exim binary (missing .../sbin dirs in PATH?"; -} - -sub connectDB($$) { - my ($h, $db) = @_; - $db = getDBDir() . "/$db" unless $db =~ m(^/); - - # Creation of DB-File if it doesn't exist - # to avoid races we change our own uid/gid for creation of - # this file. - if (!-f $db) { - (my $dir = $db) =~ s/^(.*)\/.*?$/$1/; - - # copy mode, uid, gid from the directory - my ($mode, $user, $group) = (stat $dir)[2, 4, 5] - or die "Can't stat $dir: $!"; - my $umask = umask(($mode & 0777) ^ 0777); - local $) = $group; - local $> = $user; - open(X, ">>$db") or die "Can't create $db: $!"; - close(X); - umask $umask; - } - - # now test which of the DB-Modules has been loaded - - if (exists &BerkeleyDB::Hash::TIEHASH) { - no strict; - my $umask = umask 077; - tie %$h, "BerkeleyDB::Hash", -Filename => $db - or die "$0: $db: $!"; - return $db; - } - - if (exists &DB_File::Lock::TIEHASH) { - tie %$h, 'DB_File::Lock', [$db], 'write' - or die "$0: $db: $!"; - return $db; - } - - if (exists &DB_File::TIEHASH) { - tie %$h, 'DB_File', $db or die "$0: $db: $!"; - warn "$0: using DB_File, no locking is possible!\n"; - return $db; - } - - die "Can't connect to database driver"; -} - -# These two functions do not truly serialize/de-serialize the data -# passed. They're specialiased to a fixed data format: -# serialized: [auto=[,]...] -# structured: ( -# t0 => , -# t1 => , -# count => , -# auto => [item, item, …], -# ) -sub serialize { - my %data = @_; - my $auto = (ref $data{auto} && @{$data{auto}}) ? join ',', @{$data{auto}} : ''; - return "$data{t0} $data{t1} $data{count} auto=$auto\0"; -} - -sub deserialize { - my @data = split / /, $_[0] =~ s/\0$//r; - my %data; - ($data{t0}, $data{t1}, $data{count}) = splice @data, 0, 3; - if ($data[0] =~ /^auto=(.*)/) { - $data{auto} = [split /,/, $1]; - } - return %data; -} - -1; - -__END__ -=head1 NAME - - Exim::Grey - -=head1 SYNOPSIS - - perl_startup use Exim::Grey qw(unseen); - ... - acl rcpt - defer condition = ${perl{unseen}{<$sender_address>:<$local_part@$domain>}} - -=head1 DESCRIPTION - -This is a module to be loade by Exim, the MTA. On request it exports -a single function C. This function may be used in the ACL section -to support greylisting. - -=head1 FUNCTIONS - -=over - -=item scalar B(I, I, I) - -This function returns I if the key is already known in the I database -for the minimum I time. (Note: The database may be cleaned regularly by -the compangion L tool.) - -The I is mandotory, the default I is 600 seconds and the default I -is called F. - -I may contain a suffix, separated by "/". This suffix is used for -automatic whitelisting. - -=item scalar B(I, I, I) - -The same as C, but with reversed result. - -=back - -=head1 EXAMPLES - -=head2 Greylisting - -First you have to include B into your Exim. If Exim is built with Perl -support, the configuration syntax allows for C: - - perl_startup = use Exim::Grey qw(unseen); - -In the ACL section of the configuration can check if a given key (sender, or combination -of sender and recipient, or whatever) is new (unseen): - - defer condition = ${perl{unseen}{<$sender_address>:$}} - -If the same condition is checked more then I later, the C function returns -false. - -=head2 Greylisting + automatic whitelisting - -Greylisting gets annoying if you do it for senders that are already known to retry. Thus it might be -good to maintain a whitelist. You may use a suffix to your key, separated by "/". Once the greylist -filter is passed, the used suffixes are registered with the whitelist. - - t - | - 0 a->b/x # a->b never seen, suffix never seen: greylist - 1 a->b/y # a->b again: accept AND put x and y to the whitelist, - | # as they are known to retry - 2 c->b/x # c->b unknown, but x is already whitelisted: accept - 3 d->b/y # d->b unknown, but y is already whitelisted: accept - | - v - -This can be implemented in your ACL as: - - defer condition = ${perl{unseen}{<$sender_address>:$/$sender_host_address}} - -But, if I and I are the sender and the recipient address, and the -subkey is the sender host address, a spammer might send a forged message -after t0, to get whitelisted. - -=head1 INTERNALS - -=head2 Format of the database - -The record structure is - - key: item\0 - value: timestamp(creation) timestamp(usage) counter[ flags]\0 - -This way we are compatible with ${lookup{...}dbm{...}} - -=head1 FILES - -The database files are placed in C<$spool_directory/grey/>. - -=head1 SEE ALSO - -The companion tool L should be used for inspection and manipulation -of the database. - -=cut - -# vim:aw et sw=4 ts=4: diff -r e2559ee78cb3 -r adf33377005c t/10-interface.tt --- a/t/10-interface.tt Wed Jun 21 00:26:46 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -use strict; -use warnings; - -use Test::More qw(no_plan); -use File::Temp; - -use_ok 'Exim::Grey' => qw(unseen seen) or BAIL_OUT; - -subtest 'simple' => sub { - my $db = File::Temp->new(); - is seen('a->x', 0, "$db"), 'no' => 'not seen a->x'; - is unseen('a->b', 0, "$db"), 'yes' => 'unseen a->b'; - is unseen('a->b', 600, "$db"), 'yes' => 'unseen a->b with 600s delay'; - is unseen('a->b', 0, "$db"), 'no' => 'not unseen a->b'; - is seen('a->b', 600, "$db"), 'no' => 'not seen a->b with 600s delay'; -}; - -subtest 'whitelist' => sub { - my $db = File::Temp->new(); - is unseen('x->y/1.1.1.1', 1, "$db"), 'yes' => 'unseen x->y/1.1.1.1'; - is unseen('x->y/1.1.1.1', 1, "$db"), 'yes' => 'unseen x->y/1.1.1.1'; - - is seen('x->y/1.1.1.1', 0, "$db"), 'yes' => 'seen x->y/1.1.1.1'; - is seen('x->z/1.1.1.1', 0, "$db"), 'yes' => 'seen x->z/1.1.1.1 (subkey known)'; - is seen('1.1.1.1', 0, "$db"), 'yes' => 'seen 1.1.1.1'; - -}; -__END__ - -subtest 'whitelist multiple subkeys' => sub { - my $db = File::Temp->new(); - - is unseen('x->y/1.1.1.1', 0, "$db"), 'yes' => 'unseen x->y/1.1.1.1'; - is unseen('x->y/2.2.2.2', 3, "$db"), 'yes' => 'unseen x->y/3.3.3.3'; - is unseen('x->y/3.3.3.3', 0, "$db"), 'no' => 'not unseen x->y/2.2.2.2'; - - is unseen('a->b/1.1.1.1', 0, "$db"), 'no' => 'not unseen (whitelisted source)'; - is unseen('a->c/2.2.2.2', 0, "$db"), 'no' => 'not unseen (whitelisted source)'; - is unseen('x->y/3.3.3.3', 0, "$db"), 'no' => 'not unseen x->y/3.3.3.3 (known key)'; -};