Package: logwatch Version: 7.5.6-1 Severity: normal Dear Maintainer, I get the following report in Logwatch: --------------------- EXIM Begin ------------------------
Use of uninitialized value $SelfSigned in concatenation (.) or string at /usr/share/logwatch/scripts/services/exim line 334, <STDIN> line 442. --- Self-Signed Certificate in use ( Time(s)) ---------------------- EXIM End ------------------------- I go to those lines in the named script and I don't see an error. I'm attching the script it's complaining about -- System Information: Debian Release: bookworm/sid APT prefers testing-debug APT policy: (500, 'testing-debug'), (500, 'testing') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 6.0.0-2-amd64 (SMP w/2 CPU threads; PREEMPT) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages logwatch depends on: ii exim4-daemon-light [mail-transport-agent] 4.96-7 ii perl 5.36.0-4 Versions of packages logwatch recommends: ii libdate-manip-perl 6.89-1 ii libsys-cpu-perl 0.61-3+b1 ii libsys-meminfo-perl 0.99-2+b1 logwatch suggests no packages. -- debconf-show failed
#!/usr/bin/perl ######################################################## # Please file all bug reports, patches, and feature # requests under: # https://sourceforge.net/p/logwatch/_list/tickets # Help requests and discusion can be filed under: # https://sourceforge.net/p/logwatch/discussion/ ######################################################## ######################################################## # Originally written by: # Dariusz Nierada <dnier...@kat.supermedia.pl> ######################################################## ######################################################## # Default Detail Levels: # 0: Prints MisFormatted log lines (should never happen) # Virus/Malware blocks (if AntiVirus configured) # Prints protocol violations (by category) # Prints address verification rejections # Prints administrative rejections (by category) # Prints Refused Relay count # # 5: Prints Queue Run count # Prints server Stop/Start # # 10: Prints Refused Relay (individual lines) # Prints Per Message Tracking ######################################################## ######################################################## ## Copyright (c) 2008 Gary Allen Vollink ## Covered under the included MIT/X-Consortium License: ## http://www.opensource.org/licenses/mit-license.php ## All modifications and contributions by other persons to ## this script are assumed to have been donated to the ## Logwatch project and thus assume the above copyright ## and licensing terms. If you want to make contributions ## under your own copyright or a different license this ## must be explicitly stated in the contribution an the ## Logwatch project reserves the right to not accept such ## contributions. If you have made significant ## contributions to this script and want to claim ## copyright please contact logwatch-de...@lists.sourceforge.net. ######################################################### use Logwatch ':dates'; use warnings; $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; $LvlBadFormat = $ENV{'exim_misformat'} || 0; $LvlRestarts = $ENV{'exim_restart'} || 5; $LvlVirus = $ENV{'exim_virus'} || 0; $LvlProtocol = $ENV{'exim_protocol'} || 0; $LvlProtocolLines = $ENV{'exim_protocol_lines'}|| 5; $LvlDontAccept = $ENV{'exim_dontaccept'} || 0; $LvlDontAcceptLines = $ENV{'exim_dontaccept_lines'} || 0; $LvlVerify = $ENV{'exim_verify'} || 0; $LvlVerifyLines = $ENV{'exim_verify_lines'} || 5; $LvlRuns = $ENV{'exim_runs'} || 5; $LvlRelay = $ENV{'exim_relay'} || 0; $LvlRelayLines = $ENV{'exim_relay_lines'} || 10; $LvlMsgs = $ENV{'exim_mesgs'} || 10; # procedura sortujaca tak jak ja chce (bo tamta sotrowala po ASCII) # procedure to compare numbers at the beginning of submitted strings. # .. Which in this case is the message count for a given message ID. sub wedlug_liczb { ($aa) = ($a =~ /^(\d+).+/); ($bb) = ($b =~ /^(\d+).+/); $aa <=> $bb; } # START my $SearchDate = TimeFilter("%Y-%m-%d %H:%M:%S"); $StartQueue = 0; $EndQueue = 0; # Regex to match IPv4 addresses and IPv6 addresses # IPv6 part could be made more strict my $IPAddress = qr/\d+\.\d+\.\d+\.\d+|[a-fA-F0-9]*:[a-fA-F0-9:]+/; my $MatchedDate = 0; while (defined($ThisLine = <STDIN>)) { chomp($ThisLine); # pobierz dzisiejsza date z 2002-03-31 22:13:48 ... # Collect this line's date, e.g. 2002-03-31 22:13:48 ... do { if ( $ThisLine =~ /^ Suggested action: use keep_environment./ ) { $KeepEnv++ if $MatchedDate; next; } if ( $ThisLine =~ /^ Suggested action: either install a certificate or change tls_advertise_hosts option/ ) { push @SelfSignedH, $ThisLine; next; } $BadFormat{$ThisLine}++; next; } unless ($year1,$month1,$day1,$h1,$m1,$s1) = ($ThisLine =~ /^(\d+)\-(\d+)\-(\d+)\s(\d+):(\d+):(\d+)\s.+/); unless ($ThisLine =~ /^$SearchDate /o) { $MatchedDate = 0; next; } $MatchedDate = 1; if ( $ThisLine =~ /End queue run\:/ ) { $EndQueue++; } elsif ( $ThisLine =~ /Start queue run\:/ ) { $StartQueue++; } elsif ( $ThisLine =~ /sender verify defer/ ) { # ignore this; it's temporary } elsif ( $ThisLine =~ /unknown variable name/ ) { # ignore this temporarily } elsif ( $ThisLine =~ /ignoring AUTH=.*? \(client not authenticated\)/ ) { # ignore this; it is a warning. } elsif ( $ThisLine =~ /cwd=.*? \d args: / ) { # ignore this; it is exim (or an Exim sub-command) starting. } elsif ( $ThisLine =~ /[Rr]ecipient verify fail/ ) { $RecipVerify{$ThisLine}++; } elsif ( $ThisLine =~ /[Ss]ender verify fail/ ) { $SendVerify{$ThisLine}++; } elsif ( $ThisLine =~ /Warning: purging the environment./ ) { $Purging++; } elsif ( $ThisLine =~ /fragments administratively prohib/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /unqualified (sender|recipient) rejected/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /do not accept mail / ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /rejected connection in .connect. ACL/ ) { # Likely policy rejections $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /believed to be spam/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /[Ww]arning: dnsbl\.sorbs\.net/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /mail not permitted from/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /file, which is blacklisted/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /not accept Windows executables/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /remote host address is the local host/ ) { $DontAccept{$ThisLine}++; } elsif ( $ThisLine =~ /message contains malware/ ) { # Exim <= 4.44 with ExiScan-ACL Patch (Running AntiVirus Software) $Virus{$ThisLine}++; } elsif ( $ThisLine =~ /message contains a [vV]irus/ ) { # Exim >= 4.50 compiled with WITH_CONTENT_SCAN=yes (Running AntiVirus Software) $Virus{$ThisLine}++; } elsif ( $ThisLine =~ /SMTP connection from/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /SMTP syntax error in/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /remote host used my name in HELO/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /remote host used IP address in HELO/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /unexpected disconnection while reading SMTP command/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /SMTP protocol violation/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /SMTP command timeout/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /SMTP data timeout/ ) { # Common error from SPAM hosts. $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /incomplete transaction \(([\s\w]+)\) from/ ) { # Common error from SPAM hosts (after recipient reject/callout). $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /SMTP protocol synchronization error \(([\s\w:]+)\):/ ) { # Spammer who does not wait before sending crap $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /AUTH command used when not advertised/ ) { # Spammer who does not read protocol $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /dropped: too many nonmail commands/ ) { # Often someone who tries lots of transactions $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /dropped: too many syntax or protocol errors/ ) { # Often someone who tries lots of transactions $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /SMTP protocol error in \"[^\"]+\"/ ) { # Some hosts ask for TLS even when not offered (generalised to all cmds) $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /TLS error on connection from/ ) { # Various TLS errrors $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /authenticator failed for/ ) { $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /Connection from .* too many connections from that IP address/ ) { # Some hosts make lots of simultaneous connections # this is an extra error message when logging is high # and since another message duplicates it, we can just ignore this } elsif ( $ThisLine =~ /rejected [HE][EH]LO from\s/ ) { # Typically due to underscores _ in the HELO line # (a common protocol violation) # Also can be due to odd escape sequences # (never seen from a valid MX) $Proto{$ThisLine}++; } elsif ( $ThisLine =~ /SIGHUP received\: re-exec/ ) { push @Restart, "$year1-$month1-$day1 $h1:$m1:$s1 (stop)"; } elsif ( $ThisLine =~ /daemon started\:/ ) { push @Restart, "$year1-$month1-$day1 $h1:$m1:$s1 (start)"; } elsif ( $ThisLine =~ /rejected RCPT.*greylist/) { $Greylist++; push @GreylistH, $ThisLine; } elsif ( $ThisLine =~ /refused relay/ || $ThisLine =~ /rejected RCPT/ ) { $Relay++; push @RelayH, $ThisLine; } elsif ( $ThisLine =~ /no host name found for IP address/ ) { $ReverseLookup++; push @ReverseLookupH, $ThisLine; } elsif ( $ThisLine =~ /no IP address found for host/ ) { $Lookup++; push @LookupH, $ThisLine; } elsif ( $ThisLine =~ /No server certificate defined; will use a selfsigned one/ ) { $SelfSigned++; push @SelfSignedH, $ThisLine; } elsif ( $ThisLine =~ /DKIM: .* \[verification succeeded\]/ ) { # Ignore successful DKIM verification reports # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-support_for_dkim_domainkeys_identified_mail.html } elsif ( $ThisLine =~ /^\d+\-\d+\-\d+\s\d+\:\d+\:\d+\s(\+\d+\s)?\w+\-\w+\-\w+\s/ ) { # inne wiadomosci przesylane przez EXIMA # Collect Message ID specific notes... ($mdate,$mtime,$mid,$mrest) = ($ThisLine =~ /^(\d+\-\d+\-\d+)\s(\d+\:\d+\:\d+)\s(?:\+\d+\s)?(\w+\-\w+\-\w+)(.+)/); # Count of individual Message Lines, used for sort $licze++; # Dodaje taki licznik aby potem przy wypisaniu posortowac po nim, bo wypisywal nie po kolei $mmsg{$mid}{$licze.$mrest} = "$mdate $mtime"; } else { $OtherList{$ThisLine}++; } } #end while # Print MisFormatted log lines (should never happen) if ($Detail >= $LvlBadFormat) { if (%BadFormat) { print "\n***** BAD FORMAT (Possible data corruption or Exim bug) *****\n"; foreach $ThisOne (keys %BadFormat) { print "$ThisOne\n"; } } } # Print server Stops/Starts if ($Detail >= $LvlRestarts) { if (@Restart) { print "\n--- Exim Restarted ---\n"; foreach $ThisOne (sort @Restart) { print " $ThisOne\n"; } } } if ($Purging) { print " Warning: purging the environment. : $Purging Time(s)\n"; } if ($KeepEnv) { print " ... Suggested action: use keep_environment. : $KeepEnv Time(s)\n"; } if ($Detail >= $LvlRuns) { if (($StartQueue >0 ) or ($EndQueue > 0)) { print "\n--- Queue Runners ---\n"; # Start Queue $StartQueue and print " Start queue run: $StartQueue Time(s)\n"; # End Queue $EndQueue and print " End queue run: $EndQueue Time(s)\n"; } } if (@SelfSignedH) { print "\n--- Self-Signed Certificate in use ($SelfSigned Time(s))\n"; if ($Detail >= $LvlMsgs) { foreach $ThisOne (@SelfSignedH) { print "$ThisOne\n"; } } } if ($Detail >= $LvlVerify) { if ((@SendVerify) and (@RecipVerify)) { print "\n--- Address Verification ---\n"; } if (@SendVerify) { # Sender Verifies $SendVerify and print "\nSender Verify failures: $SendVerify Time(s)\n"; if ($Detail >= $LvlVerifyLines) { foreach $ThisOne (@SendVerify) { print " $ThisOne\n"; } } } if (@RecipVerify) { # Recip Verifies $RecipVerify and print "Recipient Verify failures: $RecipVerify Time(s)\n"; if ($Detail >= $LvlVerifyLines) { foreach $ThisOne (@RecipVerify) { print " $ThisOne\n"; } } } } if ($Detail >= $LvlRelay) { if (@GreylistH) { print "\n--- Greylisted $Greylist times\n"; if ( $Detail >= $LvlRelayLines ) { print "--- Lines follow:\n\n"; foreach $ThisOne (@GreylistH) { print "$ThisOne\n"; } } } if (@RelayH) { print "\n--- Refused Relays $Relay times\n"; if ( $Detail >= $LvlRelayLines ) { print "--- Lines follow:\n\n"; foreach $ThisOne (@RelayH) { print "$ThisOne\n"; } } } } if ($Detail >= $LvlVirus) { # Print Blocked Viruses/Malware if (%Virus) { my (%vir); print "\n--- Virus/Malware Blocked ---\n"; foreach $ThisOne (sort(keys %Virus)) { # Need mid empty... $mid = ""; # Virus name holder... $cc = ""; # Extract exim date and time string... ($mdate, $mtime) = ($ThisOne =~ m/^(\d+-\d+-\d+)\s(\d+\:\d+\:\d+)\s/); # Link date and time (looks cleaner)... $aa = "$mdate $mtime"; # Extract the REAL IP address... ($bb) = ($ThisOne =~ m/\s\[($IPAddress)\][\s:]/); # Exim >= 4.50 compiled with, WITH_CONTENT_SCAN=yes # Default warning looks like this... # rejected after DATA: This message contains a [vV]irus (%s). if ($ThisOne =~ m/virus \((.*?)\)/) { $cc = $1; } # Exim <= 4.44 with ExiScan-ACL patch # rejected after DATA: This message contains malware (%s) elsif ($ThisOne =~ m/malware \((.*?)\)/) { $cc = $1; } # There is probably a more graceful way to do this... if (defined( $vir{$cc} )) { # Assign current value to temporary (mid) $mid = $vir{$cc}; } # Set current value to (old value)+new value+',' $vir{$cc} = "$mid$aa : IP:$bb,"; } # Print the results... foreach $ThisOne (sort(keys %vir)) { print "Virus: [$ThisOne]\n"; foreach $aa ( sort( split /,/, $vir{$ThisOne} )) { print " $aa\n"; } } } } if ($Detail >= $LvlDontAccept) { # Print Administrative Prohibitions if (%DontAccept) { my (%spam, %detail); my (@errList); # Probable SPAM hosts... print "\n--- Admin Policy Blocking ---\n"; foreach $ThisOne (sort(keys %DontAccept)) { # We need this blank. $mid = ""; # IP address/current issue holder. $bb = ""; # Extract exim date and time string... ($mdate, $mtime) = ($ThisOne =~ m/^(\d+-\d+-\d+)\s(\d+\:\d+\:\d+)\s/); # Link date and time (looks cleaner)... $aa = "$mdate $mtime"; if ( $ThisOne =~ m/do not accept mail from ([\w\*-._]+)@([\w.-_]+)/ ) { $cc = "Blocked Email Domain"; $bb = "$1\@$2"; } elsif ( $ThisOne =~ m/rejected connection in .connect. ACL/ ) { $cc = "Blocked Host"; ( $bb ) = ($ThisOne =~ m/\[(\d+\.\d+\.\d+\.\d+)\]/); } elsif ( $ThisOne =~ m/mail not permitted from sender ([\w\*-_.]+)@([\w.-_]+)/ ) { $cc = "Blocked Email Address"; $bb = "$1\@$2"; } elsif ( $ThisOne =~ m/contains attached ".(.*)" file, which is blacklisted/ ) { $cc = "Blocked Attachment"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /believed to be spam/ ) { $cc = "Blocked Fragmented Message"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /[Ww]arning: dnsbl\.sorbs\.net/ ) { $cc = "Blocked by DNSBL (SORBS)"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /fragments administratively prohibited/ ) { $cc = "Blocked Fragmented Message"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ m/unqualified sender rejected: <(.*)>/ ) { $cc = "Unqualified Sender"; $bb = "$1"; } elsif ( $ThisOne =~ m/unqualified recipient rejected: <(.*)>/ ) { $cc = "Unqualified Receipient"; $bb = "$1"; } elsif ( $ThisOne =~ m/not accept Windows executables/ ) { $cc = "Blocked Attachment"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ m/remote host address is the local host/ ) { $cc = "Invalid local domain"; ( $bb ) = ($ThisOne =~ m/\@[^>]+/); } else { # If we picked up a malfunction but didn't collect it here, # no need to make the user suffer with superfluous error # messages. #next; print "Didn't Summarize: $ThisOne\n"; } if ($cc =~ m/Blocked/ ) { # hash of blocked things my $h = {}; if (!defined($detail{$cc})) { # debug print "add type $cc\n" ; $detail{$cc} = $h; } $h = $detail{$cc}; if (defined($h{$bb})) { # debug print "add $bb to ".$h{$bb}."\n" ; $h{$bb} = $h{$bb} + 1; } else { $h{$bb} = 1; # debug print "start $bb at ".$h{$bb}."\n" ; } # marker $spam{$cc} = ""; } else { if (defined( $spam{$cc} )) { $mid = $spam{$cc}; } $spam{$cc} = "$mid$aa : $bb,"; } } foreach $ThisOne (sort(keys %spam)) { if ($Detail >= $LvlDontAcceptLines) { if ($spam{$cc} eq "") { print " $ThisOne\n"; my $h = $detail{$ThisOne}; foreach $aa (sort(keys %h) ) { print " $aa : ".$h{$aa}." times\n"; } } else { print " $ThisOne\n"; foreach $aa ( sort( split /,/, $spam{$ThisOne} )) { print " $aa\n"; } } } else { @errList = split /,/, $spam{$ThisOne}; print " $ThisOne ".scalar @errList." times\n"; } } } } if ($Detail >= $LvlProtocol) { # Print Protocol Violations if (%Proto) { my (%spam); my (%SmtpConnection); my (%SmtpProblemHosts); my (%TlsProblemClasses); my (%TlsProblemHosts); # Probable SPAM hosts... print "\n--- Bad Hosts ---\n"; foreach $ThisOne (sort(keys %Proto)) { # We need this blank. $mid = ""; # IP address/current issue holder. $bb = ""; $cc = ""; # Extract exim date and time string... ($mdate, $mtime) = ($ThisOne =~ m/^(\d+-\d+-\d+)\s(\d+\:\d+\:\d+)\s/); # Link date and time (looks cleaner)... $aa = "$mdate $mtime"; if ( $ThisOne =~ m/SMTP protocol violation\:\s(.*?\(.*?\))\:/ ) { $cc = $1; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /unexpected disconnection while reading SMTP command/ ) { $cc = "Sudden disconnect while expecting remote input"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ m/rejected ([HE][EH])LO from \[($IPAddress)\]\:\s(.*?):\s(.*?)$/ ) { $cc = "Rejected HELO/EHLO: $3"; $bb = "$2 ($1LO $4)"; } elsif ( $ThisOne =~ /SMTP data timeout \(message abandoned\) on connection from/ ) { $cc = "SMTP Timeout errors"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /SMTP command timeout on connection from/ ) { $cc = "SMTP Timeout errors"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /syntactically invalid argument/ ) { $cc = "SMTP Syntax errors"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /SMTP syntax error in/ ) { $cc = "SMTP Syntax errors"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /remote host used my name in HELO/ ) { $cc = "My name in HELO"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /remote host used IP address in HELO/ ) { $cc = "IP address in HELO"; ( $bb ) = ($ThisOne =~ m/\[($IPAddress)\]/); } elsif ( $ThisOne =~ /incomplete transaction (\(.*\))/ ) { $bb = "SMTP transaction cut short $1"; $SmtpConnection{$bb}++; } elsif ( $ThisOne =~ /SMTP protocol synchronization error/ ) { $bb = "SMTP protocol synchronization error"; $SmtpConnection{$bb}++; } elsif ( $ThisOne =~ /dropped: too many nonmail commands/ ) { $bb = "Connection dropped after too many nonmail SMTP commands"; $SmtpConnection{$bb}++; } elsif ( $ThisOne =~ /dropped: too many syntax or protocol errors/ ) { $bb = "Connection dropped after too many syntax/protocol errors"; $SmtpConnection{$bb}++; } elsif ( $ThisOne =~ /(SMTP protocol error in \"\w+\")/ ) { $bb = $1; $SmtpConnection{$bb}++; } elsif ( $ThisOne =~ /\[([^]]+)\] (AUTH command used when not advertised)/ ) { my $key = $1; $bb = $2; $SmtpProblemHosts{$key}++; $SmtpConnection{$bb}++; } elsif ( $ThisOne =~ /authenticator failed for (?:\S+ |)\([^)]*\) \[($IPAddress)\](?::\d+ |)(?:I=\[$IPAddress\]:\d+|): ([^(]*)/ ) { my $key = $1; $bb = $2; $bb =~ s/\s+$//; $SmtpProblemHosts{$key}++; $SmtpConnection{$bb}++; } elsif ( $ThisOne =~ /TLS error on connection from (?:(\S+) |)(?:\(([^)]*)\) |)\[($IPAddress)\](?::\d+|) (?:I=\[$IPAddress\](?::\d+|) |)\(([^)]+)\): (.*)/ ) { my ($reverseHost, $hostLabel, $hostAddress, $action, $message) = ($1, $2, $3, $4, $5); $message =~ s/\.$//; my $key = "$hostAddress"; if ($Detail > 50) { $key .= " ($hostLabel)" if ($hostLabel); $key .= " $reverseHost" if ($reverseHost); } elsif ($reverseHost) { $key = "$reverseHost"; if ($hostLabel && (() = $reverseHost =~ /\./g) > 2) { my ($common) = ($reverseHost =~ /^[^.]+(\..*)$/); $key = "($hostLabel)" if ($hostLabel =~ /^[^.]+\Q$common\E$/); } } $TlsProblemHosts{$key}++; $TlsProblemClasses{"$action: $message"}++; } elsif ( $ThisOne =~ /SMTP connection from/ ) { if ( $ThisOne =~ /lost while reading message data/ ) { $bb = "SMTP connection lost while reading message data"; } elsif ( $ThisOne =~ /Connection reset by peer/ ) { $bb = "SMTP connection lost when connection reset by peer "; } elsif ( $ThisOne =~ /lost/ ) { $bb = "SMTP connection lost (non-specific)"; } elsif ( $ThisOne =~ /closed by QUIT/ ) { $bb = "SMTP connection closed by QUIT"; } elsif ( $ThisOne =~ /closed after SIGTERM/ ) { $bb = "SMTP connection closed after SIGTERM"; } elsif ( $ThisOne =~ /TCP\/IP connection count/ ) { $bb = "SMTP connection TCP/IP connection count (warning)"; } if ( $bb ne "" ) { $SmtpConnection{$bb}++; } } else { # If we picked up a malfunction but didn't collect it here, # no need to make the user suffer with superfluous error # messages. #next; print "Didn't Summarize: $ThisOne\n"; } if (defined( $spam{$cc} )) { $mid = $spam{$cc}; } # We're picking things up in this larger block that do not # ... fit into this mold, so - let's make sure that this is valid # ... before we set it: if (( $cc ne '' ) && ( $bb ne '' )) { $spam{$cc} = "$mid$aa : IP:$bb,"; } } foreach $ThisOne (sort(keys %spam)) { if ($Detail >= $LvlProtocolLines) { print " $ThisOne:\n"; foreach $aa ( sort( split /,/, $spam{$ThisOne} )) { print " $aa\n"; } } else { @errList = split /,/, $spam{$ThisOne}; print " $ThisOne ".scalar @errList." times\n"; } } if ( %TlsProblemClasses ) { print "\n--- TLS Connection Issues \n"; foreach $ThisOne (sort keys %TlsProblemClasses) { $bb = $TlsProblemClasses{$ThisOne}; print " $ThisOne: $bb Time(s)\n"; } print "\n From these hosts:\n"; foreach $ThisOne (sort keys %TlsProblemHosts) { $bb = $TlsProblemHosts{$ThisOne}; print " $ThisOne: $bb Time(s)\n"; } } if ( %SmtpConnection ) { print "\n--- SMTP Connection Issues \n"; foreach $ThisOne (sort keys %SmtpConnection) { $bb = $SmtpConnection{$ThisOne}; print " $ThisOne: $bb Time(s)\n"; } print "\n From these hosts:\n"; foreach $ThisOne (sort keys %SmtpProblemHosts) { $bb = $SmtpProblemHosts{$ThisOne}; print " $ThisOne: $bb Time(s)\n"; } } if (@ReverseLookupH) { print "\n--- Failed Reverse Lookups \n"; print "--- $ReverseLookup Time(s)\n\n"; if ($Detail >= $LvlProtocolLines) { foreach $ThisOne (@ReverseLookupH) { print " $ThisOne\n"; } } } if (@LookupH) { print "\n--- Failed Reverse Lookups \n"; print "--- (e.g. spam try): $Lookup Time(s)\n\n"; if ($Detail >= $LvlProtocolLines) { foreach $ThisOne (@LookupH) { print "$ThisOne\n"; } } } } } if ($Detail >= $LvlMsgs) { # Messages by ID if (keys %mmsg ) { my $tmsgcount=0; my $tmsgrcpts=0; print "\n--- Messages history ---\n\n"; # mmsg is hashed by message id, which is sorted by time foreach $tmsg (sort keys %mmsg) { my @tmsgkeys = sort {wedlug_liczb} keys %{$mmsg{$tmsg}}; my $immed_deliv = 1; $immed_deliv = 0 unless $tmsgkeys[0] =~ /^\d+ <=/; foreach my $key (@tmsgkeys[1..$#tmsgkeys-1]) { $immed_deliv = 0 unless $key =~ /^\d+ [-=]>/; } $immed_deliv = 0 unless $tmsgkeys[$#tmsgkeys] =~ /^\d+ Completed/; my $qttmsgcount = 0; my $oldqttmsg = ''; if (!$immed_deliv) { print "\-MsgID: $tmsg\: \n"; foreach $ttmsg (@tmsgkeys) { $qttmsg = $ttmsg; $qttmsg =~ s/^\d+//; # wywal licznik na poczatku (te od sortowania) $qttmsg =~ s/P\=e*smtp S.+//; # wywal koncowki typu: P=smtp S=372023 id= if ($oldqttmsg eq $qttmsg) { $qttmsgcount++; } else { $oldqttmsg = $qttmsg; if ($qttmsgcount > 0) { print "\tlast message repeated $qttmsgcount times\n"; $qttmsgcount = 0; } print "\t$mmsg{$tmsg}{$ttmsg}$qttmsg\n"; } } if ($qttmsgcount > 0) { print "\tlast message repeated $qttmsgcount times\n"; } } else { $tmsgcount++; $tmsgrcpts+=$#tmsgkeys-1; } } print "$tmsgcount messages delivered immediately "; print "to $tmsgrcpts total recipients\n"; } } # INNE Badziewia if (keys %OtherList) { print "\n**Unmatched Entries**\n"; foreach $line (sort {$a cmp $b} keys %OtherList) { print "$line: $OtherList{$line} Time(s)\n"; } } exit(0); # vi: shiftwidth=3 tabstop=3 syntax=perl et # Local Variables: # mode: perl # perl-indent-level: 3 # indent-tabs-mode: nil # End: