Server IP : 85.214.239.14 / Your IP : 3.141.12.254 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /usr/share/perl5/Amavis/ |
Upload File : |
# SPDX-License-Identifier: GPL-2.0-or-later package Amavis::OS_Fingerprint; use strict; use re 'taint'; use warnings; use warnings FATAL => qw(utf8 void); no warnings 'uninitialized'; # use warnings 'extra'; no warnings 'experimental::re_strict'; use re 'strict'; BEGIN { require Exporter; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION); $VERSION = '2.412'; @ISA = qw(Exporter); } use Errno qw(EINTR EAGAIN); use Socket; use IO::Socket::UNIX; #use IO::Socket::INET; use Time::HiRes (); use Amavis::Conf qw(:platform); use Amavis::Util qw(ll do_log idn_to_ascii); sub new { my($class, $service_method,$timeout, $src_ip,$src_port, $dst_ip,$dst_port, $nonce) = @_; local($1,$2,$3); my($service_host, $service_port, $service_path); if ($service_method =~ m{^p0f: (?: \[ ([^\]]*) \] | ([^:]*) ) : ([^:]*) }six) { ($service_host, $service_port) = ($1.$2, $3); } elsif ($service_method =~ m{^p0f: ( / [^ ]+ ) \z}six) { # looks like a unix socket $service_path = $1; } else { die "Bad p0f method syntax: $service_method"; } $dst_ip = '0.0.0.0' if !defined $dst_ip; # our MTA's IP address $dst_port = defined $dst_port ? 0+$dst_port : 0; # our MTA port, usually 25 $src_port = defined $src_port ? 0+$src_port : 0; # remote client's port no. do_log(4,"Fingerprint query: [%s]:%s %s %s", $src_ip, $src_port, $nonce, $service_method); my $sock; my $query; my $query_sent = 0; # send a UDP query to p0f-analyzer $query = '['.$src_ip.']' . ($src_port==0 ? '' : ':'.$src_port); if (defined $service_path) { $sock = IO::Socket::UNIX->new(Type => SOCK_DGRAM, Peer => $service_path); $sock or do_log(0,"Can't connect to a Unix socket %s: %s", $service_path, $!); } else { # assume an INET or INET6 protocol family $service_host = idn_to_ascii($service_host); $sock = $io_socket_module_name->new( Type => SOCK_DGRAM, Proto => 'udp', PeerAddr => $service_host, PeerPort => $service_port); $sock or do_log(0,"Can't create a socket [%s]:%s: %s", $service_host, $service_port, $!); } if ($sock) { defined $sock->syswrite("$query $nonce") or do_log(0, "Fingerprint - error sending a query: %s", $!); $query_sent = 1; } return if !$query_sent; bless { sock => $sock, wait_until => (Time::HiRes::time + $timeout), query => $query, nonce => $nonce }, $class; } sub collect_response { my $self = $_[0]; my $timeout = $self->{wait_until} - Time::HiRes::time; if ($timeout < 0) { $timeout = 0 }; my $sock = $self->{sock}; my($resp,$nfound,$inbuf); my($rin,$rout); $rin = ''; vec($rin,fileno($sock),1) = 1; for (;;) { $nfound = select($rout=$rin, undef, undef, $timeout); last if !$nfound || $nfound < 0; my $rv = $sock->sysread($inbuf,1024); if (!defined $rv) { if ($! == EAGAIN || $! == EINTR) { Time::HiRes::sleep(0.1); # slow down, just in case } else { do_log(2, "Fingerprint - error reading from socket: %s", $!); } } elsif (!$rv) { # sysread returns 0 at eof last; } else { local($1,$2,$3); if ($inbuf =~ /^([^ ]*) ([^ ]*) (.*)\015\012\z/) { my($r_query,$r_nonce,$r_resp) = ($1,$2,$3); if ($r_query eq $self->{query} && $r_nonce eq $self->{nonce}) { $resp = $r_resp }; } do_log(4,"Fingerprint collect: max_wait=%.3f, %.35s... => %s", $timeout,$inbuf,$resp); $timeout = 0; } } defined $nfound && $nfound >= 0 or die "Fingerprint - select on socket failed: $!"; $sock->close or die "Error closing socket: $!"; $resp; } 1;