$ git am /tmp/285.eml
Applying: added p0f support to greylisting
fatal: corrupt patch at line 12
Patch failed at 0001 added p0f support to greylisting
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".

Also, this change appears to have some minor things unrelated to p0f
in it.

-R

Matt Simerson wrote:
> 
> 
> added p0f support to greylisting, so that greylisting can be done
> selectively.
> greylisting DB location wasn't being set in tests, added '.' to
> candidate list
> added sample greylisting entry to config/plugins, disabled by default
> 
> ---
> config.sample/plugins |    1 +
> plugins/greylisting |   57
> ++++++++++++++++++++++++++++++++++++++++++++ ++----
> 2 files changed, 51 insertions(+), 5 deletions(-)
> 
> diff --git a/config.sample/plugins b/config.sample/plugins
> index 0b51124..6a01ba0 100644
> --- a/config.sample/plugins
> +++ b/config.sample/plugins
> @@ -34,6 +34,7 @@ check_badrcptto
> check_spamhelo
> 
> # sender_permitted_from
> +# greylisting p0f genre,windows
> 
> auth/auth_flat_file
> auth/authdeny
> -- 
> 
> diff --git a/plugins/greylisting b/plugins/greylisting
> index 2bdfbc1..f84826e 100644
> --- a/plugins/greylisting
> +++ b/plugins/greylisting
> @@ -105,6 +105,23 @@ Flag to indicate whether to use per-recipient
> greylisting
> databases (default is to use a shared database).  Per-recipient
> configuration
> directories, if determined, supercede I<db_dir>.
> 
> +=item p0f
> +
> +Enable greylisting only when certain p0f criteria is met. The single
> +required argument is a comma delimited list of key/value pairs. The
> keys
> +are the following p0f TCP fingerprint elements: genre, detail, uptime,
> +link, and distance.
> +
> +To greylist emails from computers whose remote OS is windows, you'd use
> +this syntax:
> +
> +  p0f genre,windows
> +
> +To greylist only windows computers on DSL links more than 3 network
> hops
> +away:
> +
> +  p0f genre,windows,link,dsl,distance,3
> +
> =back
> 
> =head1 BUGS
> @@ -117,6 +134,8 @@ use something like File::NFSLock instead.
> 
> Written by Gavin Carr <ga...@openfusion.com.au>.
> 
> +Added p0f section <mattsimer...@cpan.org> (2010-05-03)
> +
> =cut
> 
> BEGIN { @AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File) }
> @@ -124,13 +143,13 @@ use AnyDBM_File;
> use Fcntl qw(:DEFAULT :flock);
> use strict;
> 
> -my $VERSION = '0.07';
> +my $VERSION = '0.08';
> 
> my $DENYMSG = "This mail is temporarily denied";
> my ($QPHOME) = ($0 =~ m!(.*?)/([^/]+)$!);
> my $DB = "denysoft_greylist.dbm";
> my %PERMITTED_ARGS = map { $_ => 1 } qw(per_recipient remote_ip sender
> recipient
> -  black_timeout grey_timeout white_timeout deny_late mode db_dir);
> +  black_timeout grey_timeout white_timeout deny_late mode db_dir p0f );
> 
> my %DEFAULTS = (
>                  remote_ip     => 1,
> @@ -140,6 +159,7 @@ my %DEFAULTS = (
>                  grey_timeout  => 3 * 3600 + 20 * 60,
>                  white_timeout => 36 * 24 * 3600,
>                  mode          => 'denysoft',
> +                p0f           => undef,
>                 );
> 
> sub register {
> @@ -224,17 +244,23 @@ sub denysoft_greylist {
>      return DECLINED if $self->qp->connection->notes('whitelisthost');
>      return DECLINED if $transaction->notes('whitelistsender');
> 
> +    # do not greylist if p0f matching is selected and message does
> not match
> +    return DECLINED if $config->{'p0f'} && !$self-
>  >p0f_match( $config );
> +
>      if ($config->{db_dir} && $config->{db_dir} =~ m{^([-a-zA-Z0-9./_]
>      +)$}) {
>          $config->{db_dir} = $1;
>      }
> 
>      # Setup database location
> -    my $dbdir = $transaction->notes('per_rcpt_configdir')
> +    my $dbdir;
> +    $dbdir = $transaction->notes('per_rcpt_configdir')
>        if $config->{per_recipient_db};
>      for my $d ($dbdir, $config->{db_dir}, "/var/lib/qpsmtpd/
>      greylisting",
> -               "$QPHOME/var/db", "$QPHOME/config")
> +               "$QPHOME/var/db", "$QPHOME/config", "." )
>      {
> -        last if $dbdir ||= $d && -d $d && $d;
> +        last if $dbdir && -d $dbdir;
> +        next if ( ! $d || ! -d $d );
> +        $dbdir = $d;
>      }
>      my $db = "$dbdir/$DB";
>      $self->log(LOGINFO, "using $db as greylisting database");
> @@ -316,5 +342,26 @@ sub denysoft_greylist {
>      return $config->{mode} eq 'testonly' ? DECLINED : DENYSOFT,
>      $DENYMSG;
> }
> 
> +sub p0f_match {
> +    my $self = shift;
> +    my $config = shift;
> +
> +    my $p0f = $self->connection->notes('p0f');
> +    return if !$p0f || !ref $p0f;     # p0f fingerprint info not found
> +
> +    my %valid_matches = map { $_ => 1 } qw( genre detail uptime link
> distance );
> +    my %requested_matches = split(/\,/, $config->{'p0f'} );
> +
> +    foreach my $key (keys %requested_matches) {
> +        next if !defined $valid_matches{$key}; # discard invalid
> match keys
> +        my $value = $requested_matches{$key};
> +        return 1 if $key eq 'distance' && $p0f->{$key} > $value;
> +        return 1 if $key eq 'genre'    && $p0f->{$key} =~ /$value/i;
> +        return 1 if $key eq 'uptime'   && $p0f->{$key} < $value;
> +        return 1 if $key eq 'link'     && $p0f->{$key} =~ /$value/i;
> +    }
> +    return;
> +}
> +
> # arch-tag: 6ef5919e-404b-4c87-bcfe-7e9f383f3901
> 
> -- 
> 1.7.0.6
> 
> 
> greylisting p0f tests
> 
> 
> ---
> MANIFEST |    1 +
> t/plugin_tests/greylisting |  111
> +++++++++++++++++++++++++++++++++++++ +++++++
> 2 files changed, 112 insertions(+), 0 deletions(-)
> create mode 100644 t/plugin_tests/greylisting
> 
> diff --git a/MANIFEST b/MANIFEST
> index 0e0565b..8d06c5d 100644
> --- a/MANIFEST
> +++ b/MANIFEST
> @@ -147,6 +147,7 @@ t/plugin_tests/auth/authdeny
> t/plugin_tests/auth/authnull
> t/plugin_tests/check_badrcptto
> t/plugin_tests/dnsbl
> +t/plugin_tests/greylisting
> t/plugin_tests/rcpt_ok
> t/qpsmtpd-address.t
> t/rset.t
> -- 
> 
> diff --git a/t/plugin_tests/greylisting b/t/plugin_tests/greylisting
> new file mode 100644
> index 0000000..38ed08b
> --- /dev/null
> +++ b/t/plugin_tests/greylisting
> @@ -0,0 +1,111 @@
> +use Qpsmtpd::Address;
> +
> +my $test_email = 'u...@example.com';
> +my $address = Qpsmtpd::Address->new( "<$test_email>" );
> +
> +my @greydbs = qw( denysoft_greylist.dbm denysoft_greylist.dbm.lock );
> +foreach ( @greydbs ) {
> +    unlink $_ if -f $_;
> +};
> +
> +sub register_tests {
> +    my $self = shift;
> +    $self->register_test("test_greylist_p0f_genre_miss", 1);
> +    $self->register_test("test_greylist_p0f_genre_hit", 1);
> +    $self->register_test("test_greylist_p0f_distance_hit", 1);
> +    $self->register_test("test_greylist_p0f_distance_miss", 1);
> +    $self->register_test("test_greylist_p0f_link_hit", 1);
> +    $self->register_test("test_greylist_p0f_link_miss", 1);
> +    $self->register_test("test_greylist_p0f_uptime_hit", 1);
> +    $self->register_test("test_greylist_p0f_uptime_miss", 1);
> +}
> +
> +sub test_greylist_p0f_genre_miss {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'genre,Linux';
> +    $self->connection->notes('p0f'=> { genre => 'windows', link =>
> 'dsl' } );
> +    my $r = $self->rcpt_handler( $self->qp->transaction );
> +
> +    ok( $r == 909, 'p0f genre miss');
> +}
> +
> +sub test_greylist_p0f_genre_hit {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'genre,Windows';
> +    $self->connection->notes('p0f'=> { genre => 'windows', link =>
> 'dsl' } );
> +    $self->qp->transaction->sender( $address );
> +    my $r = $self->rcpt_handler( $self->qp->transaction  );
> +
> +    ok( $r eq 'This mail is temporarily denied', 'p0f genre hit');
> +}
> +
> +sub test_greylist_p0f_distance_hit {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'distance,8';
> +    $self->connection->notes('p0f'=> { distance=>9 } );
> +    $self->qp->transaction->sender( $address );
> +    my $r = $self->rcpt_handler( $self->qp->transaction  );
> +
> +    ok( $r eq 'This mail is temporarily denied', 'p0f distance hit');
> +}
> +
> +sub test_greylist_p0f_distance_miss {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'distance,8';
> +    $self->connection->notes('p0f'=> { distance=>7 } );
> +    $self->qp->transaction->sender( $address );
> +    my $r = $self->rcpt_handler( $self->qp->transaction  );
> +
> +    ok( $r == 909, 'p0f distance miss');
> +}
> +
> +sub test_greylist_p0f_link_hit {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'link,dsl';
> +    $self->connection->notes('p0f'=> { link=>'DSL' } );
> +    $self->qp->transaction->sender( $address );
> +    my $r = $self->rcpt_handler( $self->qp->transaction  );
> +
> +    ok( $r eq 'This mail is temporarily denied', 'p0f link hit');
> +}
> +
> +sub test_greylist_p0f_link_miss {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'link,dsl';
> +    $self->connection->notes('p0f'=> { link=>'Ethernet' } );
> +    $self->qp->transaction->sender( $address );
> +    my $r = $self->rcpt_handler( $self->qp->transaction  );
> +
> +    ok( $r == 909, 'p0f link miss');
> +}
> +
> +sub test_greylist_p0f_uptime_hit {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'uptime,100';
> +    $self->connection->notes('p0f'=> { uptime=> 99 } );
> +    $self->qp->transaction->sender( $address );
> +    my $r = $self->rcpt_handler( $self->qp->transaction  );
> +
> +    ok( $r eq 'This mail is temporarily denied', 'p0f uptime hit');
> +}
> +
> +sub test_greylist_p0f_uptime_miss {
> +    my $self = shift;
> +
> +    $self->{_greylist_config}{'p0f'} = 'uptime,100';
> +    $self->connection->notes('p0f'=> { uptime=>500 } );
> +    $self->qp->transaction->sender( $address );
> +    my $r = $self->rcpt_handler( $self->qp->transaction  );
> +
> +    ok( $r == 909, 'p0f uptime miss');
> +}
> +
> +
> +
> -- 
> 1.7.0.6
> 
> 

Reply via email to