p0f: tests, tests, tests, backward compat
minor changes to facilitate testing improved error reporting of several failures added p0f v2 compatibility to p0f v3 results: in addition to all the newer values, also report the old ones too.
This commit is contained in:
parent
25a099e20b
commit
c3d1f6b16e
@ -147,7 +147,7 @@ sub register {
|
||||
sub hook_connect {
|
||||
my($self, $qp) = @_;
|
||||
|
||||
my $p0f_version = $self->{_args}->{version} || 3;
|
||||
my $p0f_version = $self->{_args}{version} || 3;
|
||||
if ( $p0f_version == 3 ) {
|
||||
my $response = $self->query_p0f_v3() or return DECLINED;
|
||||
$self->test_v3_response( $response ) or return DECLINED;
|
||||
@ -186,7 +186,10 @@ sub get_v2_query {
|
||||
sub get_v3_query {
|
||||
my $self = shift;
|
||||
|
||||
my $src_ip = $self->qp->connection->remote_ip;
|
||||
my $src_ip = $self->qp->connection->remote_ip or do {
|
||||
$self->log( LOGERROR, "unable to determine remote IP");
|
||||
return;
|
||||
};
|
||||
|
||||
if ( $src_ip =~ /:/ ) { # IPv6
|
||||
my @bits = split(/\:/, $src_ip );
|
||||
@ -200,8 +203,11 @@ sub get_v3_query {
|
||||
sub query_p0f_v3 {
|
||||
my $self = shift;
|
||||
|
||||
my $p0f_socket = $self->{_args}->{p0f_socket} or return;
|
||||
my $query = $self->get_v3_query();
|
||||
my $p0f_socket = $self->{_args}{p0f_socket} or do {
|
||||
$self->log(LOGERROR, "socket not defined in config.");
|
||||
return;
|
||||
};
|
||||
my $query = $self->get_v3_query() or return;
|
||||
|
||||
# Open the connection to p0f
|
||||
my $sock;
|
||||
@ -325,6 +331,7 @@ sub store_v2_results {
|
||||
$self->qp->connection->notes('p0f', $p0f);
|
||||
$self->log(LOGINFO, $genre." (".$detail.")");
|
||||
$self->log(LOGERROR,"error: $@") if $@;
|
||||
return $p0f;
|
||||
};
|
||||
|
||||
sub store_v3_results {
|
||||
@ -341,10 +348,16 @@ sub store_v3_results {
|
||||
next if ! defined $values[$i];
|
||||
$r{ $labels[$i] } = $values[$i];
|
||||
};
|
||||
|
||||
$self->qp->connection->notes('p0f', \%r);
|
||||
$self->log(LOGINFO, "$values[12] $values[13]");
|
||||
$self->log(LOGDEBUG, join(' ', @values ));
|
||||
$self->log(LOGERROR,"error: $@") if $@;
|
||||
if ( $r{os_name} ) { # compat with p0f v2
|
||||
$r{genre} = "$r{os_name} $r{os_flavor}";
|
||||
$r{link} = $r{link_type} if $r{link_type};
|
||||
$r{uptime} = $r{uptime_min} if $r{uptime_min};
|
||||
};
|
||||
|
||||
$self->qp->connection->notes('p0f', \%r);
|
||||
$self->log(LOGINFO, "$r{os_name} $r{os_flavor}");
|
||||
$self->log(LOGDEBUG, join(' ', @values ));
|
||||
$self->log(LOGERROR,"error: $@") if $@;
|
||||
return \%r;
|
||||
};
|
||||
|
||||
|
87
t/plugin_tests/ident/p0f
Normal file
87
t/plugin_tests/ident/p0f
Normal file
@ -0,0 +1,87 @@
|
||||
#!perl -w
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Qpsmtpd::Constants;
|
||||
|
||||
sub register_tests {
|
||||
my $self = shift;
|
||||
|
||||
$self->register_test('test_get_v2_query', 1);
|
||||
$self->register_test('test_get_v3_query', 1);
|
||||
$self->register_test('test_store_v2_results', 2);
|
||||
$self->register_test('test_store_v3_results', 2);
|
||||
}
|
||||
|
||||
sub test_query_p0f_v2 {
|
||||
#TODO
|
||||
# get path to p0f socket
|
||||
# see if it exists
|
||||
# try to connect to it
|
||||
# if connection succeeds, send it a query
|
||||
# do we a) pick an IP that recently connected?
|
||||
# or b) create a connection to localhost...
|
||||
# or c) is there a p0f test value?
|
||||
# parse and validate the response
|
||||
# using $self->test_v2_response()
|
||||
};
|
||||
|
||||
sub test_query_p0f_v3 {
|
||||
#TODO: similar to v2 ....
|
||||
};
|
||||
|
||||
sub test_get_v2_query {
|
||||
my $self = shift;
|
||||
|
||||
my $local_ip = '208.75.177.101';
|
||||
my $remote = '108.60.149.81';
|
||||
$self->{_args}{local_ip} = $local_ip;
|
||||
$self->qp->connection->local_ip($local_ip);
|
||||
$self->qp->connection->remote_ip($remote);
|
||||
$self->qp->connection->local_port(25);
|
||||
$self->qp->connection->remote_port(2500);
|
||||
|
||||
my $r = $self->get_v2_query();
|
||||
ok( $r, 'get_v2_query' );
|
||||
#use Data::Dumper; warn Data::Dumper::Dumper( $r );
|
||||
};
|
||||
|
||||
sub test_get_v3_query {
|
||||
my $self = shift;
|
||||
|
||||
my $remote = '108.60.149.81';
|
||||
$self->qp->connection->remote_ip($remote);
|
||||
|
||||
my $r = $self->get_v3_query();
|
||||
ok( $r, 'get_v3_query' );
|
||||
#use Data::Dumper; warn Data::Dumper::Dumper( $r );
|
||||
};
|
||||
|
||||
sub test_store_v2_results {
|
||||
my $self = shift;
|
||||
|
||||
my $response = pack("L L C Z20 Z40 c Z30 Z30 C C C s S N",
|
||||
'233811181', '1336687857', '0', 'Windows', 'XP/2000 (RFC1323+, w+, tstamp-)',
|
||||
'11', 'ethernet/modem', '', '0', '0', '1', '-25600', '255', '255' );
|
||||
|
||||
my $r = $self->store_v2_results( $response );
|
||||
|
||||
ok( $r, "query_p0f_v2 result") or return;
|
||||
ok( $r->{genre} =~ /windows/i, "store_v2_results, genre" );
|
||||
#use Data::Dumper; warn Data::Dumper::Dumper( $r );
|
||||
};
|
||||
|
||||
sub test_store_v3_results {
|
||||
my $self = shift;
|
||||
|
||||
my $response = pack("L L L L L L L L L s C C A32 A32 A32 A32 A32 A32 A32",
|
||||
1345340930, 16, 1336676595, 1336680290, 3, 0, 0, 0, 0, 13, 0, 0,
|
||||
'Windows', '7 or 8', '', '', 'Ethernet or modem', '', '');
|
||||
my $r = $self->store_v3_results( $response );
|
||||
|
||||
ok( $r, "query_p0f_v3 result");
|
||||
ok( $r->{genre} =~ /windows/i, "store_v3_results, genre" );
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user