cvs commit: qpsmtpd/plugins/ident geoip p0f

[email protected] (Robert Spier)
Newsgroups perl.cvs.qpsmtpd
Message-ID <[email protected]>
cvsuser     04/08/29 00:47:26

  Added:       plugins/ident geoip p0f
  Log:
  Two new plugins:
    ident/geoip - lookup country of host
    ident/p0f   - use p0f to get type of source machine
  
  Revision  Changes    Path
  1.1                  qpsmtpd/plugins/ident/geoip
  
  Index: geoip
  ===================================================================
  # -*- perl -*-
  
  =pod
  
  This plugin uses MaxMind's GeoIP service and the Geo::IP perl module to
  do a lookup on incoming connections and record the country of origin.
  
  Thats all it does.
  
  It logs the country to the connection notes 'geoip_country'.  Another
  plugin can use that value to do things to the connection, like reject,
  or greylist.
  
  =cut
  
  use Geo::IP;
  
  my $geoip = Geo::IP->new(GEOIP_STANDARD);
  
  
  sub register {
    my ($self, $qp) = @_;
    $self->register_hook("connect", "lookup_geoip");
  }
  
  sub lookup_geoip {
    my ($self) = @_;
  
    my $country = 
      $geoip->country_code_by_addr( $self->qp->connection->remote_ip );
  
    $self->qp->connection->notes('geoip_country', $country);
    $self->log(LOGNOTICE, "GeoIP Country: $country");
  
    return DECLINED;
  }
  
  
  
  1.1                  qpsmtpd/plugins/ident/p0f
  
  Index: p0f
  ===================================================================
  # -*- perl -*-
  
  =pod
  
  An Identification Plugin
  
   ./p0f -u qpsmtpd -d -q -Q /tmp/.p0f_socket 'dst port 25' -o /dev/null && \
      chown qpsmtpd /tmp/.p0f_socket
  
  and add 
  
   ident/p0f /tmp/.p0f_socket 
  
  to config/plugins
  
  it puts things into the 'p0f' connection notes so other plugins can do
  things based on source OS.
  
  =cut
  
  use IO::Socket;
  use Net::IP;
  
  sub register {
    my ($self, $qp, $p0f_socket) = @_;
    $self->register_hook("connect", "lookup_p0f");
  
    $p0f_socket =~ /(.*)/; # untaint
    $self->{_args}->{p0f_socket} = $1;
  }
  
  sub lookup_p0f {
    my($self, $qp) = @_;
  
    eval {
      my $p0f;
      $p0f = p0fq( $self->{_args}->{p0f_socket},
  		 $self->qp->connection->remote_ip,
  		 $self->qp->connection->remote_port,
  		 $self->qp->connection->local_ip,
  		 $self->qp->connection->local_port,
  	       );
      $self->qp->connection->notes('p0f',$p0f);
      $self->log(LOGNOTICE, "Results: ".$p0f->{genre}." (".$p0f->{detail}.")");
    };
    $self->log(LOGERROR,"error: $@") if $@;
  
    return DECLINED;
  }
  
  
  
  =pod
  
  Heavily based on p0fq.pl from the p0f districution, and is marked as:
   Copyright (C) 2004 by Aurelien Jacobs <[email protected]>
  
  It says:
  # If you want to query p0f from a production application, just
  # implement the same functionality in your code. It's perhaps 10
  # lines.
  
  =cut
  
  my $QUERY_MAGIC = 0x0defaced;
  sub p0fq {
    my ($p0f_socket,$srcip,$srcport,$destip,$destport) = @_;
  
    # Convert the IPs and pack the request message
    my $src = new Net::IP ($srcip) or die (Net::IP::Error());
    my $dst = new Net::IP ($destip) or die (Net::IP::Error());
    my $query = pack("L L N N S S", $QUERY_MAGIC, 0x12345678,
  		   $src->intip(), $dst->intip(), $srcport, $destport);
  
    # Open the connection to p0f
    my $sock = new IO::Socket::UNIX (Peer => $p0f_socket,
  				   Type => SOCK_STREAM);
    die "Could not create socket: $!\n" unless $sock;
  
    # Ask p0f
    print $sock $query;
    my $response = <$sock>;
    close $sock;
  
    # Extract the response from p0f
    my ($magic, $id, $type, $genre, $detail, $dist, $link, $tos, $fw,
        $nat, $real, $score, $mflags, $uptime) =
  	unpack ("L L C Z20 Z40 c Z30 Z30 C C C s S N", $response);
    die "Bad response magic.\n" if $magic != $QUERY_MAGIC;
    die "P0f did not honor our query.\n" if $type == 1;
    die "This connection is not (no longer?) in the cache.\n" if $type == 2;
    
    return ({ genre => $genre,
  	    detail => $detail,
  	    distance => $dist,
  	    link => $link,
  	    uptime => $uptime,
  	  }
  	 );
  }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.