diff -up ./NEWS.git201706 ./NEWS --- ./NEWS.git201706 2017-04-19 12:03:12.000000000 -0400 +++ ./NEWS 2017-07-12 15:25:08.630685354 -0400 @@ -1,5 +1,30 @@ This file documents the major additions and syntax changes between releases. +2.3.0 xxxx-xx-xx + ENHANCEMENTS + Added directory plugins-python containing three Python plugins + check_http: New parameter `--verify-host` will check if -H hostname matches the SSL certificate + check_ping: plugin output will now include hostname and IP address + check_disk_smb: Add configfile feature + check_apt: Add --only-critical switch + check_mailq: Add support for opensmtpd + check_mailq: Add mailq -C option for config dir or config file + check_disk: Add -s option to show status for each path/partition + + +2.2.2 xxxx-xx-xx + FIXES + check_disk: autofs being mounted despite '-l'. Fixed, and also excluded some system "fake" mountpoints + check_ntp_time: Periodically returns "Socket timeout" when one of several ntp server doesn't respond + check_ntp_time calls `write` on a UDP socket without a successful call to `connect` + check_mysql_query & mysql_query: extra-opts causes crash + check_log does not check for "-O oldlog" + check_log lost ability to use regexes for query (-q) in 2.1.4 + fix configure.ac for FreeBSD SWAPFORMAT + Fix --no-body + check_wave produces lots of errors if required arguments are not provided + + 2.2.1 2017-04-19 FIXES check_users: not accepting zero as the threshold @@ -17,6 +42,7 @@ This file documents the major additions check_mailq: Nullmailer Regex is not working for Ubuntu 16.04 check_swap: Downstream Fedora patch: Prevent check_swap from returning OK, if no swap activated Building RPMs on Amazon Linux - Add 'install-root' on line 165 of spec file + check_http: Memory allocation error 2.2.0 2017-01-19 diff -up ./lib/parse_ini.c.git201706 ./lib/parse_ini.c --- ./lib/parse_ini.c.git201706 2017-01-19 11:01:31.000000000 -0500 +++ ./lib/parse_ini.c 2017-07-12 15:25:08.630685354 -0400 @@ -83,6 +83,7 @@ static char* default_file_in_path(void); */ static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i){ size_t locator_len=0, stanza_len=0; + char *dflt = NULL; /* if locator is NULL we'll use default values */ if(locator){ @@ -102,7 +103,9 @@ static void parse_locator(const char *lo } /* if there is no @file part */ if(stanza_len==locator_len){ - i->file=default_file(); + dflt=default_file(); + if (dflt) + i->file=strdup(dflt); } else { i->file=strdup(&(locator[stanza_len+1])); } diff -up ./plugins-scripts/check_disk_smb.pl.git201706 ./plugins-scripts/check_disk_smb.pl --- ./plugins-scripts/check_disk_smb.pl.git201706 2017-01-16 12:24:03.000000000 -0500 +++ ./plugins-scripts/check_disk_smb.pl 2017-07-12 15:25:08.630685354 -0400 @@ -22,7 +22,7 @@ require 5.004; use POSIX; use strict; use Getopt::Long; -use vars qw($opt_P $opt_V $opt_h $opt_H $opt_k $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $verbose); +use vars qw($opt_P $opt_V $opt_h $opt_H $opt_k $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $opt_C $verbose); use vars qw($PROGNAME); use FindBin; use lib "$FindBin::Bin"; @@ -52,7 +52,8 @@ GetOptions "s=s" => \$opt_s, "share=s" => \$opt_s, "W=s" => \$opt_W, "workgroup=s" => \$opt_W, "H=s" => \$opt_H, "hostname=s" => \$opt_H, - "a=s" => \$opt_a, "address=s" => \$opt_a); + "a=s" => \$opt_a, "address=s" => \$opt_a, + "C=s" => \$opt_C, "configfile=s" => \$opt_C); if ($opt_V) { print_revision($PROGNAME,'@NP_VERSION@'); #' @@ -90,6 +91,10 @@ my $warn = $1 if ($opt_w =~ /^([0-9]{1,2 my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/); ($crit) || usage("Invalid critical threshold: $opt_c\n"); +($opt_C) || ($opt_C = shift @ARGV) || ($opt_C = ""); +my $configfile = $opt_C if ($opt_C); +usage("Unable to read config file $configfile\n") if ($configfile) && (! -r $configfile); + # Execute the given command line and return anything it writes to STDOUT and/or # STDERR. (This might be useful for other plugins, too, so it should possibly # be moved to utils.pm.) @@ -191,6 +196,7 @@ my @cmd = ( defined($address) ? ("-I", $address) : (), defined($opt_P) ? ("-p", $opt_P) : (), defined($opt_k) ? ("-k") : (), + defined($configfile) ? ("-s, $configfile") : (), "-c", "du" ); @@ -289,8 +295,9 @@ print "$state\n" if ($verbose); exit $ERRORS{$state}; sub print_usage () { - print "Usage: $PROGNAME -H -s -u -p - -w -c [-W ] [-P ] [-a ]\n"; + print "Usage: $PROGNAME -H -s -u + -p -w -c [-W ] [-P ] + [-a ] [-C ]\n"; } sub print_help () { @@ -316,12 +323,13 @@ Perl Check SMB Disk plugin for Nagios Password to log in to server. (Defaults to an empty password) -w, --warning=INTEGER or INTEGER[kMG] Percent of used space at which a warning will be generated (Default: 85%) - -c, --critical=INTEGER or INTEGER[kMG] Percent of used space at which a critical will be generated (Defaults: 95%) -P, --port=INTEGER Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default) - +-C, --configfile=STRING + Path to configfile which should be used by smbclient (Defaults to smb.conf of your smb installation) + If thresholds are followed by either a k, M, or G then check to see if that much disk space is available (kilobytes, Megabytes, Gigabytes) diff -up ./plugins-scripts/check_log.sh.git201706 ./plugins-scripts/check_log.sh --- ./plugins-scripts/check_log.sh.git201706 2017-01-19 11:01:31.000000000 -0500 +++ ./plugins-scripts/check_log.sh 2017-07-12 15:25:08.630685354 -0400 @@ -169,6 +169,16 @@ while test -n "$1"; do shift done +if [ "$oldlog" = "" ]; then + echo "Log check error: You must supply an Old Log File name using '-O'!" + exit "$STATE_UNKNOWN" +fi +rc=`echo "$oldlog" | grep -q -- "^-"; echo $?` +if [ $rc -eq 0 ]; then + echo "Log check error: You must supply an Old Log File name using '-O'!" + exit "$STATE_UNKNOWN" +fi + # If the source log file doesn't exist, exit if [ ! -e "$logfile" ]; then @@ -205,10 +215,10 @@ fi diff "$logfile" "$oldlog" | grep -v "^>" > "$tempdiff" # Count the number of matching log entries we have -count=$(grep -c "$query" "$tempdiff") +count=$(egrep -c "$query" "$tempdiff") # Get the last matching entry in the diff file -lastentry=$(grep "$query" "$tempdiff" | tail -1) +lastentry=$(egrep "$query" "$tempdiff" | tail -1) rm -f "$tempdiff" cat "$logfile" > "$oldlog" diff -up ./plugins-scripts/check_mailq.pl.git201706 ./plugins-scripts/check_mailq.pl --- ./plugins-scripts/check_mailq.pl.git201706 2017-04-19 12:03:12.000000000 -0400 +++ ./plugins-scripts/check_mailq.pl 2017-07-12 15:26:23.894040115 -0400 @@ -28,9 +28,9 @@ use POSIX; use strict; use Getopt::Long; -use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s - $opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq @lines - %srcdomains %dstdomains); +use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s $opt_d + $opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq $mailq_args + @lines %srcdomains %dstdomains); use FindBin; use lib "$FindBin::Bin"; use lib '@libexecdir@'; @@ -49,6 +49,8 @@ $PROGNAME = "check_mailq"; $mailq = 'sendmail'; # default $msg_q = 0 ; $msg_p = 0 ; +# If appended, must start with a space +$mailq_args = '' ; $state = $ERRORS{'UNKNOWN'}; Getopt::Long::Configure('bundling'); @@ -58,6 +60,10 @@ if ($status){ exit $ERRORS{"UNKNOWN"}; } +if ($opt_d) { + $mailq_args = $mailq_args . ' -C ' . $opt_d; +} + if ($opt_s) { if ($utils::PATH_TO_SUDO ne "") { if (-x $utils::PATH_TO_SUDO) { @@ -313,19 +319,19 @@ elsif ( $mailq eq "postfix" ) { ## open mailq if ( defined $utils::PATH_TO_MAILQ ) { if (-x $utils::PATH_TO_MAILQ) { - if (! open (MAILQ, "$utils::PATH_TO_MAILQ | ")) { - print "ERROR: $utils::PATH_TO_MAILQ returned an error\n"; + if (! open (MAILQ, "$utils::PATH_TO_MAILQ$mailq_args | ")) { + print "ERROR: $utils::PATH_TO_MAILQ$mailq_args returned an error\n"; exit $ERRORS{'UNKNOWN'}; } } else { if ( $sudo ne "" ) { - if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ | " ) ) { - print "ERROR: $utils::PATH_TO_MAILQ is not executable with sudo by (uid $>:gid($)))\n"; + if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ$mailq_args | " ) ) { + print "ERROR: $utils::PATH_TO_MAILQ$mailq_args is not executable with sudo by (uid $>:gid($)))\n"; exit $ERRORS{'UNKNOWN'}; } } else { - print "ERROR: $utils::PATH_TO_MAILQ is not executable by (uid $>:gid($))) and sudo is not set in utils.pm\n"; + print "ERROR: $utils::PATH_TO_MAILQ$mailq_args is not executable by (uid $>:gid($))) and sudo is not set in utils.pm\n"; exit $ERRORS{'UNKNOWN'}; } } @@ -338,7 +344,7 @@ elsif ( $mailq eq "postfix" ) { @lines = reverse ; if ( $? ) { - print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ",$/; + print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ$mailq_args",$/; exit $ERRORS{CRITICAL}; } @@ -351,7 +357,7 @@ elsif ( $mailq eq "postfix" ) { }elsif ($lines[0]=~/Mail queue is empty/) { $msg_q = 0; }else{ - print "Couldn't match $utils::PATH_TO_MAILQ output\n"; + print "Couldn't match $utils::PATH_TO_MAILQ$mailq_args output\n"; exit $ERRORS{'UNKNOWN'}; } @@ -520,7 +526,47 @@ elsif ( $mailq eq "exim" ) { $state = $ERRORS{'CRITICAL'}; } } # end of ($mailq eq "exim") +elsif ( $mailq eq "opensmtpd" ) { + ## open smtpctl + if ( defined $utils::PATH_TO_SMTPCTL && -x $utils::PATH_TO_SMTPCTL ) { + if (! open (MAILQ, "$sudo $utils::PATH_TO_SMTPCTL show queue | " ) ) { + print "ERROR: could not open $utils::PATH_TO_SMTPCTL \n"; + exit $ERRORS{'UNKNOWN'}; + } + }elsif( defined $utils::PATH_TO_SMTPCTL){ + unless (-x $utils::PATH_TO_SMTPCTL) { + print "ERROR: $utils::PATH_TO_SMTPCTL is not executable by (uid $>:gid($)))\n"; + exit $ERRORS{'UNKNOWN'}; + } + } else { + print "ERROR: \$utils::PATH_TO_SMTPCTL is not defined\n"; + exit $ERRORS{'UNKNOWN'}; + } + + while () { + + # 34357f5b3f589feb|inet4|mta||f.someone@domaina.org|no-reply@domainb.com|no-reply@domainb.com|1498235412|1498581012|0|25|pending|17168|Network error on destination MXs + if (/^.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*$/) { + $msg_q++ ; + } + } + close(MAILQ); + if ( $? ) { + print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_SMTPCTL",$/; + exit $ERRORS{CRITICAL}; + } + if ($msg_q < $opt_w) { + $msg = "OK: $mailq mailq ($msg_q) is below threshold ($opt_w/$opt_c)"; + $state = $ERRORS{'OK'}; + }elsif ($msg_q >= $opt_w && $msg_q < $opt_c) { + $msg = "WARNING: $mailq mailq is $msg_q (threshold w = $opt_w)"; + $state = $ERRORS{'WARNING'}; + }else { + $msg = "CRITICAL: $mailq mailq is $msg_q (threshold c = $opt_c)"; + $state = $ERRORS{'CRITICAL'}; + } +} # end of ($mailq eq "opensmtpd") elsif ( $mailq eq "nullmailer" ) { ## open mailq if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) { @@ -558,6 +604,39 @@ elsif ( $mailq eq "nullmailer" ) { } } # end of ($mailq eq "nullmailer") +elsif ( $mailq eq "opensmtp" ) { + ## open mailq + if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) { + if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ | " ) ) { + print "ERROR: could not open $utils::PATH_TO_MAILQ \n"; + exit $ERRORS{'UNKNOWN'}; + } + }elsif( defined $utils::PATH_TO_MAILQ){ + unless (-x $utils::PATH_TO_MAILQ) { + print "ERROR: $utils::PATH_TO_MAILQ is not executable by (uid $>:gid($)))\n"; + exit $ERRORS{'UNKNOWN'}; + } + } else { + print "ERROR: \$utils::PATH_TO_MAILQ is not defined\n"; + exit $ERRORS{'UNKNOWN'}; + } + + $msg_q++ while (); + + close(MAILQ) ; + if ($msg_q < $opt_w) { + $msg = "OK: $mailq mailq ($msg_q) is below threshold ($opt_w/$opt_c)"; + $state = $ERRORS{'OK'}; + }elsif ($msg_q >= $opt_w && $msg_q < $opt_c) { + $msg = "WARNING: $mailq mailq is $msg_q (threshold w = $opt_w)"; + $state = $ERRORS{'WARNING'}; + }else { + $msg = "CRITICAL: $mailq mailq is $msg_q (threshold c = $opt_c)"; + $state = $ERRORS{'CRITICAL'}; + } +} # end of ($mailq eq "opensmtp") + + # Perfdata support print "$msg|unsent=$msg_q;$opt_w;$opt_c;0\n"; exit $state; @@ -576,7 +655,8 @@ sub process_arguments(){ "w=i" => \$opt_w, "warning=i" => \$opt_w, # warning if above this number "c=i" => \$opt_c, "critical=i" => \$opt_c, # critical if above this number "t=i" => \$opt_t, "timeout=i" => \$opt_t, - "s" => \$opt_s, "sudo" => \$opt_s + "s" => \$opt_s, "sudo" => \$opt_s, + "d:s" => \$opt_d, "configdir:s" => \$opt_d ); if ($opt_V) { @@ -618,7 +698,7 @@ sub process_arguments(){ } if (defined $opt_M) { - if ($opt_M =~ /^(sendmail|qmail|postfix|exim|nullmailer)$/) { + if ($opt_M =~ /^(sendmail|qmail|postfix|exim|nullmailer|opensmtpd)$/) { $mailq = $opt_M ; }elsif( $opt_M eq ''){ $mailq = 'sendmail'; @@ -648,6 +728,10 @@ sub process_arguments(){ { $mailq = 'nullmailer'; } + elsif (defined $utils::PATH_TO_SMTPCTL && -x $utils::PATH_TO_SMTPCTL) + { + $mailq = 'opensmtpd'; + } else { $mailq = 'sendmail'; } @@ -657,7 +741,7 @@ sub process_arguments(){ } sub print_usage () { - print "Usage: $PROGNAME -w -c [-W ] [-C ] [-M ] [-t ] [-s] [-v]\n"; + print "Usage: $PROGNAME -w -c [-W ] [-C ] [-M ] [-t ] [-s] [-d ] [-v]\n"; } sub print_help () { @@ -673,7 +757,7 @@ sub print_help () { print "-W (--Warning) = Min. number of messages for same domain in queue to generate warning\n"; print "-C (--Critical) = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n"; print "-t (--timeout) = Plugin timeout in seconds (default = $utils::TIMEOUT)\n"; - print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer ] (default = autodetect)\n"; + print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer | opensmtpd ] (default = autodetect)\n"; print "-h (--help)\n"; print "-V (--version)\n"; print "-v (--verbose) = debugging output\n"; diff -up ./plugins-scripts/check_mssql.pl.git201706 ./plugins-scripts/check_mssql.pl --- ./plugins-scripts/check_mssql.pl.git201706 2017-07-12 15:25:08.631685372 -0400 +++ ./plugins-scripts/check_mssql.pl 2017-07-12 15:25:08.631685372 -0400 @@ -0,0 +1,147 @@ +#!@PERL@ -w + +# +# Copyright 2003 Roy Sigurd Karlsbakk +# +# Requires freetds and DBD::Sybase +# http://www.freetds.org +# http://www.mbay.net/~mpeppler/ +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA +# +# Report bugs to: help@nagios-plugins.org +# +# + + +use DBI; +use DBD::Sybase; +use Getopt::Long; +use FindBin; +use lib "$FindBin::Bin"; +use lib '@libexecdir@'; +use utils qw($TIMEOUT %ERRORS &print_revision &support); +use strict; + +my $PROGNAME = "check_mssql"; + +$ENV{'PATH'}='@TRUSTED_PATH@'; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +my ( + $server,$database,$username,$password,$query,$help,$verbose,$timeout, + $dbh,$sth,$row, + $s,$opt_V,$regex +); +my $exitcode = $ERRORS{'OK'}; + +process_arguments(); + +# Just in case of problems, let's not hang Nagios +$SIG{'ALRM'} = sub { + print ("SQL UNKNOWN: ERROR connection $server (alarm timeout)\n"); + exit $ERRORS{"UNKNOWN"}; +}; +alarm($TIMEOUT); + +unless ($dbh = DBI->connect("dbi:Sybase:server=".uc($server), "$username", "$password")) { + printf "SQL CRITICAL: Can't connect to mssql server $DBI::errstr\n"; + exit($ERRORS{'CRITICAL'}); +} + +if (defined $database) { # otherwise use default database + unless ($dbh->do("use $database")) { + printf ("SQL CRITICAL: Can't 'use $database': $dbh->errstr"); + exit($ERRORS{'CRITICAL'}); + } +} +$sth = $dbh->prepare($query); +unless ($sth->execute()) { + printf("SQL CRITICAL: Error in query: $dbh->errstr\n"); + exit($ERRORS{'CRITICAL'}); +} + +$row = join(";",$sth->fetchrow_array); + +$sth->finish; +$dbh->disconnect; + +alarm(0); +if (defined $regex) { + if ($row =~ /$regex/) { + printf "SQL CRITICAL: - $row|$row\n"; + exit $ERRORS{'CRITICAL'}; + }else{ + print "SQL OK: $row|$row\n"; + exit $ERRORS{'OK'}; + } +} + +print "SQL OK: $row|$row\n"; +exit $ERRORS{'OK'}; + +################################################## + +sub syntax { + $s = shift or $s = 'Unknown'; + printf("Error: ($s)\n") unless ($help); + printf("Runs a query against a MS-SQL server or Sybase server and returns the first row\n"); + printf("Returns an error if no responses are running. Row is passed to perfdata in\n"); + printf("semicolon delimited format\n"); + printf("A simple sql statement like \"select getdate()\" verifies server responsiveness\n\n"); + printf("Syntax: %s -s -d -u -p -q [-v]\n", $PROGNAME); + printf(" --database -d Database name\n"); + printf(" --Hostname -H Server name\n"); + printf(" --username -u Username\n"); + printf(" --password -p Password\n"); + printf(" --query -q SQL query to run\n"); + printf(" --timeout -t Plugin timeout (default:$TIMEOUT)\n"); + printf(" --regex -r regex against SQL response(CRIT if MATCH)\n"); + printf(" --verbose -v verbose\n"); + printf("\nThe SQL response is concatenated into a string with a \";\" demarkation\n\n"); + exit($ERRORS{'UNKNOWN'}); +} + +sub process_arguments { + Getopt::Long::Configure('bundling'); + my $status = GetOptions + ("p=s" => \$password, "password=s" => \$password, + "u=s" => \$username, "username=s" => \$username, + "H=s" => \$server, "Hostname=s" => \$server, + "d=s" => \$database, "database=s" => \$database, + "q=s" => \$query, "query=s" => \$query, + "t=i" => \$timeout, "timeout=i" => \$timeout, + "r=s" => \$regex, "regex=s" => \$regex, + "h" => \$help, "help" => \$help, + "v" => \$verbose, "verbose" => \$verbose, + "V" => \$opt_V, "version" => \$opt_V); + + if (defined $opt_V) { + print_revision($PROGNAME,'@NP_VERSION@'); + exit $ERRORS{'OK'}; + } + + syntax("Help:") if ($help); + syntax("Missing username") unless (defined($username)); + syntax("Missing password") unless (defined($password)); + syntax("Missing server") unless (defined($server)); + syntax("Missing query string") unless (defined($query)); + $timeout = $TIMEOUT unless (defined($timeout)); + + return; + +} diff -up ./plugins-scripts/check_netdns.pl.git201706 ./plugins-scripts/check_netdns.pl --- ./plugins-scripts/check_netdns.pl.git201706 2017-07-12 15:25:08.631685372 -0400 +++ ./plugins-scripts/check_netdns.pl 2017-07-12 15:25:08.631685372 -0400 @@ -0,0 +1,145 @@ +#!@PERL@ -w + +# Perl version of check_dns plugin which calls DNS directly instead of +# relying on nslookup (which has bugs) +# +# Copyright 2000, virCIO, LLP +# +# Revision 1.3 2002/05/07 05:35:49 sghosh +# 2nd fix for ePN +# +# Revision 1.2 2002/05/02 16:43:29 sghosh +# fix for embedded perl +# +# Revision 1.1.1.1 2002/02/28 06:43:00 egalstad +# Initial import of existing plugin code +# +# Revision 1.1 2000/08/03 20:41:12 karldebisschop +# rename to avoid conflict when installing +# +# Revision 1.1 2000/08/03 19:27:08 karldebisschop +# use Net::DNS to check name server +# +# Revision 1.1 2000/07/20 19:09:13 cwg +# All the pieces needed to use my version of check_dns. +# +# + +use Getopt::Long; +use Net::DNS; +use FindBin; +use lib "$FindBin::Bin"; +use lib '@libexecdir@'; +use utils ; + +my $PROGNAME = "check_netdns"; + +$ENV{'PATH'}='@TRUSTED_PATH@'; +$ENV{'BASH_ENV'}=''; +$ENV{'ENV'}=''; + +Getopt::Long::Configure(`bundling`); +GetOptions("V" => $opt_V, "version" => $opt_V, + "h" => $opt_h, "help" => $opt_h, + "t=i" => $opt_t, "timeout=i" => $opt_t, + "s=s" => $opt_s, "server=s" => $opt_s, + "H=s" => $opt_H, "hostname=s" => $opt_H); + +# -h means display verbose help screen +if($opt_h){ print_help(); exit 0; } + +# -V means display version number +if ($opt_V) { print_version(); exit 0; } + +# -H means host name +$opt_H = shift unless ($opt_H); +unless ($opt_H) { print_usage(); exit -1; } +if ($opt_H && + $opt_H =~ m/^([0-9]+.[0-9]+.[0-9]+.[0-9]+|[a-zA-Z][-a-zA-Z0]+(.[a-zA-Z][-a-zA-Z0]+)*)$/) +{ + $host = $1; +} else { + print "$opt_H is not a valid host name"; + exit -1; +} + +# -s means server name +$opt_s = shift unless ($opt_s); +if ($opt_s) { + if ($opt_s =~ m/^([0-9]+.[0-9]+.[0-9]+.[0-9]+|[a-zA-Z][-a-zA-Z0]+(.[a-zA-Z][-a-zA-Z0]+)*)$/) + { + $server = $1; + } else { + print "$opt_s is not a valid host name"; + exit -1; + } +} + +# -t means timeout +my $timeout = 10 unless ($opt_t); + +my $res = new Net::DNS::Resolver; +#$res->debug(1); +if ($server) { + $res->nameservers($server); +} + +$res->tcp_timeout($timeout); +$SIG{ALRM} = &catch_alarm; +alarm($timeout); + +$query = $res->query($host); +if ($query) { + my @answer = $query->answer; + if (@answer) { + print join(`/`, map { + $_->type . ` ` . $_->rdatastr; + } @answer); + exit 0; + } else { + print "empty answer"; + exit 2; + } +} +else { + print "query failed: ", $res->errorstring, ""; + exit 2; +} + +sub catch_alarm { + print "query timed out"; + exit 2; +} + +sub print_version () { + my $arg0 = $0; + chomp $arg0; + print "$arg0 version 0.1"; +} +sub print_help() { + print_version(); + print ""; + print "Check if a nameserver can resolve a given hostname."; + print ""; + print_usage(); + print ""; + print "-H, --hostname=HOST"; + print " The name or address you want to query"; + print "-s, --server=HOST"; + print " Optional DNS server you want to use for the lookup"; + print "-t, --timeout=INTEGER"; + print " Seconds before connection times out (default: 10)"; + print "-h, --help"; + print " Print detailed help"; + print "-V, --version"; + print " Print version numbers and license information"; +} + +sub print_usage () { + my $arg0 = $0; + chomp $arg0; + print "$arg0 check_dns -H host [-s server] [-t timeout]"; + print "$arg0 [-h | --help]"; + print "$arg0 [-V | --version]"; +} + diff -up ./plugins-scripts/check_wave.pl.git201706 ./plugins-scripts/check_wave.pl --- ./plugins-scripts/check_wave.pl.git201706 2017-01-16 12:24:03.000000000 -0500 +++ ./plugins-scripts/check_wave.pl 2017-07-12 15:25:08.631685372 -0400 @@ -13,7 +13,8 @@ use vars qw($opt_V $opt_h $verbose $opt_ my (@test, $low1, $med1, $high1, $snr, $low2, $med2, $high2); my ($low, $med, $high, $lowavg, $medavg, $highavg, $tot, $ss); -$PROGNAME = "check_wave"; +$PROGNAME = $0; +chomp $PROGNAME; sub print_help (); sub print_usage (); @@ -41,9 +42,9 @@ if ($opt_h) { } $opt_H = shift unless ($opt_H); -print_usage() unless ($opt_H); +unless ($opt_H) { print_usage(); exit -1; } my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/); -print_usage() unless ($host); +unless ($host) { print_usage(); exit -1; } ($opt_c) || ($opt_c = shift) || ($opt_c = 120); my $critical = $1 if ($opt_c =~ /([0-9]+)/); @@ -51,7 +52,12 @@ my $critical = $1 if ($opt_c =~ /([0-9]+ ($opt_w) || ($opt_w = shift) || ($opt_w = 60); my $warning = $1 if ($opt_w =~ /([0-9]+)/); -$low1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1`; +$low1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1 2>/dev/null`; +unless ($low1) { + print "UNKNOWN - Could not find the 'snmpget' command Please install\n"; + print "the snmp commands (usually net-snmp) before using $PROGNAME\n"; + exit $ERRORS{'UNKNOWN'}; +} @test = split(/ /,$low1); $low1 = $test[2]; @@ -97,7 +103,7 @@ if ($tot==0) { $ss = ($medavg*50) + ($highavg*100); } -printf("Signal Strength at: %3.0f%, SNR at $snr%",$ss); +printf("Signal Strength at: %3.0f%, SNR at $snr%\n",$ss); if ($ss<$critical) { exit(2); diff -up ./plugins/check_apt.c.git201706 ./plugins/check_apt.c --- ./plugins/check_apt.c.git201706 2017-01-16 12:24:03.000000000 -0500 +++ ./plugins/check_apt.c 2017-07-12 15:25:08.632685390 -0400 @@ -73,6 +73,7 @@ char* add_to_regexp(char *expr, const ch /* configuration variables */ static int verbose = 0; /* -v */ static int do_update = 0; /* whether to call apt-get update */ +static int only_critical = 0; /* whether to warn about non-critical updates */ static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */ static char *upgrade_opts = NULL; /* options to override defaults for upgrade */ static char *update_opts = NULL; /* options to override defaults for update */ @@ -110,7 +111,7 @@ int main (int argc, char **argv) { if(sec_count > 0){ result = max_state(result, STATE_CRITICAL); - } else if(packages_available > 0){ + } else if(packages_available > 0 && only_critical == 0){ result = max_state(result, STATE_WARNING); } else if(result > STATE_UNKNOWN){ result = STATE_UNKNOWN; @@ -148,12 +149,13 @@ int process_arguments (int argc, char ** {"include", required_argument, 0, 'i'}, {"exclude", required_argument, 0, 'e'}, {"critical", required_argument, 0, 'c'}, + {"only-critical", no_argument, 0, 'o'}, {"input-file", required_argument, 0, INPUT_FILE_OPT}, {0, 0, 0, 0} }; while(1) { - c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:", longopts, NULL); + c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:o", longopts, NULL); if(c == -1 || c == EOF || c == 1) break; @@ -203,6 +205,9 @@ int process_arguments (int argc, char ** case 'c': do_critical=add_to_regexp(do_critical, optarg); break; + case 'o': + only_critical=1; + break; case INPUT_FILE_OPT: input_filename = optarg; break; @@ -463,7 +468,11 @@ print_help (void) printf (" %s\n", _("upgrades for Debian and Ubuntu:")); printf (" \t\%s\n", SECURITY_RE); printf (" %s\n", _("Note that the package must first match the include list before its")); - printf (" %s\n\n", _("information is compared against the critical list.")); + printf (" %s\n", _("information is compared against the critical list.")); + printf (" %s\n", "-o, --only-critical"); + printf (" %s\n", _("Only warn about upgrades matching the critical list. The total number")); + printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause")); + printf (" %s\n\n", _("the plugin to return WARNING status.")); printf ("%s\n\n", _("The following options require root privileges and should be used with care:")); printf (" %s\n", "-u, --update=OPTS"); diff -up ./plugins/check_disk.c.git201706 ./plugins/check_disk.c --- ./plugins/check_disk.c.git201706 2017-01-19 11:01:31.000000000 -0500 +++ ./plugins/check_disk.c 2017-07-12 15:25:08.632685390 -0400 @@ -127,7 +127,6 @@ enum int process_arguments (int, char **); void print_path (const char *mypath); void set_all_thresholds (struct parameter_list *path); -int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *); void print_help (void); void print_usage (void); double calculate_percent(uintmax_t, uintmax_t); @@ -147,6 +146,7 @@ int erronly = FALSE; int display_mntp = FALSE; int exact_match = FALSE; int freespace_ignore_reserved = FALSE; +int show_status = FALSE; char *warn_freespace_units = NULL; char *crit_freespace_units = NULL; char *warn_freespace_percent = NULL; @@ -171,16 +171,15 @@ main (int argc, char **argv) int result = STATE_UNKNOWN; int disk_result = STATE_UNKNOWN; char *output; - char *details; + char status_lit[4]; char *perf; char *preamble; - char *flag_header; double inode_space_pct; double warning_high_tide; double critical_high_tide; int temp_result; - struct mount_entry *me; + struct mount_entry *me, *last_me = NULL; struct fs_usage fsp, tmpfsp; struct parameter_list *temp_list, *path; @@ -190,7 +189,6 @@ main (int argc, char **argv) preamble = strdup (" - free space:"); output = strdup (""); - details = strdup (""); perf = strdup (""); stat_buf = malloc(sizeof *stat_buf); @@ -206,11 +204,37 @@ main (int argc, char **argv) if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); + if (show_status) + sprintf(status_lit, "x:"); + else + status_lit[0] = '\0'; + /* If a list of paths has not been selected, find entire mount list and create list of paths */ if (path_selected == FALSE) { for (me = mount_list; me; me = me->me_next) { + if (strcmp(me->me_type, "autofs") == 0 && show_local_fs) { + if (last_me == NULL) + mount_list = me; + else + last_me->me_next = me->me_next; + free_mount_entry (me); + continue; + } + if (strcmp(me->me_type, "sysfs") == 0 || strcmp(me->me_type, "proc") == 0 + || strcmp(me->me_type, "debugfs") == 0 || strcmp(me->me_type, "tracefs") == 0 + || strcmp(me->me_type, "fusectl") == 0 || strcmp(me->me_type, "fuse.gvfsd-fuse") == 0 + || strcmp(me->me_type, "cgroup") == 0 || strstr(me->me_type, "tmpfs") != NULL) + { + if (last_me == NULL) + mount_list = me->me_next; + else + last_me->me_next = me->me_next; + free_mount_entry (me); + continue; + } + if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) { path = np_add_parameter(&path_select_list, me->me_mountdir); } @@ -321,6 +345,9 @@ main (int argc, char **argv) if (verbose >=3) printf("Freeinodes_percent result=%d\n", temp_result); disk_result = max_state( disk_result, temp_result ); + if (show_status) + status_lit[0] = state_text(disk_result)[0]; + result = max_state(result, disk_result); /* What a mess of units. The output shows free space, the perf data shows used space. Yikes! @@ -357,14 +384,10 @@ main (int argc, char **argv) if (disk_result==STATE_OK && erronly && !verbose) continue; - if (disk_result && verbose) { - xasprintf(&flag_header, " %s [", state_text (disk_result)); - } - else { - xasprintf(&flag_header, ""); - } - xasprintf (&output, "%s %s %.0f %s (%.2f%%", + xasprintf (&output, "%s%s%s%s %.0f %s (%.2f%%", output, + newlines ? "" : " ", + status_lit, (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, path->dfree_units, units, @@ -384,8 +407,6 @@ main (int argc, char **argv) } } - free(flag_header); - /* TODO: Need to do a similar debug line xasprintf (&details, _("%s\n\ %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"), @@ -398,9 +419,6 @@ main (int argc, char **argv) } - if (verbose >= 2) - xasprintf (&output, "%s%s", output, details); - if (newlines) { printf ("DISK %s%s\n%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf); } else { @@ -483,6 +501,7 @@ process_arguments (int argc, char **argv {"errors-only", no_argument, 0, 'e'}, {"exact-match", no_argument, 0, 'E'}, {"all", no_argument, 0, 'A'}, + {"show-status", no_argument, 0, 's'}, {"verbose", no_argument, 0, 'v'}, {"quiet", no_argument, 0, 'q'}, {"clear", no_argument, 0, 'C'}, @@ -502,7 +521,7 @@ process_arguments (int argc, char **argv strcpy (argv[c], "-t"); while (1) { - c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEAn", longopts, &option); + c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEAns", longopts, &option); if (c == -1 || c == EOF) break; @@ -703,6 +722,10 @@ process_arguments (int argc, char **argv cflags = default_cflags; break; + case 's': + show_status = TRUE; + break; + case 'A': optarg = strdup(".*"); case 'R': @@ -839,50 +862,6 @@ set_all_thresholds (struct parameter_lis set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); } -/* TODO: Remove? - -int -validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath) -{ - if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) { - printf (_("INPUT ERROR: No thresholds specified")); - print_path (mypath); - return ERROR; - } - else if ((wp >= 0.0 || cp >= 0.0) && - (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) { - printf (_("\ -INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"), - cp, wp); - print_path (mypath); - return ERROR; - } - else if ((iwp >= 0.0 || icp >= 0.0) && - (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) { - printf (_("\ -INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"), - icp, iwp); - print_path (mypath); - return ERROR; - } - else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) { - printf (_("\ -INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"), - (unsigned long)c, (unsigned long)w); - print_path (mypath); - return ERROR; - } - - return OK; -} - -*/ - - - - - - void print_help (void) @@ -949,6 +928,8 @@ print_help (void) printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); + printf (" %s\n", "-s, --show-status"); + printf (" %s\n", _("Show status for each path/partition")); printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); printf (" %s\n", "-u, --units=STRING"); printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); @@ -980,16 +961,20 @@ print_usage (void) { printf ("%s\n", _("Usage:")); printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname); - printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); - printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type] [-n]\n"); + printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] {-A | [-R path] [-r path]}\n"); + printf ("[-s] [-t timeout] [-u unit] [-v] [-X type] [-N type] [-n]\n"); } void stat_path (struct parameter_list *p) { /* Stat entry to check that dir exists and is accessible */ - if (verbose >= 3) - printf("calling stat on %s\n", p->name); + if (verbose >= 3) { + if (p->best_match) + printf("calling stat on %s (%s %s)\n", p->name, p->best_match->me_devname, p->best_match->me_type); + else + printf("calling stat on %s\n", p->name); + } if (stat (p->name, &stat_buf[0])) { if (verbose >= 3) printf("stat failed on %s\n", p->name); diff -up ./plugins/check_http.c.git201706 ./plugins/check_http.c --- ./plugins/check_http.c.git201706 2017-04-19 12:03:12.000000000 -0400 +++ ./plugins/check_http.c 2017-07-12 15:26:38.842309188 -0400 @@ -146,6 +146,9 @@ char *perfd_size (int page_len); void print_help (void); void print_usage (void); +extern int check_hostname; + + int main (int argc, char **argv) { @@ -200,7 +203,8 @@ process_arguments (int argc, char **argv enum { INVERT_REGEX = CHAR_MAX + 1, - SNI_OPTION + SNI_OPTION, + VERIFY_HOST }; int option = 0; @@ -210,6 +214,7 @@ process_arguments (int argc, char **argv {"nohtml", no_argument, 0, 'n'}, {"ssl", optional_argument, 0, 'S'}, {"sni", no_argument, 0, SNI_OPTION}, + {"verify-host", no_argument, 0, VERIFY_HOST}, {"post", required_argument, 0, 'P'}, {"method", required_argument, 0, 'j'}, {"IP-address", required_argument, 0, 'I'}, @@ -368,6 +373,9 @@ process_arguments (int argc, char **argv case SNI_OPTION: use_sni = TRUE; break; + case VERIFY_HOST: + check_hostname = 1; + break; case 'f': /* onredirect */ if (!strcmp (optarg, "stickyport")) onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT; @@ -694,14 +702,12 @@ int chunk_header(char **buf) if (lth <= 0) return lth; - while (**buf != '\r' && **buf != '\n') + while (**buf !='\0' && **buf != '\r' && **buf != '\n') ++*buf; // soak up the leading CRLF - if (**buf && **buf == '\r' && *(++*buf) && **buf == '\n') + while (**buf != '\0' && (**buf == '\r' || **buf == '\n')) ++*buf; - else - die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse chunked body, invalid format\n")); return lth; } @@ -724,7 +730,7 @@ decode_chunked_page (const char *raw, ch dst_pos += chunksize; *dst_pos = '\0'; - if (*raw_pos && *raw_pos == '\r' && *(++raw_pos) && *raw_pos == '\n') + while (*raw_pos && (*raw_pos == '\r' || *raw_pos == '\n')) raw_pos++; } @@ -749,6 +755,8 @@ header_value (const char *headers, const while (*s && isspace(*s)) s++; value_end = strchr(s, '\r'); + if (!value_end) + value_end = strchr(s, '\n'); if (!value_end) { // Turns out there's no newline after the header... So it's at the end! value_end = s + strlen(s); @@ -1027,8 +1035,8 @@ check_http (void) if (check_cert == TRUE) { result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); if (result != STATE_OK) { - np_net_ssl_cleanup(); if (sd) close(sd); + np_net_ssl_cleanup(); return result; } } @@ -1134,15 +1142,19 @@ check_http (void) elapsed_time_firstbyte = (double)microsec_firstbyte / 1.0e6; } buffer[i] = '\0'; - xasprintf (&full_page_new, "%s%s", full_page, buffer); - free (full_page); + /* xasprintf (&full_page_new, "%s%s", full_page, buffer); */ + if ((full_page_new = realloc(full_page, pagesize + i + 1)) == NULL) + die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate memory for full_page\n")); + + memmove(&full_page_new[pagesize], buffer, i); + /*free (full_page);*/ full_page = full_page_new; pagesize += i; - if (no_body && document_headers_done (full_page)) { - i = 0; - break; - } + if (no_body && document_headers_done (full_page)) { + i = 0; + break; + } } microsec_transfer = deltime (tv_temp); elapsed_time_transfer = (double)microsec_transfer / 1.0e6; @@ -1206,7 +1218,7 @@ check_http (void) /* find header info and null-terminate it */ header = page; for (;;) { - if (!strncmp(page, "\r\n\r\n", 4) || !strncmp(page, "\n\n", 2)) + if (!*page || !strncmp(page, "\r\n\r\n", 4) || !strncmp(page, "\n\n", 2)) break; while (*page == '\r' || *page == '\n') { ++page; } page += (size_t) strcspn (page, "\r\n"); @@ -1668,6 +1680,10 @@ print_help (void) printf (" %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted.")); printf (" %s\n", "--sni"); printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + printf (" %s\n", "--verify-host"); + printf (" %s\n", _("Verify SSL certificate is for the -H hostname (with --sni and -S)")); +#endif printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); printf (" %s\n", _("(when this option is used the URL is not checked.)")); @@ -1802,6 +1818,11 @@ print_usage (void) printf (" [-b proxy_auth] [-f ]\n"); printf (" [-e ] [-d string] [-s string] [-l] [-r | -R ]\n"); printf (" [-P string] [-m :] [-4|-6] [-N] [-M ]\n"); - printf (" [-A string] [-k string] [-S ] [--sni] [-C [,]]\n"); - printf (" [-T ] [-j method]\n"); +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + printf (" [-A string] [-k string] [-S ] [--sni] [--verify-host]\n"); + printf (" [-C [,]] [-T ] [-j method]\n"); +#else + printf (" [-A string] [-k string] [-S ] [--sni] [-C [,]]\n"); + printf (" [-T ] [-j method]\n"); +#endif } diff -up ./plugins/check_ntp_time.c.git201706 ./plugins/check_ntp_time.c --- ./plugins/check_ntp_time.c.git201706 2017-01-19 11:01:31.000000000 -0500 +++ ./plugins/check_ntp_time.c 2017-07-12 15:25:08.633685408 -0400 @@ -80,6 +80,7 @@ typedef struct { /* this structure holds data about results from querying offset from a peer */ typedef struct { time_t waiting; /* ts set when we started waiting for a response */ + int connected; /* don't try to "write()" if "connect()" fails */ int num_responses; /* number of successfully recieved responses */ uint8_t stratum; /* copied verbatim from the ntp_message */ double rtdelay; /* converted from the ntp_message */ @@ -355,6 +356,7 @@ double offset_request(const char *host, ufds[i].fd=socklist[i]; ufds[i].events=POLLIN; ufds[i].revents=0; + servers[i].connected=1; } ai_tmp = ai_tmp->ai_next; } @@ -370,6 +372,8 @@ double offset_request(const char *host, now_time=time(NULL); for(i=0; i timeout_interval/2) break; } if (one_read == 0) { diff -up ./plugins/check_ping.c.git201706 ./plugins/check_ping.c --- ./plugins/check_ping.c.git201706 2017-01-16 12:24:03.000000000 -0500 +++ ./plugins/check_ping.c 2017-07-12 15:25:08.633685408 -0400 @@ -54,6 +54,7 @@ void print_usage (void); void print_help (void); int display_html = FALSE; +int show_resolution = FALSE; int wpl = UNKNOWN_PACKET_LOSS; int cpl = UNKNOWN_PACKET_LOSS; float wrta = UNKNOWN_TRIP_TIME; @@ -67,6 +68,8 @@ int verbose = 0; float rta = UNKNOWN_TRIP_TIME; int pl = UNKNOWN_PACKET_LOSS; +char ping_name[256]; +char ping_ip_addr[64]; char *warn_text; @@ -159,6 +162,12 @@ main (int argc, char **argv) else printf (_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text (this_result), warn_text, pl, rta); + if (show_resolution) { + if (strcmp(ping_name, ping_ip_addr) == 0) + printf(" - %s", ping_name); + else + printf(" - %s (%s)", ping_name, ping_ip_addr); + } if (display_html == TRUE) printf (""); @@ -196,6 +205,7 @@ process_arguments (int argc, char **argv static struct option longopts[] = { STD_LONG_OPTS, {"packets", required_argument, 0, 'p'}, + {"show-resolution", no_argument, 0, 's'}, {"nohtml", no_argument, 0, 'n'}, {"link", no_argument, 0, 'L'}, {"use-ipv4", no_argument, 0, '4'}, @@ -214,7 +224,7 @@ process_arguments (int argc, char **argv } while (1) { - c = getopt_long (argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); + c = getopt_long (argc, argv, "VvhsnL46t:c:w:H:p:", longopts, &option); if (c == -1 || c == EOF) break; @@ -271,6 +281,9 @@ process_arguments (int argc, char **argv else usage2 (_(" (%s) must be a non-negative number\n"), optarg); break; + case 's': + show_resolution = TRUE; + break; case 'n': /* no HTML */ display_html = FALSE; break; @@ -448,6 +461,9 @@ run_ping (const char *cmd, const char *a result = max_state (result, error_scan (buf, addr)); + if(sscanf(buf, "PING %255s (%63[^)]", &ping_name, &ping_ip_addr)) + continue; + /* get the percent loss statistics */ match = 0; if((sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) || @@ -585,6 +601,8 @@ print_help (void) printf (" %s\n", "-p, --packets=INTEGER"); printf (" %s ", _("number of ICMP ECHO packets to send")); printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS); + printf (" %s\n", "-s, --show-resolution"); + printf (" %s\n", _("show name resolution in the plugin output (DNS & IP)")); printf (" %s\n", "-L, --link"); printf (" %s\n", _("show HTML in the plugin output (obsoleted by urlize)")); diff -up ./plugins/common.h.git201706 ./plugins/common.h --- ./plugins/common.h.git201706 2017-01-19 11:01:31.000000000 -0500 +++ ./plugins/common.h 2017-07-12 15:25:08.633685408 -0400 @@ -146,6 +146,9 @@ # include # include # include +# if OPENSSL_VERSION_NUMBER >= 0x10002000L +# include +# endif # include # include # include @@ -154,6 +157,9 @@ # include # include # include +# if OPENSSL_VERSION_NUMBER >= 0x10002000L +# include +# endif # include # include # include diff -up ./plugins/sslutils.c.git201706 ./plugins/sslutils.c --- ./plugins/sslutils.c.git201706 2017-04-19 12:03:12.000000000 -0400 +++ ./plugins/sslutils.c 2017-07-12 15:25:08.633685408 -0400 @@ -35,6 +35,8 @@ static SSL_CTX *c=NULL; static SSL *s=NULL; static int initialized=0; +int check_hostname = 0; + int np_net_ssl_init(int sd) { return np_net_ssl_init_with_hostname(sd, NULL); } @@ -157,6 +159,16 @@ int np_net_ssl_init_with_hostname_versio #endif SSL_set_fd(s, sd); if (SSL_connect(s) == 1) { +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + if (check_hostname && host_name && *host_name) { + X509 *certificate=SSL_get_peer_certificate(s); + int rc = X509_check_host(certificate, host_name, 0, 0, NULL); + if (rc != 1) { + printf("%s\n", _("CRITICAL - Hostname mismatch.")); + return STATE_CRITICAL; + } + } +#endif return OK; } else { printf("%s\n", _("CRITICAL - Cannot make SSL connection.")); diff -up ./plugins/t/check_apt.t.git201706 ./plugins/t/check_apt.t --- ./plugins/t/check_apt.t.git201706 2017-01-16 12:24:03.000000000 -0500 +++ ./plugins/t/check_apt.t 2017-07-12 15:25:08.633685408 -0400 @@ -23,7 +23,7 @@ sub make_result_regexp { } if (-x "./check_apt") { - plan tests => 28; + plan tests => 36; } else { plan skip_all => "No check_apt compiled"; } @@ -40,10 +40,18 @@ $result = NPTest->testCmd( sprintf($test is( $result->return_code, 1, "Debian apt output, warning" ); like( $result->output, make_result_regexp(13, 0), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian2") ); +is( $result->return_code, 0, "Debian apt output, no critical" ); +like( $result->output, make_result_regexp(13, 0), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") ); is( $result->return_code, 2, "Debian apt output, some critical" ); like( $result->output, make_result_regexp(19, 4), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian3") ); +is( $result->return_code, 2, "Debian apt output, some critical" ); +like( $result->output, make_result_regexp(19, 4), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "-c '^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)'", "debian3") ); is( $result->return_code, 2, "Debian apt output - should have same result when default security regexp specified via -c" ); like( $result->output, make_result_regexp(19, 4), "Output correct" ); @@ -52,6 +60,10 @@ $result = NPTest->testCmd( sprintf($test is( $result->return_code, 1, "Debian apt output, filter for libc6" ); like( $result->output, make_result_regexp(3, 0), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") ); +is( $result->return_code, 1, "Debian apt output, filter for libc6, not critical" ); +like( $result->output, make_result_regexp(3, 0), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6 -i xen", "debian3") ); is( $result->return_code, 2, "Debian apt output, filter for libc6 and xen" ); like( $result->output, make_result_regexp(9, 4), "Output correct" ); @@ -64,6 +76,10 @@ $result = NPTest->testCmd( sprintf($test is( $result->return_code, 2, "Debian apt output, filter out libc6" ); like( $result->output, make_result_regexp(16, 4), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -o", "debian3") ); +is( $result->return_code, 2, "Debian apt output, filter out libc6, critical" ); +like( $result->output, make_result_regexp(16, 4), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -e xen", "debian3") ); is( $result->return_code, 1, "Debian apt output, filter out libc6 and xen" ); like( $result->output, make_result_regexp(10, 0), "Output correct" );