diff -Nru nagios-plugins-contrib-22.20181105+1/check_httpd_status/check_httpd_status nagios-plugins-contrib-23.20190206/check_httpd_status/check_httpd_status
--- nagios-plugins-contrib-22.20181105+1/check_httpd_status/check_httpd_status 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_httpd_status/check_httpd_status 2019-02-06 12:45:06.000000000 +0000
@@ -235,6 +235,10 @@
my $patternFound = 0;
my $Uptime = 0;
+# if ( $webcontent =~ m/Uptime: (.*?)\n/) {
+ # $Uptime = $1;
+ # $patternFound++;
+# }
### FIXME XH 20171204 catch ServerUptimeSeconds, not [Server]Uptime. Change in server-status between 2.2 & 2.4
if ( $webcontent =~ m/\b(ServerUptimeSeconds|Uptime): (\d+)\n/) {
$Uptime = $2;
diff -Nru nagios-plugins-contrib-22.20181105+1/check_httpd_status/control nagios-plugins-contrib-23.20190206/check_httpd_status/control
--- nagios-plugins-contrib-22.20181105+1/check_httpd_status/control 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_httpd_status/control 2019-02-06 12:45:06.000000000 +0000
@@ -1,7 +1,7 @@
Homepage: http://cvs.orion.education.fr/viewvc/viewvc.cgi/nagios-plugins-perl/trunk/plugins/check_httpd_status.pl?view=log
Watch: http://cvs.orion.education.fr/viewvc/viewvc.cgi/nagios-plugins-perl/trunk/plugins/check_httpd_status.pl?view=log
Recommends: liblocale-gettext-perl, libmonitoring-plugin-perl | libnagios-plugin-perl, liblwp-useragent-determined-perl
-Version: rev193
+Version: rev204
Uploaders: Jan Wagner
Description: plugin checking Apache or Lighthttpd
server-status page (using mod_status)
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/changelog nagios-plugins-contrib-23.20190206/check_ipmi_sensor/changelog
--- nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/changelog 1970-01-01 00:00:00.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ipmi_sensor/changelog 2019-02-06 12:45:06.000000000 +0000
@@ -0,0 +1,129 @@
+################################################################################
+Changelog for check_ipmi_sensor, a Nagios/Icinga plugin to check IPMI sensors
+################################################################################
+
+Version 3.13 20190123
+ * Option --unify-sensors to unify sensor names across platforms
+ (closes issue #8)
+ * Options --xx and -sx now support regular expressions (closes issue #25)
+ * Added --selonly option to check only System Event Log (closes issue #12)
+ * Added --seltail to limit SEL output to specified count of last messages
+ * Added ipmi-dcmi command to fetch current power (closes issue #26)
+ * Added spec file for creating a rpm file under RHEL (closes issue #24)
+ * Added check sensor event and reading for absent sensors
+ * Added installation hints for CentOS
+ * Bug fixes and minor improvements
+ * Updated help texts and usage information
+ * Updated copyright information
+
+Version 3.12 20161005
+ * New Options added (closes issue #6)
+ Option -xT to exclude monitored sensor types
+ Option -xST to exclude SEL entries of specific sensor types
+ * Improved error message when a monitored server seems to be powered off
+ * More comprehensible output for warnings caused by SEL entries
+ (closes issue #7)
+
+Version 3.11 20160524
+ * Skip entities which are absent if '--noentityabsent' is present
+ * Per default monitor all SEL sensor types
+ Add command line flag to specify entry types for SEL
+
+Version 3.10 20151020
+ * Only monitor specific sensor types from the system event log (SEL).
+ The check with ipmi-sel is limited to types of Memory and Processor for
+ monitoring.
+
+Version 3.9 20150624
+ * Add exclude files for sensors - use name and type in a file to exclude not
+ needed sensors (-xx for normal sensors, -sx for SEL entries).
+
+Version 3.8 20150402
+ * If ipmi host is ommited, localhost is assumed without a LAN driver
+ * Add a 'nosudo' option to disable sudo
+ * Only add sudo if user is not already root
+ * Fix base command usage on localhost
+ * Only add hostname parameter if not on localhost
+ * Check if freeipmi version supports output-sensor-thresholds
+ * Print sensor thresholds fetched via output-sensor-thresholds
+
+Version 3.7 20150211
+ * Add LAN driver LAN_2_0 to ipmi-sel and ipmi-fru
+
+Version 3.6 20150107
+ * Fix ipmi calls on localhost with sudo
+ * Monitor ipmi system event log with ipmi-sel
+ * Enhance verbose output for sensors, fru and sel
+
+Version 3.5 20141031
+ * Fix LAN Driver if called on localhost
+
+Version 3.4 20140929
+ * Fix implicit array warning with split
+ * Add option to disable LAN protocol version 2.0
+
+Version 3.3 20140606
+ * Print a warning if ipmi-sensors only returned a single output row
+ * Ignore sudo errors and warnings in IPMI command output
+ (Thanks to Robert Heinzmann for contributing)
+ * Use LAN protocol version 2.0 per default
+ * Print empty output error only if return code was 0
+ * Exit the plugin with return code 3 if fru command fails
+ * Added an include list option to only include specific sensors
+
+Version 3.2 20131028
+ * Added FRU serial number to output
+ * Add check if ipmimonitoring output is empty
+ * Print correct command in verbose output
+ * Number of fans can be compared to a desired number of fans
+
+Version 3.2-dev 20120627
+ * Help text cleanups (hint on 'ipmi-sensors -L').
+
+Version 3.1 20120524
+ Version 3.1-dev (20120312-20120508)
+ * Documentation cleanups.
+ * Added PNP4Nagios default-combinedgraph.template in contrib/ directory.
+ (was missing for 3.* version)
+ * Updated help text (-v|-vv|-vvv verbose outputs).
+ * Renamed check_ipmi_sensor.pl to check_ipmi_sensor.
+ * Added output of check_ipmi_sensor version.
+ * Added newlines to debug output master.
+ Version 3.1rc1 20120222
+ * Reformatted code to be as close as possible to check_ipmi_sensor v2 (bash).
+ * Fetched Version 3.0 from https://github.com/zito/check_ipmi_sensor.git
+ * Moved development to git.thomas-krenn.com
+ * Added various default options.
+
+Version 3.0 20110501
+ * The code rewritten using the Perl.
+ * Added long variant options.
+ * Removed trailing zeros after the decimal point in perfdata.
+ * Output format of the ipmimonitoring version 0.8.x and up supported.
+
+Version 2.2 20110127
+ * Added -b option to enable backward compatibility with FreeIPMI 0.5.*.
+ reported by: Tobias Gablunsky, CBXNET combox internet GmbH
+ * Added ipmimonitoring version information in verbose output (-v 3).
+ * Further improved readability of the help text (-x Option).
+
+List of contributors to version 3.* branch:
+ Werner Fischer, Thomas-Krenn.AG
+ Georg Schönberger, Thomas-Krenn.AG
+ Václav Ovsík (ported version 2 to Perl)
+ Robert Heinzmann
+
+List of contributors to version 2.* branch:
+ Werner Fischer, Thomas-Krenn.AG (author)
+ Tobias Gablunsky, CBXNET combox internet GmbH
+ Sebastian Mörchen, DFS Deutsche Flugsicherung GmbH
+ Gustav Olsson, Telavox AB
+
+List of contributors to version 1.* branch:
+ Nikolaus Filus (to version 1.3rc1)
+ Werner Fischer, Thomas-Krenn.AG (author)
+ Lars Meuser, LMA Deutschland GmbH (to version 1.2.1)
+ Holger Paschke, comspace GmbH & Co. KG (to version 1.2)
+ Ulrich Zehl, lagis Internet Serviceprovider GmbH (to version 1.1)
+
+################################################################################
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/changelog.txt nagios-plugins-contrib-23.20190206/check_ipmi_sensor/changelog.txt
--- nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/changelog.txt 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ipmi_sensor/changelog.txt 1970-01-01 00:00:00.000000000 +0000
@@ -1,115 +0,0 @@
-################################################################################
-Changelog for check_ipmi_sensor, a Nagios/Icinga plugin to check IPMI sensors
-################################################################################
-
-Version 3.12 20161005
- * New Options added (closes issue #6)
- Option -xT to exclude monitored sensor types
- Option -xST to exclude SEL entries of specific sensor types
- * Improved error message when a monitored server seems to be powered off
- * More comprehensible output for warnings caused by SEL entries
- (closes issue #7)
-
-Version 3.11 20160524
- * Skip entities which are absent if '--noentityabsent' is present
- * Per default monitor all SEL sensor types
- Add command line flag to specify entry types for SEL
-
-Version 3.10 20151020
- * Only monitor specific sensor types from the system event log (SEL).
- The check with ipmi-sel is limited to types of Memory and Processor for
- monitoring.
-
-Version 3.9 20150624
- * Add exclude files for sensors - use name and type in a file to exclude not
- needed sensors (-xx for normal sensors, -sx for SEL entries).
-
-Version 3.8 20150402
- * If ipmi host is ommited, localhost is assumed without a LAN driver
- * Add a 'nosudo' option to disable sudo
- * Only add sudo if user is not already root
- * Fix base command usage on localhost
- * Only add hostname parameter if not on localhost
- * Check if freeipmi version supports output-sensor-thresholds
- * Print sensor thresholds fetched via output-sensor-thresholds
-
-Version 3.7 20150211
- * Add LAN driver LAN_2_0 to ipmi-sel and ipmi-fru
-
-Version 3.6 20150107
- * Fix ipmi calls on localhost with sudo
- * Monitor ipmi system event log with ipmi-sel
- * Enhance verbose output for sensors, fru and sel
-
-Version 3.5 20141031
- * Fix LAN Driver if called on localhost
-
-Version 3.4 20140929
- * Fix implicit array warning with split
- * Add option to disable LAN protocol version 2.0
-
-Version 3.3 20140606
- * Print a warning if ipmi-sensors only returned a single output row
- * Ignore sudo errors and warnings in IPMI command output
- (Thanks to Robert Heinzmann for contributing)
- * Use LAN protocol version 2.0 per default
- * Print empty output error only if return code was 0
- * Exit the plugin with return code 3 if fru command fails
- * Added an include list option to only include specific sensors
-
-Version 3.2 20131028
- * Added FRU serial number to output
- * Add check if ipmimonitoring output is empty
- * Print correct command in verbose output
- * Number of fans can be compared to a desired number of fans
-
-Version 3.2-dev 20120627
- * Help text cleanups (hint on 'ipmi-sensors -L').
-
-Version 3.1 20120524
- Version 3.1-dev (20120312-20120508)
- * Documentation cleanups.
- * Added PNP4Nagios default-combinedgraph.template in contrib/ directory.
- (was missing for 3.* version)
- * Updated help text (-v|-vv|-vvv verbose outputs).
- * Renamed check_ipmi_sensor.pl to check_ipmi_sensor.
- * Added output of check_ipmi_sensor version.
- * Added newlines to debug output master.
- Version 3.1rc1 20120222
- * Reformatted code to be as close as possible to check_ipmi_sensor v2 (bash).
- * Fetched Version 3.0 from https://github.com/zito/check_ipmi_sensor.git
- * Moved development to git.thomas-krenn.com
- * Added various default options.
-
-Version 3.0 20110501
- * The code rewritten using the Perl.
- * Added long variant options.
- * Removed trailing zeros after the decimal point in perfdata.
- * Output format of the ipmimonitoring version 0.8.x and up supported.
-
-Version 2.2 20110127
- * Added -b option to enable backward compatibility with FreeIPMI 0.5.*.
- reported by: Tobias Gablunsky, CBXNET combox internet GmbH
- * Added ipmimonitoring version information in verbose output (-v 3).
- * Further improved readability of the help text (-x Option).
-
-List of contributors to version 3.* branch:
- Werner Fischer, Thomas-Krenn.AG
- Georg Schönberger, Thomas-Krenn.AG
- Václav Ovsík (ported version 2 to Perl)
- Robert Heinzmann
-
-List of contributors to version 2.* branch:
- Werner Fischer, Thomas-Krenn.AG (author)
- Tobias Gablunsky, CBXNET combox internet GmbH
- Sebastian Mörchen, DFS Deutsche Flugsicherung GmbH
- Gustav Olsson, Telavox AB
-
-List of contributors to version 1.* branch:
- Nikolaus Filus (to version 1.3rc1)
- Werner Fischer, Thomas-Krenn.AG (author)
- Lars Meuser, LMA Deutschland GmbH (to version 1.2.1)
- Holger Paschke, comspace GmbH & Co. KG (to version 1.2)
- Ulrich Zehl, lagis Internet Serviceprovider GmbH (to version 1.1)
-
-################################################################################
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/check_ipmi_sensor nagios-plugins-contrib-23.20190206/check_ipmi_sensor/check_ipmi_sensor
--- nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/check_ipmi_sensor 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ipmi_sensor/check_ipmi_sensor 2019-02-06 12:45:06.000000000 +0000
@@ -1,7 +1,7 @@
#!/usr/bin/perl
# check_ipmi_sensor: Nagios/Icinga plugin to check IPMI sensors
#
-# Copyright (C) 2009-2016 Thomas-Krenn.AG,
+# Copyright (C) 2009-2019 Thomas-Krenn.AG,
# additional contributors see changelog.txt
#
# This program is free software; you can redistribute it and/or modify it under
@@ -35,12 +35,12 @@
use IPC::Run qw( run ); #interact with processes
################################################################################
# set text variables
-our $check_ipmi_sensor_version = "3.12";
+our $check_ipmi_sensor_version = "3.13";
sub get_version{
return <
[-f | -U -P -L ]
- [-O ] [-b] [-T ] [-x ]
- [-xT ] [-xST ] [-b] [-T ] [-ST ]
+ [-x ] [-xT ] [-xST ] [-o zenoss] [-D ] [-h] [-V]
- [-fc ] [--fru] [--nosel] [--nothresholds] [--nosudo]
+ [-fc ] [--fru] [--nosel] [--selonly] [--seltail ]
+ [-sx|--selexclude ] [-xx|--sexclude ]
+ [-us|--unify-sensors ] [--nosudo [--nothresholds]
+ [--noentityabsent] [-s ] [-h] [-V]
[-v|-vv|-vvv]
EOT
}
@@ -96,8 +99,10 @@
Examples for IPMI sensor types are 'Fan', 'Temperature', 'Voltage', ...
See the output of the FreeIPMI command 'ipmi-sensors -L' and chapter
'42.2 Sensor Type Codes and Data' of the IPMI 2.0 spec for a full list
- of possible sensor types. The available types depend on your particular
- server and the available sensors there.
+ of possible sensor types. You can also find the full list of possible
+ sensor types at https://www.thomas-krenn.com/en/wiki/IPMI_Sensor_Types
+ The available types depend on your particular server and the available
+ sensors there.
Multiple sensor types can be specified as a comma-separated list.
[-ST ]
limit SEL entries to specific types, run 'ipmi-sel -L' for a list of
@@ -137,9 +142,10 @@
version if not overwritten with this option. Use 'default' here if you
don't want to use LAN_2_0.
[-fc ]
- number of fans that should be active. If the number of current active
- fans reported by IPMI is smaller than then a Warning state
- is returned.
+ number of installed fans. If the number of current installed
+ fans reported by IPMI is not equal than then a Warning state
+ is returned. Please use this option carefully as number of fans and
+ number of fan sensors can differ!
[--fru]
print the product serial number if it is available in the IPMI FRU data.
For this purpose the tool 'ipmi-fru' is used. E.g.:
@@ -148,6 +154,12 @@
turn off system event log checking via ipmi-sel. If there are
unintentional entries in SEL, use 'ipmi-sel --clear' or the -sx or -xST
option.
+ [--selonly]
+ check only system event log checking via ipmi-sel. If there are
+ unintentional entries in SEL, use 'ipmi-sel --clear' or the -sx or -xST
+ option.
+ [--seltail ]
+ limit SEL output to specified count of last messages
[-sx|--selexclude ]
use a sel exclude file to exclude entries from the system event log.
Specify name and type pipe delimitered in this file to exclude an entry,
@@ -155,10 +167,24 @@
To get valid names and types use the -vvv option and take a look at:
debug output for sel (-vvv is set). Don't use name and type from the
web interface as sensor descriptions are not complete there.
+ As with the '-xx' option if the first character of a line is '~' the
+ name is treated as a regular expression.
[-xx|--sexclude ]
- use an exclude file to exclude sensors.
+ use an exclude file to exclude sensors, each line specifies an exclude.
Specify name and type pipe delimitered in this file to exclude a sensor,
+ for example: System Chassis Chassis Intru|Physical Security
+ If the first character of a line is '~' the name is treated as a regular
+ expression. E.g. to exclude all sensor names from CPU0 to CPU9:
+ ~CPU[0-9] Temp|Temperature
To get valid names and types use the -vvv option.
+ [-us|--unify-sensors ]
+ use an unify file to unify sensor names. This is an easy way to rename
+ sensors with given patterns in the file. Once might use this option
+ to get the same sensor names accross different platforms, e.g. to only
+ have 'Mainboard Temperature' as sensor name and not 'MB1 Temperature' or 'System Temp'.
+ Rules in the file follow simple regex patterns e.g.:
+ ^(MB1 Temperature|System Temp)\$/Mainboard Temperature
+ Temp\$/TEMP
[--nosudo]
turn off sudo usage on localhost or if ipmi host is ommited.
[--nothresholds]
@@ -189,10 +215,10 @@
http://www.thomas-krenn.com/en/wiki/IPMI_Sensor_Monitoring_Plugin
Use the github repo at https://github.com/thomas-krenn/check_ipmi_sensor_v3.git
-to submit patches, or suggest improvements.
+to submit patches, suggest improvements or if you have questions regarding
+use of this plugin.
-Send email to the IPMI-plugin-user mailing list if you have questions regarding
-use of this software. The mailing list is available at
+Attention: the mailing list is no longer in use but an archive can be found at
http://lists.thomas-krenn.com/
EOT
}
@@ -364,6 +390,62 @@
return \@sel_rows;
}
+sub get_dcmi{
+ my @dcmicmd = @{(shift)};
+ my $verbosity = shift;
+ my $dcmi;
+ if(-e '/usr/sbin/ipmi-dcmi'){
+ $dcmi = '/usr/sbin/ipmi-dcmi';
+ }
+ else{
+ chomp($dcmi = `which ipmi-dcmi`);
+ }
+ #if sudo is used the command is the second element
+ if($dcmicmd[0] eq 'sudo'){
+ $dcmicmd[1] = $dcmi;
+ }
+ else{
+ $dcmicmd[0] = $dcmi;
+ }
+ push @dcmicmd, '--get-system-power-statistics';
+
+ my $dcmioutput;
+ my $returncode;
+ run \@dcmicmd, '>&', \$dcmioutput;
+ $returncode = $? >> 8;
+ if ( $returncode == 0 ){
+ return split('\n', $dcmioutput);
+ }
+}
+
+sub parse_dcmi{
+ my $dcmicmd = shift;
+ my $verbosity = shift;
+ my @dcmioutput = get_dcmi($dcmicmd, $verbosity);
+ if(@dcmioutput){
+ @dcmioutput = map { [ map { s/^\s*//; s/\s*$//; $_; } split(m/\:/, $_) ] } @dcmioutput;
+ my %current_power;
+ my $power_available = 0;
+ foreach my $power (@dcmioutput){
+ if(defined($power) && defined($power->[0]) && $power->[0] ne ''){
+ if($power->[0] eq 'Current Power'){
+ $power->[1] =~ m/^(\d+)/;
+ my $watts = $1;
+ $current_power{'Current Power'} = $watts;
+ }
+ if($power->[0] eq 'Power Measurement'){
+ if($power->[1] eq 'Active'){
+ $power_available = 1;
+ }
+ }
+ }
+ }
+ if($power_available == 1){
+ return \%current_power;
+ }
+ }
+}
+
# Excludes a name and type pair if it is present in the given file, pipe
# delimitered.
# @return 1 if name should be skipped, 0 if not
@@ -382,15 +464,49 @@
}
foreach my $exclude (@xlist){
my @curr_exclude = map { s/^\s*//; s/\s*$//; $_; } split(/\|/,$exclude);
- if($curr_exclude[0] eq $name &&
- $curr_exclude[1] eq $type){
- $skip = 1;
+ if(@curr_exclude && $curr_exclude[0] ne '' && $curr_exclude[1] ne ''){
+ #if the first char of the name in the exclude file is a '~' treat it as regex
+ if(substr($curr_exclude[0], 0, 1 ) eq '~'){
+ my $regex_curr_exclude = substr $curr_exclude[0], 1;
+ if($name =~ m/$regex_curr_exclude/ && $curr_exclude[1] eq $type){
+ $skip = 1;
+ }
+ }
+ elsif($curr_exclude[0] eq $name && $curr_exclude[1] eq $type){
+ $skip = 1;
+ }
}
}
close FH;
return $skip;
}
+# Reads regular expressions from a file and applies the rules to sensor names.
+# This unifies sensor names across different platforms.
+# @return The sensor name with specified unify rules applied
+sub unify_with_file{
+ my $file_name = shift;
+ my $name = shift;# given sensor name
+ my @ulist;# list of rules to apply
+ if($file_name){
+ if(!(open (FH, "< $file_name"))){
+ print "-> Reading unify file $file_name failed with: $!.\n";
+ exit(3);
+ };
+ @ulist = ;
+ }
+ foreach my $unify_rule (@ulist){
+ #split at the only / that is not masked with a \,
+ #this is the separator in s/x/y/g to get x and y
+ my @curr_rule = map { s/^\s*//; s/\s*$//; $_; } split(/(? 'id', # FreeIPMI ...,0.7.x
@@ -434,7 +550,7 @@
my @exclude_sel_sensor_types;
my $sel_issues_present = 0;
my $simulate = '';
- my ($use_fru, $no_sel, $no_sudo, $use_thresholds, $no_thresholds, $sel_xfile, $s_xfile, $no_entity_absent);
+ my ($use_fru, $no_sel, $sel_only, $sel_tail, $no_sudo, $use_thresholds, $no_thresholds, $sel_xfile, $s_xfile, $s_ufile, $no_entity_absent);
#read in command line arguments and init hash variables with the given values from argv
if ( !( GetOptions(
@@ -451,6 +567,8 @@
'xST|exclude-sel-sensor-types=s' => \@exclude_sel_sensor_types,
'fru' => \$use_fru,
'nosel' => \$no_sel,
+ 'selonly' => \$sel_only,
+ 'seltail=s' => \$sel_tail,
'nosudo' => \$no_sudo,
'nothresholds' => \$no_thresholds,
'noentityabsent' => \$no_entity_absent,
@@ -460,6 +578,7 @@
'x|exclude=s' => \@ipmi_xlist,
'sx|selexclude=s' => \$sel_xfile,
'xx|sexclude=s' => \$s_xfile,
+ 'us|unify-sensors=s'=> \$s_ufile,
'i|include=s' => \@ipmi_ilist,
'o|outformat=s' => \$ipmi_outformat,
'fc|fancount=i' => \$fan_count,
@@ -575,6 +694,7 @@
@frucmd = @basecmd
}
my @selcmd = @basecmd;
+ my @dcmicmd = @basecmd;
if(@ipmi_sensor_types){
# , is the seperator in the new string
@@ -629,12 +749,18 @@
if($use_thresholds && !$no_thresholds){
push @getstatus, '--output-sensor-thresholds';
}
+ if(defined($sel_tail)){
+ push @selcmd, "--tail=$sel_tail";
+ }
################################################################################
#execute status command and redirect stdout and stderr to ipmioutput
my $ipmioutput;
my $returncode;
- if(!$simulate){
+ if ($sel_only){
+ $returncode = 0;
+ }
+ elsif(!$simulate){
run \@getstatus, '>&', \$ipmioutput;
#the upper eight bits contain the error condition (exit code)
#see http://perldoc.perl.org/perlvar.html#Error-Variables
@@ -653,9 +779,11 @@
if(!$no_sel){
$seloutput = parse_sel(\@selcmd, $verbosity, $sel_xfile, \@sel_sensor_types, \@exclude_sel_sensor_types);
}
+ my $dcmioutput;
+ $dcmioutput = parse_dcmi(\@dcmicmd, $verbosity);
################################################################################
# print debug output when verbosity is set to 3 (-vvv)
- if ( $verbosity == 3 ){
+ if ( $verbosity == 3 && !$sel_only ){
my $ipmicommandversion;
run [$IPMICOMMAND, '-V'], '2>&1', '|', ['head', '-n', 1], '&>', \$ipmicommandversion;
#remove trailing newline with chomp
@@ -689,7 +817,7 @@
if(defined($ipmioutput)){
@outputRows = split('\n', $ipmioutput);
}
- if(!defined($ipmioutput) || scalar(@outputRows) == 1){
+ if(!$sel_only && (!defined($ipmioutput) || scalar(@outputRows) == 1)){
print "-> Your server seems to be powered off.";
print " (Execution of FreeIPMI returned an empty output or only 1 header row!)\n";
print "-> $IPMICOMMAND was executed with the following parameters:\n";
@@ -700,129 +828,147 @@
if ( @ipmi_sensor_types ){
print "Sensor Type(s) ", join(', ', @ipmi_sensor_types), " Status: ";
}
+ elsif ($sel_only){
+ print "SEL Status: ";
+ }
else{
print "IPMI Status: ";
}
- #split at newlines, fetch array with lines of output
- my @ipmioutput = split('\n', $ipmioutput);
-
- #remove sudo errors and warnings like they appear on dns resolving issues
- @ipmioutput = map { /^sudo:/ ? () : $_ } @ipmioutput;
-
- #remove leading and trailing whitespace characters, split at the pipe delimiter
- @ipmioutput = map { [ map { s/^\s*//; s/\s*$//; $_; } split(m/\|/, $_) ] } @ipmioutput;
-
- #shift out the header as it is the first line
- my $header = shift @ipmioutput;
- if(!defined($header)){
- print "$ipmioutput\n";
- print " FreeIPMI returned an empty header map (first line)";
- if(@ipmi_sensor_types){
- print " FreeIPMI could not find any sensors for the given sensor type (option '-T').\n";
- }
- exit(3);
- }
- my %header;
- for(my $i = 0; $i < @$header; $i++)
- {
- #assigning %header with (key from hdrmap) => $i
- #checking at which position in the header is which key
- $header{$hdrmap{$header->[$i]}} = $i;
- }
- my @ipmioutput2;
- foreach my $row ( @ipmioutput ){
- my %row;
- #fetch keys from header and assign existent values to row
- #this maps the values from row(ipmioutput) to the header values
- while ( my ($key, $index) = each %header ){
- $row{$key} = $row->[$index];
- }
- if(!(exclude_with_file($s_xfile, $row{'name'}, $row{'type'}))){
- push @ipmioutput2, \%row;
- }
- }
- #create hash with sensor name an 1
- my %ipmi_xlist = map { ($_, 1) } @ipmi_xlist;
- #filter out the desired sensor values
- @ipmioutput2 = grep(!exists $ipmi_xlist{$_->{'id'}}, @ipmioutput2);
- #check for an include list
- if(@ipmi_ilist){
- my %ipmi_ilist = map { ($_, 1) } @ipmi_ilist;
- #only include sensors from include list
- @ipmioutput2 = grep(exists $ipmi_ilist{$_->{'id'}}, @ipmioutput2);
- }
#start with main output
my $exit = 0;
my $w_sensors = '';#sensors with warnings
my $sel_w_sensors = '';#verbose output for sel entries with warnings
my $perf = '';#performance sensor
my $curr_fans = 0;
- foreach my $row ( @ipmioutput2 ){
- if( $zenoss ){
- $row->{'name'} =~ s/ /_/g;
+ my @ipmioutput2;#filtered original ipmi output
+
+ #skip ipmi output, if only SEL queried
+ if (!$sel_only){
+ #split at newlines, fetch array with lines of output
+ my @ipmioutput = split('\n', $ipmioutput);
+
+ #remove sudo errors and warnings like they appear on dns resolving issues
+ @ipmioutput = map { /^sudo:/ ? () : $_ } @ipmioutput;
+
+ #remove leading and trailing whitespace characters, split at the pipe delimiter
+ @ipmioutput = map { [ map { s/^\s*//; s/\s*$//; $_; } split(m/\|/, $_) ] } @ipmioutput;
+
+ #shift out the header as it is the first line
+ my $header = shift @ipmioutput;
+ if(!defined($header)){
+ print "$ipmioutput\n";
+ print " FreeIPMI returned an empty header map (first line)";
+ if(@ipmi_sensor_types){
+ print " FreeIPMI could not find any sensors for the given sensor type (option '-T').\n";
+ }
+ exit(3);
}
- my $check_sensor_state = 1;
- if($no_entity_absent && ($row->{'event'} eq '\'Entity Absent\'')){
- $check_sensor_state = 0;
+ my %header;
+ for(my $i = 0; $i < @$header; $i++)
+ {
+ #assigning %header with (key from hdrmap) => $i
+ #checking at which position in the header is which key
+ $header{$hdrmap{$header->[$i]}} = $i;
}
- #check for warning sensors
- if($check_sensor_state && ($row->{'state'} ne 'Nominal' && $row->{'state'} ne 'N/A')){
- $exit = 1 if $exit < 1;
- $exit = 2 if $exit < 2 && $row->{'state'} ne 'Warning';
- #don't insert a , the first time
- $w_sensors .= ", " unless $w_sensors eq '';
- $w_sensors .= "$row->{'name'} = $row->{'state'}";
- if( $verbosity ){
- if( $row->{'reading'} ne 'N/A'){
- $w_sensors .= " ($row->{'reading'})" ;
+ foreach my $row ( @ipmioutput ){
+ my %row;
+ #fetch keys from header and assign existent values to row
+ #this maps the values from row(ipmioutput) to the header values
+ while ( my ($key, $index) = each %header ){
+ #check if the option to unify sensor names is active
+ if($key eq 'name' && $s_ufile && $s_ufile ne ''){
+ $row{$key} = unify_with_file($s_ufile, $row->[$index]);
}
else{
- $w_sensors .= " ($row->{'event'})";
+ $row{$key} = $row->[$index];
}
}
+ if(!(exclude_with_file($s_xfile, $row{'name'}, $row{'type'}))){
+ push @ipmioutput2, \%row;
+ }
}
- if($check_sensor_state && ($row->{'units'} ne 'N/A')){
- my $val = $row->{'reading'};
- my $perf_data;
- my $perf_thresholds;
- if($zenoss){
- $perf_data = $row->{'name'}."=".$val;
- }
- else{
- $perf_data = "'".$row->{'name'}."'=".$val;
- }
- if($use_thresholds && !$no_thresholds){
- if(($row->{'lowerNC'} ne 'N/A') && ($row->{'upperNC'} ne 'N/A')){
- $perf_thresholds = $row->{'lowerNC'}.":".$row->{'upperNC'}.";";
- }
- elsif(($row->{'lowerNC'} ne 'N/A') && ($row->{'upperNC'} eq 'N/A')){
- $perf_thresholds = $row->{'lowerNC'}.":;";
- }
- elsif(($row->{'lowerNC'} eq 'N/A') && ($row->{'upperNC'} ne 'N/A')){
- $perf_thresholds = "~:".$row->{'upperNC'}.";";
+ #create hash with sensor name an 1
+ my %ipmi_xlist = map { ($_, 1) } @ipmi_xlist;
+ #filter out the desired sensor values
+ @ipmioutput2 = grep(!exists $ipmi_xlist{$_->{'id'}}, @ipmioutput2);
+ #check for an include list
+ if(@ipmi_ilist){
+ my %ipmi_ilist = map { ($_, 1) } @ipmi_ilist;
+ #only include sensors from include list
+ @ipmioutput2 = grep(exists $ipmi_ilist{$_->{'id'}}, @ipmioutput2);
+ }
+ foreach my $row ( @ipmioutput2 ){
+ if( $zenoss ){
+ $row->{'name'} =~ s/ /_/g;
+ }
+ my $check_sensor_state = 1;
+ if($no_entity_absent){
+ if(exists $row->{'event'} && ($row->{'event'} =~ /\'.*((Device|Entity) (Absent|Removed)).*\'/)){
+ $check_sensor_state = 0;
}
- elsif(($row->{'lowerNC'} eq 'N/A') && ($row->{'upperNC'} eq 'N/A')){
- $perf_thresholds = ";";
+ if(exists $row->{'reading'} && ($row->{'reading'} =~ /\'.*((Device|Entity) (Absent|Removed)).*\'/)){
+ $check_sensor_state = 0;
}
- if(($row->{'lowerC'} ne 'N/A') && ($row->{'upperC'} ne 'N/A')){
- $perf_thresholds .= $row->{'lowerC'}.":".$row->{'upperC'};
+ }
+ #check for warning sensors
+ if($check_sensor_state && ($row->{'state'} ne 'Nominal' && $row->{'state'} ne 'N/A')){
+ $exit = 1 if $exit < 1;
+ $exit = 2 if $exit < 2 && $row->{'state'} ne 'Warning';
+ #don't insert a , the first time
+ $w_sensors .= ", " unless $w_sensors eq '';
+ $w_sensors .= "$row->{'name'} = $row->{'state'}";
+ if( $verbosity ){
+ if( $row->{'reading'} ne 'N/A'){
+ $w_sensors .= " ($row->{'reading'})" ;
+ }
+ else{
+ $w_sensors .= " ($row->{'event'})";
+ }
}
- elsif(($row->{'lowerC'} ne 'N/A') && ($row->{'upperC'} eq 'N/A')){
- $perf_thresholds .= $row->{'lowerC'}.":";
+ }
+ if($check_sensor_state && ($row->{'units'} ne 'N/A')){
+ my $val = $row->{'reading'};
+ my $perf_data;
+ my $perf_thresholds;
+ if($zenoss){
+ $perf_data = $row->{'name'}."=".$val;
}
- elsif(($row->{'lowerC'} eq 'N/A') && ($row->{'upperC'} ne 'N/A')){
- $perf_thresholds .= "~:".$row->{'upperC'};
+ else{
+ $perf_data = "'".$row->{'name'}."'=".$val;
}
- # Add thresholds to performance data
- if(($row->{'lowerNC'} ne 'N/A') || ($row->{'upperNC'} ne 'N/A') ||
- ($row->{'lowerC'} ne 'N/A') || ($row->{'upperC'} ne 'N/A')){
- $perf_data .= ";".$perf_thresholds;
+ if($use_thresholds && !$no_thresholds){
+ if(($row->{'lowerNC'} ne 'N/A') && ($row->{'upperNC'} ne 'N/A')){
+ $perf_thresholds = $row->{'lowerNC'}.":".$row->{'upperNC'}.";";
+ }
+ elsif(($row->{'lowerNC'} ne 'N/A') && ($row->{'upperNC'} eq 'N/A')){
+ $perf_thresholds = $row->{'lowerNC'}.":;";
+ }
+ elsif(($row->{'lowerNC'} eq 'N/A') && ($row->{'upperNC'} ne 'N/A')){
+ $perf_thresholds = "~:".$row->{'upperNC'}.";";
+ }
+ elsif(($row->{'lowerNC'} eq 'N/A') && ($row->{'upperNC'} eq 'N/A')){
+ $perf_thresholds = ";";
+ }
+ if(($row->{'lowerC'} ne 'N/A') && ($row->{'upperC'} ne 'N/A')){
+ $perf_thresholds .= $row->{'lowerC'}.":".$row->{'upperC'};
+ }
+ elsif(($row->{'lowerC'} ne 'N/A') && ($row->{'upperC'} eq 'N/A')){
+ $perf_thresholds .= $row->{'lowerC'}.":";
+ }
+ elsif(($row->{'lowerC'} eq 'N/A') && ($row->{'upperC'} ne 'N/A')){
+ $perf_thresholds .= "~:".$row->{'upperC'};
+ }
+ # Add thresholds to performance data
+ if(($row->{'lowerNC'} ne 'N/A') || ($row->{'upperNC'} ne 'N/A') ||
+ ($row->{'lowerC'} ne 'N/A') || ($row->{'upperC'} ne 'N/A')){
+ $perf_data .= ";".$perf_thresholds;
+ }
}
+ $perf .= $perf_data." ";
+ }
+ if( $row->{'type'} eq 'Fan' && $row->{'reading'} ne 'N/A' ){
+ $curr_fans++;
}
- $perf .= $perf_data." ";
- }
- if( $row->{'type'} eq 'Fan' && $row->{'reading'} ne 'N/A' ){
- $curr_fans++;
}
}
foreach my $row (@{$seloutput}){
@@ -876,6 +1022,20 @@
$serial_number = $1;
}
}
+ if(defined($dcmioutput) && $dcmioutput ne ''){
+ my $power_perf = '';
+ if(exists $dcmioutput->{'Current Power'}){
+ my $power_key = 'Current Power';
+ if($s_ufile && $s_ufile ne ''){
+ $power_key = unify_with_file($s_ufile, $power_key);
+ }
+ if( $zenoss ){
+ $power_key =~ s/ /_/g;
+ }
+ $power_perf = "\'$power_key\'=" . $dcmioutput->{'Current Power'};
+ }
+ $perf = $power_perf . ' ' . $perf;
+ }
$perf = substr($perf, 0, -1);#cut off the last chars
if ( $exit == 0 ){
print "OK";
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/control nagios-plugins-contrib-23.20190206/check_ipmi_sensor/control
--- nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/control 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ipmi_sensor/control 2019-02-06 12:45:06.000000000 +0000
@@ -1,5 +1,5 @@
Recommends: freeipmi-tools, libipc-run-perl
-Version: 3.12
+Version: 3.13
Uploaders: Bernd Zeimetz
Homepage: http://www.thomas-krenn.com/en/oss/ipmi-plugin.html
Description: IPMI Sensor Monitoring Plugin
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/README nagios-plugins-contrib-23.20190206/check_ipmi_sensor/README
--- nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/README 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ipmi_sensor/README 1970-01-01 00:00:00.000000000 +0000
@@ -1,45 +0,0 @@
-
- check_ipmi_sensor
- =================
-
- check_ipmi_sensor: Nagios/Icinga plugin to check IPMI sensors
-
- Copyright (C) 2009-2016 Thomas-Krenn.AG,
- additional contributors see changelog.txt
-
- 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 3 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, see .
-
-
- Requirements:
- -------------
- o Nagios or Icinga
- o FreeIPMI version 0.5.1 or newer
- o Perl
- o Perl IPC::Run
-
-
- Installation hints:
- -------------------
- On Debian/Ubuntu use 'apt-get install libipc-run-perl' to install IPC::Run.
- If you are running the plugin locally and not via network, the user 'nagios'
- needs root privileges for calling:
- o ipmimonitoring/ipmi-sensors/ipmi-sel/[ipmi-fru]
- You can achieve that by adding a sudoers config (e.g. for ipmi-sensors)
- o nagios ALL=(root) NOPASSWD: /usr/sbin/ipmi-sensors, /usr/sbin/ipmi-sel
- Please check with '-vvv' which commands are run by the plugin!
-
- Notes on ipmi-sel:
- ------------------
- If you want to clear the ipmi system event log, pleas use:
- o /usr/sbin/ipmi-sel -h $IP -u ADMIN -p $PW -l ADMIN --clear
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/README.md nagios-plugins-contrib-23.20190206/check_ipmi_sensor/README.md
--- nagios-plugins-contrib-22.20181105+1/check_ipmi_sensor/README.md 1970-01-01 00:00:00.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ipmi_sensor/README.md 2019-02-06 12:45:06.000000000 +0000
@@ -0,0 +1,67 @@
+# check_ipmi_sensor - Nagios/Icinga plugin to check IPMI sensors [![License: GPL v3+](https://img.shields.io/badge/License-GPL%20v3%2B-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
+
+## Description
+With this plugin the hardware status of a server can be monitored with Nagios, Icinga or Icinga 2. Specifically, fan speeds, temperatures, voltages, power consumption, power supply performance, etc. can be monitored.
+
+## Requirements
+* Nagios, Icinga or Icinga 2
+* FreeIPMI version 0.5.1 or newer
+* Perl
+* Perl IPC::Run
+
+## Installation hints
+For detailed information, installation instructions and definition examples, please go to:
+
+* [IPMI Sensor Monitoring Plugin](https://www.thomas-krenn.com/en/wiki/IPMI_Sensor_Monitoring_Plugin)
+
+### Destination folder
+Copy this plugin to the following folder:
+
+ /usr/lib/nagios/plugins/check_ipmi_sensor
+
+### Debian/Ubuntu
+Install missing lib:
+
+ apt-get install libipc-run-perl
+
+### CentOS
+Install missing lib:
+
+ yum install perl-IPC-Run freeipmi
+
+### Additional
+If you are running the plugin locally and not via network, the user 'nagios'
+needs root privileges for calling:
+* ipmimonitoring/ipmi-sensors/ipmi-sel/[ipmi-fru]/[ipmi-dcmi]
+
+You can achieve that by adding a sudoers config (e.g. for ipmi-sensors)
+
+ nagios ALL=(root) NOPASSWD: /usr/sbin/ipmi-sensors, /usr/sbin/ipmi-sel, /usr/sbin/ipmi-fru, /usr/sbin/ipmi-dcmi
+
+Please check with '-vvv' which commands are run by the plugin!
+
+## Notes on ipmi-sel
+If you want to clear the ipmi system event log, please use ipmi-sel.
+
+### Remote machine
+ /usr/sbin/ipmi-sel -h $IP -u ADMIN -p $PW -l ADMIN --clear
+
+### Local machine
+ /usr/sbin/ipmi-sel --clear
+
+## License
+Copyright (C) 2009-2019 [Thomas-Krenn.AG](https://www.thomas-krenn.com/en/index.html),
+additional contributors see changelog.txt
+
+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 3 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, see .
diff -Nru nagios-plugins-contrib-22.20181105+1/check_mongodb/check_mongodb.py nagios-plugins-contrib-23.20190206/check_mongodb/check_mongodb.py
--- nagios-plugins-contrib-22.20181105+1/check_mongodb/check_mongodb.py 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_mongodb/check_mongodb.py 2019-02-06 12:45:06.000000000 +0000
@@ -26,17 +26,19 @@
# See the README.md
#
+from __future__ import print_function
+from __future__ import division
import sys
import time
import optparse
-import textwrap
import re
import os
+import numbers
try:
import pymongo
-except ImportError, e:
- print e
+except ImportError as e:
+ print(e)
sys.exit(2)
# As of pymongo v 1.9 the SON API is part of the BSON package, therefore attempt
@@ -80,37 +82,35 @@
def numeric_type(param):
- if ((type(param) == float or type(param) == int or type(param) == long or param == None)):
- return True
- return False
+ return param is None or isinstance(param, numbers.Real)
def check_levels(param, warning, critical, message, ok=[]):
if (numeric_type(critical) and numeric_type(warning)):
if param >= critical:
- print "CRITICAL - " + message
+ print("CRITICAL - " + message)
sys.exit(2)
elif param >= warning:
- print "WARNING - " + message
+ print("WARNING - " + message)
sys.exit(1)
else:
- print "OK - " + message
+ print("OK - " + message)
sys.exit(0)
else:
if param in critical:
- print "CRITICAL - " + message
+ print("CRITICAL - " + message)
sys.exit(2)
if param in warning:
- print "WARNING - " + message
+ print("WARNING - " + message)
sys.exit(1)
if param in ok:
- print "OK - " + message
+ print("OK - " + message)
sys.exit(0)
# unexpected param value
- print "CRITICAL - Unexpected value : %d" % param + "; " + message
+ print("CRITICAL - Unexpected value : %d" % param + "; " + message)
return 2
@@ -155,6 +155,8 @@
p.add_option('--insecure', action='store_true', dest='insecure', default=False, help="Don't verify SSL/TLS certificates")
p.add_option('--ssl-ca-cert-file', action='store', type='string', dest='ssl_ca_cert_file', default=None, help='Path to Certificate Authority file for SSL')
p.add_option('-f', '--ssl-cert-file', action='store', type='string', dest='cert_file', default=None, help='Path to PEM encoded key and cert for client authentication')
+ p.add_option('-m','--auth-mechanism', action='store', type='choice', dest='auth_mechanism', default=None, help='Auth mechanism used for auth with mongodb',
+ choices=['MONGODB-X509','SCRAM-SHA-256','SCRAM-SHA-1'])
options, arguments = p.parse_args()
host = options.host
@@ -185,6 +187,7 @@
insecure = options.insecure
ssl_ca_cert_file = options.ssl_ca_cert_file
cert_file = options.cert_file
+ auth_mechanism = options.auth_mechanism
if action == 'replica_primary' and replicaset is None:
return "replicaset must be passed in when using replica_primary check"
@@ -206,7 +209,6 @@
return err
conn_time = time.time() - start
- conn_time = round(conn_time, 0)
if action == "connections":
return check_connections(con, warning, critical, perf_data)
@@ -283,7 +285,7 @@
return check_connect(host, port, warning, critical, perf_data, user, passwd, conn_time)
-def mongo_connect(host=None, port=None, ssl=False, user=None, passwd=None, replica=None, authdb="admin", insecure=False, ssl_ca_cert_file=None, ssl_cert=None):
+def mongo_connect(host=None, port=None, ssl=False, user=None, passwd=None, replica=None, authdb="admin", insecure=False, ssl_ca_cert_file=None, ssl_cert=None, auth_mechanism=None):
from pymongo.errors import ConnectionFailure
from pymongo.errors import PyMongoError
import ssl as SSL
@@ -314,6 +316,14 @@
else:
con = pymongo.Connection(host, port, slave_okay=True, network_timeout=10)
+ # we must authenticate the connection, otherwise we won't be able to perform certain operations
+ if ssl_cert and ssl_ca_cert_file and user and auth_mechanism == 'SCRAM-SHA-256':
+ con.the_database.authenticate(user, mechanism='SCRAM-SHA-256')
+ elif ssl_cert and ssl_ca_cert_file and user and auth_mechanism == 'SCRAM-SHA-1':
+ con.the_database.authenticate(user, mechanism='SCRAM-SHA-1')
+ elif ssl_cert and ssl_ca_cert_file and user and auth_mechanism == 'MONGODB-X509':
+ con.the_database.authenticate(user, mechanism='MONGODB-X509')
+
try:
result = con.admin.command("ismaster")
except ConnectionFailure:
@@ -321,7 +331,7 @@
sys.exit(2)
if 'arbiterOnly' in result and result['arbiterOnly'] == True:
- print "OK - State: 7 (Arbiter on port %s)" % (port)
+ print("OK - State: 7 (Arbiter on port %s)" % (port))
sys.exit(0)
if user and passwd:
@@ -334,11 +344,11 @@
# Ping to check that the server is responding.
con.admin.command("ping")
- except Exception, e:
+ except Exception as e:
if isinstance(e, pymongo.errors.AutoReconnect) and str(e).find(" is an arbiter") != -1:
# We got a pymongo AutoReconnect exception that tells us we connected to an Arbiter Server
# This means: Arbiter is reachable and can answer requests/votes - this is all we need to know from an arbiter
- print "OK - State: 7 (Arbiter)"
+ print("OK - State: 7 (Arbiter)")
sys.exit(0)
return exit_with_general_critical(e), None
return 0, con
@@ -348,7 +358,7 @@
if isinstance(e, SystemExit):
return e
else:
- print "WARNING - General MongoDB warning:", e
+ print("WARNING - General MongoDB warning:", e)
return 1
@@ -356,7 +366,7 @@
if isinstance(e, SystemExit):
return e
else:
- print "CRITICAL - General MongoDB Error:", e
+ print("CRITICAL - General MongoDB Error:", e)
return 2
@@ -369,14 +379,14 @@
def check_version(con):
try:
server_info = con.server_info()
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e), None
return 0, int(server_info['version'].split('.')[0].strip())
def check_connect(host, port, warning, critical, perf_data, user, passwd, conn_time):
warning = warning or 3
critical = critical or 6
- message = "Connection took %i seconds" % conn_time
+ message = "Connection took %.3f seconds" % conn_time
message += performance_data(perf_data, [(conn_time, "connection_time", warning, critical)])
return check_levels(conn_time, warning, critical, message)
@@ -398,15 +408,15 @@
(available, "available_connections")])
return check_levels(used_percent, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
def check_rep_lag(con, host, port, warning, critical, percent, perf_data, max_lag, user, passwd, ssl=None, insecure=None, ssl_ca_cert_file=None, cert_file=None):
# Get mongo to tell us replica set member name when connecting locally
if "127.0.0.1" == host:
- if not "me" in con.admin.command("ismaster","1").keys():
- print "UNKNOWN - This is not replicated MongoDB"
+ if not "me" in list(con.admin.command("ismaster","1").keys()):
+ print("UNKNOWN - This is not replicated MongoDB")
return 3
host = con.admin.command("ismaster","1")["me"].split(':')[0]
@@ -425,9 +435,9 @@
# Get replica set status
try:
rs_status = con.admin.command("replSetGetStatus")
- except pymongo.errors.OperationFailure, e:
+ except pymongo.errors.OperationFailure as e:
if ((e.code == None and str(e).find('failed: not running with --replSet"')) or (e.code == 76 and str(e).find('not running with --replSet"'))):
- print "UNKNOWN - Not running with replSet"
+ print("UNKNOWN - Not running with replSet")
return 3
serverVersion = tuple(con.server_info()['version'].split('.'))
@@ -454,19 +464,19 @@
# Check if we're in the middle of an election and don't have a primary
if primary_node is None:
- print "WARNING - No primary defined. In an election?"
+ print("WARNING - No primary defined. In an election?")
return 1
# Check if we failed to find the current host
# below should never happen
if host_node is None:
- print "CRITICAL - Unable to find host '" + host + "' in replica set."
+ print("CRITICAL - Unable to find host '" + host + "' in replica set.")
return 2
# Is the specified host the primary?
if host_node["stateStr"] == "PRIMARY":
if max_lag == False:
- print "OK - This is the primary."
+ print("OK - This is the primary.")
return 0
else:
#get the maximal replication lag
@@ -491,7 +501,7 @@
message += performance_data(perf_data, [(maximal_lag, "replication_lag", warning, critical)])
return check_levels(maximal_lag, warning, critical, message)
elif host_node["stateStr"] == "ARBITER":
- print "UNKNOWN - This is an arbiter"
+ print("UNKNOWN - This is an arbiter")
return 3
# Find the difference in optime between current node and PRIMARY
@@ -543,12 +553,12 @@
# Check if we're in the middle of an election and don't have a primary
if primary_node is None:
- print "WARNING - No primary defined. In an election?"
+ print("WARNING - No primary defined. In an election?")
sys.exit(1)
# Is the specified host the primary?
if host_node["stateStr"] == "PRIMARY":
- print "OK - This is the primary."
+ print("OK - This is the primary.")
sys.exit(0)
# Find the difference in optime between current node and PRIMARY
@@ -567,7 +577,7 @@
message += performance_data(perf_data, [(lag, "replication_lag", warning, critical)])
return check_levels(lag, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
#
@@ -602,7 +612,7 @@
try:
data = get_server_status(con)
if not data['mem']['supported'] and not mapped_memory:
- print "OK - Platform not supported for memory info"
+ print("OK - Platform not supported for memory info")
return 0
#
# convert to gigs
@@ -639,7 +649,7 @@
else:
return check_levels(mem_resident, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -652,7 +662,7 @@
try:
data = get_server_status(con)
if not data['mem']['supported']:
- print "OK - Platform not supported for memory info"
+ print("OK - Platform not supported for memory info")
return 0
#
# convert to gigs
@@ -674,10 +684,10 @@
if not mem_mapped == -1:
return check_levels(mem_mapped, warning, critical, message)
else:
- print "OK - Server does not provide mem.mapped info"
+ print("OK - Server does not provide mem.mapped info")
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -702,11 +712,11 @@
message = "Lock Percentage: %.2f%%" % lock_percentage
message += performance_data(perf_data, [("%.2f" % lock_percentage, "lock_percentage", warning, critical)])
return check_levels(lock_percentage, warning, critical, message)
- except Exception, e:
- print "Couldn't get globalLock lockTime info from mongo, are you sure you're not using version 3? See the -M option."
+ except Exception as e:
+ print("Couldn't get globalLock lockTime info from mongo, are you sure you're not using version 3? See the -M option.")
return exit_with_general_critical(e)
else:
- print "OK - MongoDB version 3 doesn't report on global locks"
+ print("OK - MongoDB version 3 doesn't report on global locks")
return 0
@@ -733,10 +743,10 @@
return check_levels(flush_time, warning, critical, message)
except Exception:
- print "OK - flushing stats not available for this storage engine"
+ print("OK - flushing stats not available for this storage engine")
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -757,14 +767,14 @@
not_supported_msg = "not supported on this platform"
try:
data['indexCounters']
- if data['indexCounters'].has_key('note'):
- print "OK - MongoDB says: " + not_supported_msg
+ if 'note' in data['indexCounters']:
+ print("OK - MongoDB says: " + not_supported_msg)
return 0
else:
- print "WARNING - Can't get counter from MongoDB"
+ print("WARNING - Can't get counter from MongoDB")
return 1
except Exception:
- print "OK - MongoDB says: " + not_supported_msg
+ print("OK - MongoDB says: " + not_supported_msg)
return 0
message = "Miss Ratio: %.2f" % miss_ratio
@@ -772,7 +782,7 @@
return check_levels(miss_ratio, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
def check_replset_quorum(con, perf_data):
@@ -796,7 +806,7 @@
message = "Cluster is not quorate and cannot operate"
return check_levels(state, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -811,7 +821,7 @@
except:
critical = [8, 4, -1]
- ok = range(-1, 8) # should include the range of all posiible values
+ ok = list(range(-1, 8)) # should include the range of all posiible values
try:
worst_state = -2
message = ""
@@ -821,22 +831,22 @@
data = con.admin.command(pymongo.son_manipulator.SON([('replSetGetStatus', 1)]))
except:
data = con.admin.command(son.SON([('replSetGetStatus', 1)]))
- members = data['members'];
+ members = data['members']
my_state = int(data['myState'])
worst_state = my_state
for member in members:
their_state = int(member['state'])
message += " %s: %i (%s)" % (member['name'], their_state, state_text(their_state))
if state_is_worse(their_state, worst_state, warning, critical):
- worst_state = their_state;
+ worst_state = their_state
message += performance_data(perf_data, [(my_state, "state")])
- except pymongo.errors.OperationFailure, e:
+ except pymongo.errors.OperationFailure as e:
if ((e.code == None and str(e).find('failed: not running with --replSet"')) or (e.code == 76 and str(e).find('not running with --replSet"'))):
worst_state = -1
return check_levels(worst_state, warning, critical, message, ok)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
def state_is_worse(state, worst_state, warning, critical):
@@ -881,7 +891,7 @@
message = "Number of DBs: %.0f" % count
message += performance_data(perf_data, [(count, "databases", warning, critical, message)])
return check_levels(count, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -903,7 +913,7 @@
message += performance_data(perf_data, [(count, "collections", warning, critical, message)])
return check_levels(count, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -940,21 +950,21 @@
try:
set_read_preference(con.admin)
data = con[database].command('dbstats')
- storage_size = data['storageSize'] / 1024 / 1024
+ storage_size = data['storageSize'] // 1024 // 1024
if perf_data:
perfdata += " | database_size=%i;%i;%i" % (storage_size, warning, critical)
#perfdata += " database=%s" %(database)
if storage_size >= critical:
- print "CRITICAL - Database size: %.0f MB, Database: %s%s" % (storage_size, database, perfdata)
+ print("CRITICAL - Database size: %.0f MB, Database: %s%s" % (storage_size, database, perfdata))
return 2
elif storage_size >= warning:
- print "WARNING - Database size: %.0f MB, Database: %s%s" % (storage_size, database, perfdata)
+ print("WARNING - Database size: %.0f MB, Database: %s%s" % (storage_size, database, perfdata))
return 1
else:
- print "OK - Database size: %.0f MB, Database: %s%s" % (storage_size, database, perfdata)
+ print("OK - Database size: %.0f MB, Database: %s%s" % (storage_size, database, perfdata))
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -968,20 +978,20 @@
try:
set_read_preference(con.admin)
data = con[database].command('dbstats')
- index_size = data['indexSize'] / 1024 / 1024
+ index_size = data['indexSize'] / 1024 // 1024
if perf_data:
perfdata += " | database_indexes=%i;%i;%i" % (index_size, warning, critical)
if index_size >= critical:
- print "CRITICAL - %s indexSize: %.0f MB %s" % (database, index_size, perfdata)
+ print("CRITICAL - %s indexSize: %.0f MB %s" % (database, index_size, perfdata))
return 2
elif index_size >= warning:
- print "WARNING - %s indexSize: %.0f MB %s" % (database, index_size, perfdata)
+ print("WARNING - %s indexSize: %.0f MB %s" % (database, index_size, perfdata))
return 1
else:
- print "OK - %s indexSize: %.0f MB %s" % (database, index_size, perfdata)
+ print("OK - %s indexSize: %.0f MB %s" % (database, index_size, perfdata))
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -995,15 +1005,15 @@
perfdata += " | collection_documents=%i;%i;%i" % (documents, warning, critical)
if documents >= critical:
- print "CRITICAL - %s.%s documents: %s %s" % (database, collection, documents, perfdata)
+ print("CRITICAL - %s.%s documents: %s %s" % (database, collection, documents, perfdata))
return 2
elif documents >= warning:
- print "WARNING - %s.%s documents: %s %s" % (database, collection, documents, perfdata)
+ print("WARNING - %s.%s documents: %s %s" % (database, collection, documents, perfdata))
return 1
else:
- print "OK - %s.%s documents: %s %s" % (database, collection, documents, perfdata)
+ print("OK - %s.%s documents: %s %s" % (database, collection, documents, perfdata))
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1022,15 +1032,15 @@
perfdata += " | collection_indexes=%i;%i;%i" % (total_index_size, warning, critical)
if total_index_size >= critical:
- print "CRITICAL - %s.%s totalIndexSize: %.0f MB %s" % (database, collection, total_index_size, perfdata)
+ print("CRITICAL - %s.%s totalIndexSize: %.0f MB %s" % (database, collection, total_index_size, perfdata))
return 2
elif total_index_size >= warning:
- print "WARNING - %s.%s totalIndexSize: %.0f MB %s" % (database, collection, total_index_size, perfdata)
+ print("WARNING - %s.%s totalIndexSize: %.0f MB %s" % (database, collection, total_index_size, perfdata))
return 1
else:
- print "OK - %s.%s totalIndexSize: %.0f MB %s" % (database, collection, total_index_size, perfdata)
+ print("OK - %s.%s totalIndexSize: %.0f MB %s" % (database, collection, total_index_size, perfdata))
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1047,7 +1057,7 @@
message += performance_data(perf_data, [(total_queues, "total_queues", warning, critical), (readers_queues, "readers_queues"), (writers_queues, "writers_queues")])
return check_levels(total_queues, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
def check_collection_size(con, database, collection, warning, critical, perf_data):
@@ -1062,15 +1072,15 @@
perfdata += " | collection_size=%i;%i;%i" % (size, warning, critical)
if size >= critical:
- print "CRITICAL - %s.%s size: %.0f MB %s" % (database, collection, size, perfdata)
+ print("CRITICAL - %s.%s size: %.0f MB %s" % (database, collection, size, perfdata))
return 2
elif size >= warning:
- print "WARNING - %s.%s size: %.0f MB %s" % (database, collection, size, perfdata)
+ print("WARNING - %s.%s size: %.0f MB %s" % (database, collection, size, perfdata))
return 1
else:
- print "OK - %s.%s size: %.0f MB %s" % (database, collection, size, perfdata)
+ print("OK - %s.%s size: %.0f MB %s" % (database, collection, size, perfdata))
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1086,15 +1096,15 @@
perfdata += " | collection_storageSize=%i;%i;%i" % (storageSize, warning, critical)
if storageSize >= critical:
- print "CRITICAL - %s.%s storageSize: %.0f MB %s" % (database, collection, storageSize, perfdata)
+ print("CRITICAL - %s.%s storageSize: %.0f MB %s" % (database, collection, storageSize, perfdata))
return 2
elif storageSize >= warning:
- print "WARNING - %s.%s storageSize: %.0f MB %s" % (database, collection, storageSize, perfdata)
+ print("WARNING - %s.%s storageSize: %.0f MB %s" % (database, collection, storageSize, perfdata))
return 1
else:
- print "OK - %s.%s storageSize: %.0f MB %s" % (database, collection, storageSize, perfdata)
+ print("OK - %s.%s storageSize: %.0f MB %s" % (database, collection, storageSize, perfdata))
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1155,7 +1165,7 @@
return check_levels(query_per_sec, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1202,7 +1212,7 @@
message += performance_data(perf_data, [("%.2f" % hours_in_oplog, 'oplog_time', warning, critical), ("%.2f " % approx_level, 'oplog_time_100_percent_used')])
return check_levels(-approx_level, -warning, -critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1220,7 +1230,7 @@
message += performance_data(perf_data, [(j_commits_in_wl, "j_commits_in_wl", warning, critical)])
return check_levels(j_commits_in_wl, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1236,7 +1246,7 @@
message += performance_data(perf_data, [("%.2f" % journaled, "journaled", warning, critical)])
return check_levels(journaled, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1253,7 +1263,7 @@
message += performance_data(perf_data, [("%.2f" % writes, "write_to_data_files", warning, critical)])
return check_levels(writes, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1265,7 +1275,7 @@
delete = data[opcounters_name]['delete']
getmore = data[opcounters_name]['getmore']
command = data[opcounters_name]['command']
- except KeyError, e:
+ except KeyError as e:
return 0, [0] * 100
total_commands = insert + query + update + delete + getmore + command
new_vals = [total_commands, insert, query, update, delete, getmore, command]
@@ -1432,9 +1442,9 @@
try:
#on linux servers only
- page_faults = (int(data2['extra_info']['page_faults']) - int(data1['extra_info']['page_faults'])) / sample_time
+ page_faults = (int(data2['extra_info']['page_faults']) - int(data1['extra_info']['page_faults'])) // sample_time
except KeyError:
- print "WARNING - Can't get extra_info.page_faults counter from MongoDB"
+ print("WARNING - Can't get extra_info.page_faults counter from MongoDB")
sys.exit(1)
message = "Page Faults: %i" % (page_faults)
@@ -1442,7 +1452,7 @@
message += performance_data(perf_data, [(page_faults, "page_faults", warning, critical)])
check_levels(page_faults, warning, critical, message)
- except Exception, e:
+ except Exception as e:
exit_with_general_critical(e)
@@ -1458,35 +1468,35 @@
shards = col.distinct("shard")
except:
- print "WARNING - Can't get chunks infos from MongoDB"
+ print("WARNING - Can't get chunks infos from MongoDB")
sys.exit(1)
if nscount == 0:
- print "WARNING - Namespace %s is not sharded" % (nsfilter)
+ print("WARNING - Namespace %s is not sharded" % (nsfilter))
sys.exit(1)
- avgchunksnb = nscount / len(shards)
- warningnb = avgchunksnb * warning / 100
- criticalnb = avgchunksnb * critical / 100
+ avgchunksnb = nscount // len(shards)
+ warningnb = avgchunksnb * warning // 100
+ criticalnb = avgchunksnb * critical // 100
for shard in shards:
delta = abs(avgchunksnb - col.find({"ns": nsfilter, "shard": shard}).count())
message = "Namespace: %s, Shard name: %s, Chunk delta: %i" % (nsfilter, shard, delta)
if delta >= criticalnb and delta > 0:
- print "CRITICAL - Chunks not well balanced " + message
+ print("CRITICAL - Chunks not well balanced " + message)
sys.exit(2)
elif delta >= warningnb and delta > 0:
- print "WARNING - Chunks not well balanced " + message
+ print("WARNING - Chunks not well balanced " + message)
sys.exit(1)
- print "OK - Chunks well balanced across shards"
+ print("OK - Chunks well balanced across shards")
sys.exit(0)
- except Exception, e:
+ except Exception as e:
exit_with_general_critical(e)
- print "OK - Chunks well balanced across shards"
+ print("OK - Chunks well balanced across shards")
sys.exit(0)
@@ -1502,7 +1512,7 @@
data = con.admin.command(son.SON([('isMaster', 1)]))
if data['ismaster'] == True:
- print "OK - This server is primary"
+ print("OK - This server is primary")
return 0
phost = data['primary'].split(':')[0]
@@ -1520,17 +1530,17 @@
return check_levels(pconn_time, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
def check_collection_state(con, database, collection):
try:
con[database][collection].find_one()
- print "OK - Collection %s.%s is reachable " % (database, collection)
+ print("OK - Collection %s.%s is reachable " % (database, collection))
return 0
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1542,7 +1552,7 @@
return check_levels(count, warning, critical, message)
- except Exception, e:
+ except Exception as e:
return exit_with_general_critical(e)
@@ -1566,7 +1576,7 @@
f = None
try:
f = open(file_name, 'w')
- except IOError, e:
+ except IOError as e:
#try creating
if (e.errno == 2):
ensure_dir(file_name)
@@ -1585,11 +1595,11 @@
data = f.read()
f.close()
return 0, data
- except IOError, e:
+ except IOError as e:
if (e.errno == 2):
#no previous data
return 1, ''
- except Exception, e:
+ except Exception as e:
return 2, None
@@ -1627,8 +1637,8 @@
col = 'oplog.$main'
firstc = local[col].find().sort("$natural", 1).limit(1)
lastc = local[col].find().sort("$natural", -1).limit(1)
- first = firstc.next()
- last = lastc.next()
+ first = next(firstc)
+ last = next(lastc)
tfirst = first["ts"]
tlast = last["ts"]
delta = tlast.time - tfirst.time
diff -Nru nagios-plugins-contrib-22.20181105+1/check_mongodb/control nagios-plugins-contrib-23.20190206/check_mongodb/control
--- nagios-plugins-contrib-22.20181105+1/check_mongodb/control 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_mongodb/control 2019-02-06 12:45:06.000000000 +0000
@@ -1,6 +1,6 @@
Uploaders: Jan Wagner
Recommends: python-pymongo
-Version: 3805751
+Version: b33e763
Homepage: https://github.com/mzupan/nagios-plugin-mongodb
Watch: https://github.com/mzupan/nagios-plugin-mongodb ]*>\s+([0-9a-f]+)\s+
Description: Plugin script to monitor your MongoDB server(s)
diff -Nru nagios-plugins-contrib-22.20181105+1/check_raid/check_raid nagios-plugins-contrib-23.20190206/check_raid/check_raid
--- nagios-plugins-contrib-22.20181105+1/check_raid/check_raid 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_raid/check_raid 2019-02-06 12:45:06.000000000 +0000
@@ -380,6 +380,25 @@
use constant G => M * 1024;
use constant T => G * 1024;
+ sub parse_bytes {
+ my ($this, $size) = @_;
+
+ if ($size =~ s/\sT//) {
+ return int($size) * T;
+ }
+ if ($size =~ s/\sG//) {
+ return int($size) * G;
+ }
+ if ($size =~ s/\sM//) {
+ return int($size) * M;
+ }
+ if ($size =~ s/\sK//) {
+ return int($size) * K;
+ }
+
+ return int($size);
+ }
+
sub format_bytes {
my $this = shift;
@@ -2858,7 +2877,7 @@
$fatpacked{"App/Monitoring/Plugin/CheckRaid/Plugins/hpacucli.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_MONITORING_PLUGIN_CHECKRAID_PLUGINS_HPACUCLI';
package App::Monitoring::Plugin::CheckRaid::Plugins::hpacucli;
- ## hpacucli/hpssacli support
+ ## hpacucli/hpssacli/ssacli support
#
# driver developers recommend to use cciss_vol_status for monitoring,
# hpacucli/hpssacli shouldn't be used for monitoring due they obtaining global
@@ -3030,7 +3049,7 @@
# "array A"
# "array A (Failed)"
# "array B (Failed)"
- if (my($a, $s) = /^\s+array (\S+)(?:\s*\((\S+)\))?$/) {
+ if (my($a, $s) = /^\s+array (\S+)(?:\s*\((\S+)\))?$/i) {
$index++;
# Offset 0 is Array own status
# XXX: I don't like this one: undef could be false positive
@@ -3653,6 +3672,11 @@
my (@status);
my @md = $this->parse;
+ my @spare_options = ();
+
+ @spare_options = split(/\,/, $this->{options}{mdstat_spare_count})
+ if (exists $this->{options}{mdstat_spare_count});
+
foreach (@md) {
my %md = %$_;
@@ -3663,6 +3687,26 @@
# failed disks
my @fd = map { $_->{dev} } grep { $_->{flags} =~ /F/ } @{$md{disks}};
+ # spare disks
+ my @sd = map { $_->{dev} } grep { $_->{flags} =~ /S/ } @{$md{disks}};
+
+ my $spare_count = 0;
+ OPTION_LOOP:
+ {
+ foreach my $i (0 .. $#spare_options)
+ {
+ my ($disk, $value) = split(/:/, $spare_options[$i]);
+ for(@md)
+ {
+ if ($md{dev} eq $disk)
+ {
+ $spare_count = $value;
+ splice(@spare_options, $i, 1);
+ last OPTION_LOOP;
+ }
+ }
+ }
+ }
# raid0 is just there or its not. raid0 can't degrade.
# same for linear, no $md_status available
@@ -3686,12 +3730,27 @@
# FIXME: this is same as above?
$this->warning;
$s .= "hot-spare failure:". join(",", @fd) .":$md{status}";
+ } elsif (@sd < $spare_count)
+ {
+ $this->warning;
+ $s .= "Array ".$md{dev}." should have ".$spare_count." spares, but has only ".(0+@sd)." spares";
} else {
$s .= "$md{status}";
}
push(@status, $s);
}
+ if (scalar @spare_options > 0)
+ {
+ $this->critical;
+ foreach (@spare_options)
+ {
+ my ($disk, $value) = split(/:/, $_);
+ my $s = "$disk is defined in spare_count option but could not be found!";
+ push(@status, $s);
+ }
+ }
+
return unless @status;
# denote this plugin as ran ok
@@ -4475,21 +4534,24 @@
return defined($id);
}
- # get controller from mpt-status -p
- # FIXME: could there be multiple controllers?
sub get_controller {
my $this = shift;
+
+ # controller ID may be given on the command line
+ my $id = $this->{options}{'mpt-id'};
+ if (!$id) {
- my $fh = $this->cmd('get_controller_no');
- my $id;
- while (<$fh>) {
- chomp;
- if (/^Found.*id=(\d{1,2}),.*/) {
- $id = $1;
- last;
+ # get controller from mpt-status -p
+ my $fh = $this->cmd('get_controller_no');
+ while (<$fh>) {
+ chomp;
+ if (/^Found.*id=(\d{1,2}),.*/) {
+ $id = $1;
+ last;
+ }
}
+ close $fh;
}
- close $fh;
return $id;
}
@@ -4661,8 +4723,9 @@
sub commands {
{
- 'mvcli blk' => ['-|', '@CMD'],
- 'mvcli smart' => ['-|', '@CMD'],
+ 'mvcli blk' => ['-|', '@CMD', 'info', '-o', 'blk'],
+ 'mvcli vd' => ['-|', '@CMD', 'info', '-o', 'vd'],
+ 'mvcli smart' => ['-|', '@CMD', 'smart', '-p', '0'],
}
}
@@ -4714,6 +4777,48 @@
return wantarray ? @blk : \@blk;
}
+ sub parse_vd {
+ my $this = shift;
+
+ my (@vd, %vd);
+ my ($name, $value);
+
+ my $fh = $this->cmd('mvcli vd');
+ while (<$fh>) {
+ chomp;
+
+ if (/^$/
+ || /----+/
+ || /SG driver version/
+ || /Virtual Disk Information/
+ ) {
+ next;
+ }
+
+ unless (($name, $value) = /^(.+):\s+(.+)$/) {
+ warn "UNPARSED: [$_]";
+ next;
+ }
+
+ if ($name eq 'id') {
+ # id is first item, so push previous item to list
+ if (%vd) {
+ push(@vd, { %vd });
+ %vd = ();
+ }
+ }
+
+ $vd{$name} = $value;
+ }
+ close $fh;
+
+ if (%vd) {
+ push(@vd, { %vd });
+ }
+
+ return wantarray ? @vd : \@vd;
+ }
+
sub parse_smart {
my ($this, $blk) = @_;
@@ -4727,13 +4832,14 @@
while (<$fh>) {
chomp;
- if (my($id, $name, $current, $worst, $treshold, $raw) = /
- ([\dA-F]{2})\s+ # attr
+ if (my($id, $name, $current, $worst, $treshold, $raw, $status) = /
+ ([\dA-F]{2})\s+ # id
(.*?)\s+ # name
(\d+)\s+ # current
(\d+)\s+ # worst
(\d+)\s+ # treshold
- ([\dA-F]+) # raw
+ ([\dA-F]{12}) # raw
+ (?:\s+(\w+))? # status
/x) {
my %attr = ();
$attr{id} = $id;
@@ -4742,6 +4848,7 @@
$attr{worst} = int($worst);
$attr{treshold} = int($treshold);
$attr{raw} = $raw;
+ $attr{status} = $status || undef;
$attrs{$id} = { %attr };
} else {
# warn "[$_]\n";
@@ -4758,10 +4865,12 @@
my $this = shift;
my $blk = $this->parse_blk;
+ my $vd = $this->parse_vd;
my $smart = $this->parse_smart($blk);
return {
blk => $blk,
+ vd => $vd,
smart => $smart,
};
}
@@ -4769,11 +4878,21 @@
sub check {
my $this = shift;
- my (@status);
- my @d = $this->parse;
+ my @status;
+ my $c = $this->parse;
- # not implemented yet
- $this->unknown;
+ foreach my $vd (@{$c->{vd}}) {
+ my $size = $this->format_bytes($this->parse_bytes($vd->{size}));
+ if ($vd->{status} ne 'functional') {
+ $this->critical;
+ }
+ push(@status, "VD($vd->{name} $vd->{'RAID mode'} $size): $vd->{status}");
+ }
+
+ return unless @status;
+
+ # denote this plugin as ran ok
+ $this->ok;
$this->message(join('; ', @status));
}
@@ -5137,6 +5256,19 @@
1;
APP_MONITORING_PLUGIN_CHECKRAID_PLUGINS_SMARTCTL
+$fatpacked{"App/Monitoring/Plugin/CheckRaid/Plugins/ssacli.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_MONITORING_PLUGIN_CHECKRAID_PLUGINS_SSACLI';
+ package App::Monitoring::Plugin::CheckRaid::Plugins::ssacli;
+
+ # This plugin extends hpacucli plugin,
+ # with the only difference that different program name will be used.
+
+ use base 'App::Monitoring::Plugin::CheckRaid::Plugins::hpacucli';
+ use strict;
+ use warnings;
+
+ 1;
+APP_MONITORING_PLUGIN_CHECKRAID_PLUGINS_SSACLI
+
$fatpacked{"App/Monitoring/Plugin/CheckRaid/Plugins/tw_cli.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_MONITORING_PLUGIN_CHECKRAID_PLUGINS_TW_CLI';
package App::Monitoring::Plugin::CheckRaid::Plugins::tw_cli;
@@ -5863,7 +5995,7 @@
# setup alias, so we could easily remove these later by matching lines with 'CHECK_RAID'
# also this avoids installing ourselves twice.
"# Lines matching CHECK_RAID added by $0 -S on ". scalar localtime,
- "User_Alias CHECK_RAID=nagios, icinga",
+ "User_Alias CHECK_RAID=nagios, icinga, sensu",
"Defaults:CHECK_RAID !requiretty",
# actual rules from plugins
@@ -6056,15 +6188,59 @@
APP_MONITORING_PLUGIN_CHECKRAID_UTILS
$fatpacked{"Class/Accessor.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CLASS_ACCESSOR';
- package Class::Accessor;require 5.00502;use strict;$Class::Accessor::VERSION='0.34';sub new {my($proto,$fields)=@_;my($class)=ref$proto || $proto;$fields={}unless defined$fields;bless {%$fields},$class}sub mk_accessors {my($self,@fields)=@_;$self->_mk_accessors('rw',@fields)}if (eval {require Sub::Name}){Sub::Name->import}{no strict 'refs';sub import {my ($class,@what)=@_;my$caller=caller;for (@what){if (/^(?:antlers|moose-?like)$/i){*{"${caller}::has"}=sub {my ($f,%args)=@_;$caller->_mk_accessors(($args{is}||"rw"),$f)};*{"${caller}::extends"}=sub {@{"${caller}::ISA"}=@_;unless (grep $_->can("_mk_accessors"),@_){push @{"${caller}::ISA"},$class}};&{"${caller}::extends"}(@{"${caller}::ISA"})}}}sub follow_best_practice {my($self)=@_;my$class=ref$self || $self;*{"${class}::accessor_name_for"}=\&best_practice_accessor_name_for;*{"${class}::mutator_name_for"}=\&best_practice_mutator_name_for}sub _mk_accessors {my($self,$access,@fields)=@_;my$class=ref$self || $self;my$ra=$access eq 'rw' || $access eq 'ro';my$wa=$access eq 'rw' || $access eq 'wo';for my$field (@fields){my$accessor_name=$self->accessor_name_for($field);my$mutator_name=$self->mutator_name_for($field);if($accessor_name eq 'DESTROY' or $mutator_name eq 'DESTROY'){$self->_carp("Having a data accessor named DESTROY in '$class' is unwise.")}if ($accessor_name eq $mutator_name){my$accessor;if ($ra && $wa){$accessor=$self->make_accessor($field)}elsif ($ra){$accessor=$self->make_ro_accessor($field)}else {$accessor=$self->make_wo_accessor($field)}my$fullname="${class}::$accessor_name";my$subnamed=0;unless (defined &{$fullname}){subname($fullname,$accessor)if defined&subname;$subnamed=1;*{$fullname}=$accessor}if ($accessor_name eq $field){my$alias="${class}::_${field}_accessor";subname($alias,$accessor)if defined&subname and not $subnamed;*{$alias}=$accessor unless defined &{$alias}}}else {my$fullaccname="${class}::$accessor_name";my$fullmutname="${class}::$mutator_name";if ($ra and not defined &{$fullaccname}){my$accessor=$self->make_ro_accessor($field);subname($fullaccname,$accessor)if defined&subname;*{$fullaccname}=$accessor}if ($wa and not defined &{$fullmutname}){my$mutator=$self->make_wo_accessor($field);subname($fullmutname,$mutator)if defined&subname;*{$fullmutname}=$mutator}}}}}sub mk_ro_accessors {my($self,@fields)=@_;$self->_mk_accessors('ro',@fields)}sub mk_wo_accessors {my($self,@fields)=@_;$self->_mk_accessors('wo',@fields)}sub best_practice_accessor_name_for {my ($class,$field)=@_;return "get_$field"}sub best_practice_mutator_name_for {my ($class,$field)=@_;return "set_$field"}sub accessor_name_for {my ($class,$field)=@_;return$field}sub mutator_name_for {my ($class,$field)=@_;return$field}sub set {my($self,$key)=splice(@_,0,2);if(@_==1){$self->{$key}=$_[0]}elsif(@_ > 1){$self->{$key}=[@_]}else {$self->_croak("Wrong number of arguments received")}}sub get {my$self=shift;if(@_==1){return$self->{$_[0]}}elsif(@_ > 1){return @{$self}{@_}}else {$self->_croak("Wrong number of arguments received")}}sub make_accessor {my ($class,$field)=@_;return sub {my$self=shift;if(@_){return$self->set($field,@_)}else {return$self->get($field)}}}sub make_ro_accessor {my($class,$field)=@_;return sub {my$self=shift;if (@_){my$caller=caller;$self->_croak("'$caller' cannot alter the value of '$field' on objects of class '$class'")}else {return$self->get($field)}}}sub make_wo_accessor {my($class,$field)=@_;return sub {my$self=shift;unless (@_){my$caller=caller;$self->_croak("'$caller' cannot access the value of '$field' on objects of class '$class'")}else {return$self->set($field,@_)}}}use Carp ();sub _carp {my ($self,$msg)=@_;Carp::carp($msg || $self);return}sub _croak {my ($self,$msg)=@_;Carp::croak($msg || $self);return}1;
+ package Class::Accessor;require 5.00502;use strict;$Class::Accessor::VERSION='0.51';sub new {return bless defined $_[1]? {%{$_[1]}}: {},ref $_[0]|| $_[0]}sub mk_accessors {my($self,@fields)=@_;$self->_mk_accessors('rw',@fields)}if (eval {require Sub::Name}){Sub::Name->import}{no strict 'refs';sub import {my ($class,@what)=@_;my$caller=caller;for (@what){if (/^(?:antlers|moose-?like)$/i){*{"${caller}::has"}=sub {my ($f,%args)=@_;$caller->_mk_accessors(($args{is}||"rw"),$f)};*{"${caller}::extends"}=sub {@{"${caller}::ISA"}=@_;unless (grep $_->can("_mk_accessors"),@_){push @{"${caller}::ISA"},$class}};&{"${caller}::extends"}(@{"${caller}::ISA"})}}}sub follow_best_practice {my($self)=@_;my$class=ref$self || $self;*{"${class}::accessor_name_for"}=\&best_practice_accessor_name_for;*{"${class}::mutator_name_for"}=\&best_practice_mutator_name_for}sub _mk_accessors {my($self,$access,@fields)=@_;my$class=ref$self || $self;my$ra=$access eq 'rw' || $access eq 'ro';my$wa=$access eq 'rw' || $access eq 'wo';for my$field (@fields){my$accessor_name=$self->accessor_name_for($field);my$mutator_name=$self->mutator_name_for($field);if($accessor_name eq 'DESTROY' or $mutator_name eq 'DESTROY'){$self->_carp("Having a data accessor named DESTROY in '$class' is unwise.")}if ($accessor_name eq $mutator_name){my$accessor;if ($ra && $wa){$accessor=$self->make_accessor($field)}elsif ($ra){$accessor=$self->make_ro_accessor($field)}else {$accessor=$self->make_wo_accessor($field)}my$fullname="${class}::$accessor_name";my$subnamed=0;unless (defined &{$fullname}){subname($fullname,$accessor)if defined&subname;$subnamed=1;*{$fullname}=$accessor}if ($accessor_name eq $field){my$alias="${class}::_${field}_accessor";subname($alias,$accessor)if defined&subname and not $subnamed;*{$alias}=$accessor unless defined &{$alias}}}else {my$fullaccname="${class}::$accessor_name";my$fullmutname="${class}::$mutator_name";if ($ra and not defined &{$fullaccname}){my$accessor=$self->make_ro_accessor($field);subname($fullaccname,$accessor)if defined&subname;*{$fullaccname}=$accessor}if ($wa and not defined &{$fullmutname}){my$mutator=$self->make_wo_accessor($field);subname($fullmutname,$mutator)if defined&subname;*{$fullmutname}=$mutator}}}}}sub mk_ro_accessors {my($self,@fields)=@_;$self->_mk_accessors('ro',@fields)}sub mk_wo_accessors {my($self,@fields)=@_;$self->_mk_accessors('wo',@fields)}sub best_practice_accessor_name_for {my ($class,$field)=@_;return "get_$field"}sub best_practice_mutator_name_for {my ($class,$field)=@_;return "set_$field"}sub accessor_name_for {my ($class,$field)=@_;return$field}sub mutator_name_for {my ($class,$field)=@_;return$field}sub set {my($self,$key)=splice(@_,0,2);if(@_==1){$self->{$key}=$_[0]}elsif(@_ > 1){$self->{$key}=[@_]}else {$self->_croak("Wrong number of arguments received")}}sub get {my$self=shift;if(@_==1){return$self->{$_[0]}}elsif(@_ > 1){return @{$self}{@_}}else {$self->_croak("Wrong number of arguments received")}}sub make_accessor {my ($class,$field)=@_;return sub {my$self=shift;if(@_){return$self->set($field,@_)}else {return$self->get($field)}}}sub make_ro_accessor {my($class,$field)=@_;return sub {my$self=shift;if (@_){my$caller=caller;$self->_croak("'$caller' cannot alter the value of '$field' on objects of class '$class'")}else {return$self->get($field)}}}sub make_wo_accessor {my($class,$field)=@_;return sub {my$self=shift;unless (@_){my$caller=caller;$self->_croak("'$caller' cannot access the value of '$field' on objects of class '$class'")}else {return$self->set($field,@_)}}}use Carp ();sub _carp {my ($self,$msg)=@_;Carp::carp($msg || $self);return}sub _croak {my ($self,$msg)=@_;Carp::croak($msg || $self);return}1;
CLASS_ACCESSOR
$fatpacked{"Class/Accessor/Fast.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CLASS_ACCESSOR_FAST';
- package Class::Accessor::Fast;use base 'Class::Accessor';use strict;$Class::Accessor::Fast::VERSION='0.34';sub make_accessor {my($class,$field)=@_;return sub {return $_[0]->{$field}if scalar(@_)==1;return $_[0]->{$field}=scalar(@_)==2 ? $_[1]: [@_[1..$#_]]}}sub make_ro_accessor {my($class,$field)=@_;return sub {return $_[0]->{$field}if @_==1;my$caller=caller;$_[0]->_croak("'$caller' cannot alter the value of '$field' on objects of class '$class'")}}sub make_wo_accessor {my($class,$field)=@_;return sub {if (@_==1){my$caller=caller;$_[0]->_croak("'$caller' cannot access the value of '$field' on objects of class '$class'")}else {return $_[0]->{$field}=$_[1]if @_==2;return (shift)->{$field}=\@_}}}1;
+ package Class::Accessor::Fast;use base 'Class::Accessor';use strict;use B 'perlstring';$Class::Accessor::Fast::VERSION='0.51';sub make_accessor {my ($class,$field)=@_;eval sprintf q{
+ sub {
+ return $_[0]{%s} if scalar(@_) == 1;
+ return $_[0]{%s} = scalar(@_) == 2 ? $_[1] : [@_[1..$#_]];
+ }
+ },map {perlstring($_)}$field,$field}sub make_ro_accessor {my($class,$field)=@_;eval sprintf q{
+ sub {
+ return $_[0]{%s} if @_ == 1;
+ my $caller = caller;
+ $_[0]->_croak(sprintf "'$caller' cannot alter the value of '%%s' on objects of class '%%s'", %s, %s);
+ }
+ },map {perlstring($_)}$field,$field,$class}sub make_wo_accessor {my($class,$field)=@_;eval sprintf q{
+ sub {
+ if (@_ == 1) {
+ my $caller = caller;
+ $_[0]->_croak(sprintf "'$caller' cannot access the value of '%%s' on objects of class '%%s'", %s, %s);
+ }
+ else {
+ return $_[0]{%s} = $_[1] if @_ == 2;
+ return (shift)->{%s} = \@_;
+ }
+ }
+ },map {perlstring($_)}$field,$class,$field,$field}1;
CLASS_ACCESSOR_FAST
$fatpacked{"Class/Accessor/Faster.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CLASS_ACCESSOR_FASTER';
- package Class::Accessor::Faster;use base 'Class::Accessor';use strict;$Class::Accessor::Faster::VERSION='0.34';my%slot;sub _slot {my($class,$field)=@_;my$n=$slot{$class}->{$field};return$n if defined$n;$n=keys %{$slot{$class}};$slot{$class}->{$field}=$n;return$n}sub new {my($proto,$fields)=@_;my($class)=ref$proto || $proto;my$self=bless [],$class;$fields={}unless defined$fields;for my$k (keys %$fields){my$n=$class->_slot($k);$self->[$n]=$fields->{$k}}return$self}sub make_accessor {my($class,$field)=@_;my$n=$class->_slot($field);return sub {return $_[0]->[$n]if scalar(@_)==1;return $_[0]->[$n]=scalar(@_)==2 ? $_[1]: [@_[1..$#_]]}}sub make_ro_accessor {my($class,$field)=@_;my$n=$class->_slot($field);return sub {return $_[0]->[$n]if @_==1;my$caller=caller;$_[0]->_croak("'$caller' cannot alter the value of '$field' on objects of class '$class'")}}sub make_wo_accessor {my($class,$field)=@_;my$n=$class->_slot($field);return sub {if (@_==1){my$caller=caller;$_[0]->_croak("'$caller' cannot access the value of '$field' on objects of class '$class'")}else {return $_[0]->[$n]=$_[1]if @_==2;return (shift)->[$n]=\@_}}}1;
+ package Class::Accessor::Faster;use base 'Class::Accessor';use strict;use B 'perlstring';$Class::Accessor::Faster::VERSION='0.51';my%slot;sub _slot {my($class,$field)=@_;my$n=$slot{$class}->{$field};return$n if defined$n;$n=keys %{$slot{$class}};$slot{$class}->{$field}=$n;return$n}sub new {my($proto,$fields)=@_;my($class)=ref$proto || $proto;my$self=bless [],$class;$fields={}unless defined$fields;for my$k (keys %$fields){my$n=$class->_slot($k);$self->[$n]=$fields->{$k}}return$self}sub make_accessor {my($class,$field)=@_;my$n=$class->_slot($field);eval sprintf q{
+ sub {
+ return $_[0][%d] if scalar(@_) == 1;
+ return $_[0][%d] = scalar(@_) == 2 ? $_[1] : [@_[1..$#_]];
+ }
+ },$n,$n}sub make_ro_accessor {my($class,$field)=@_;my$n=$class->_slot($field);eval sprintf q{
+ sub {
+ return $_[0][%d] if @_ == 1;
+ my $caller = caller;
+ $_[0]->_croak(sprintf "'$caller' cannot alter the value of '%%s' on objects of class '%%s'", %s, %s);
+ }
+ },$n,map(perlstring($_),$field,$class)}sub make_wo_accessor {my($class,$field)=@_;my$n=$class->_slot($field);eval sprintf q{
+ sub {
+ if (@_ == 1) {
+ my $caller = caller;
+ $_[0]->_croak(sprintf "'$caller' cannot access the value of '%%s' on objects of class '%%s'", %s, %s);
+ }
+ else {
+ return $_[0][%d] = $_[1] if @_ == 2;
+ return (shift)->[%d] = \@_;
+ }
+ }
+ },map(perlstring($_),$field,$class),$n,$n}1;
CLASS_ACCESSOR_FASTER
$fatpacked{"Config/Tiny.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CONFIG_TINY';
@@ -6159,7 +6335,7 @@
MODULE_PLUGGABLE_OBJECT
$fatpacked{"Module/Runtime.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_RUNTIME';
- package Module::Runtime;BEGIN {require 5.006}BEGIN {${^WARNING_BITS}=""}our$VERSION="0.015";our@EXPORT_OK=qw($module_name_rx is_module_name is_valid_module_name check_module_name module_notional_filename require_module use_module use_package_optimistically $top_module_spec_rx $sub_module_spec_rx is_module_spec is_valid_module_spec check_module_spec compose_module_name);my%export_ok=map {($_=>undef)}@EXPORT_OK;sub import {my$me=shift;my$callpkg=caller(0);my$errs="";for(@_){if(exists$export_ok{$_}){if(/\A\$(.*)\z/s){*{$callpkg."::".$1}=\$$1}else {*{$callpkg."::".$_}=\&$_}}else {$errs .= "\"$_\" is not exported by the $me module\n"}}if($errs ne ""){die "${errs}Can't continue after import errors "."at @{[(caller(0))[1]]} line @{[(caller(0))[2]]}.\n"}}sub _is_string($) {my($arg)=@_;return defined($arg)&& ref(\$arg)eq "SCALAR"}our$module_name_rx=qr/[A-Z_a-z][0-9A-Z_a-z]*(?:::[0-9A-Z_a-z]+)*/;my$qual_module_spec_rx=qr#(?:/|::)[A-Z_a-z][0-9A-Z_a-z]*(?:(?:/|::)[0-9A-Z_a-z]+)*#;my$unqual_top_module_spec_rx=qr#[A-Z_a-z][0-9A-Z_a-z]*(?:(?:/|::)[0-9A-Z_a-z]+)*#;our$top_module_spec_rx=qr/$qual_module_spec_rx|$unqual_top_module_spec_rx/o;my$unqual_sub_module_spec_rx=qr#[0-9A-Z_a-z]+(?:(?:/|::)[0-9A-Z_a-z]+)*#;our$sub_module_spec_rx=qr/$qual_module_spec_rx|$unqual_sub_module_spec_rx/o;sub is_module_name($) {_is_string($_[0])&& $_[0]=~ /\A$module_name_rx\z/o}*is_valid_module_name=\&is_module_name;sub check_module_name($) {unless(&is_module_name){die +(_is_string($_[0])? "`$_[0]'" : "argument")." is not a module name\n"}}sub module_notional_filename($) {&check_module_name;my($name)=@_;$name =~ s!::!/!g;return$name.".pm"}BEGIN {*_WORK_AROUND_HINT_LEAKAGE="$]" < 5.011 &&!("$]" >= 5.009004 && "$]" < 5.010001)? sub(){1}: sub(){0};*_WORK_AROUND_BROKEN_MODULE_STATE="$]" < 5.009 ? sub(){1}: sub(){0}}BEGIN {if(_WORK_AROUND_BROKEN_MODULE_STATE){eval q{
+ package Module::Runtime;BEGIN {require 5.006}BEGIN {${^WARNING_BITS}=""}our$VERSION="0.016";our@EXPORT_OK=qw($module_name_rx is_module_name is_valid_module_name check_module_name module_notional_filename require_module use_module use_package_optimistically $top_module_spec_rx $sub_module_spec_rx is_module_spec is_valid_module_spec check_module_spec compose_module_name);my%export_ok=map {($_=>undef)}@EXPORT_OK;sub import {my$me=shift;my$callpkg=caller(0);my$errs="";for(@_){if(exists$export_ok{$_}){if(/\A\$(.*)\z/s){*{$callpkg."::".$1}=\$$1}else {*{$callpkg."::".$_}=\&$_}}else {$errs .= "\"$_\" is not exported by the $me module\n"}}if($errs ne ""){die "${errs}Can't continue after import errors "."at @{[(caller(0))[1]]} line @{[(caller(0))[2]]}.\n"}}sub _is_string($) {my($arg)=@_;return defined($arg)&& ref(\$arg)eq "SCALAR"}our$module_name_rx=qr/[A-Z_a-z][0-9A-Z_a-z]*(?:::[0-9A-Z_a-z]+)*/;my$qual_module_spec_rx=qr#(?:/|::)[A-Z_a-z][0-9A-Z_a-z]*(?:(?:/|::)[0-9A-Z_a-z]+)*#;my$unqual_top_module_spec_rx=qr#[A-Z_a-z][0-9A-Z_a-z]*(?:(?:/|::)[0-9A-Z_a-z]+)*#;our$top_module_spec_rx=qr/$qual_module_spec_rx|$unqual_top_module_spec_rx/o;my$unqual_sub_module_spec_rx=qr#[0-9A-Z_a-z]+(?:(?:/|::)[0-9A-Z_a-z]+)*#;our$sub_module_spec_rx=qr/$qual_module_spec_rx|$unqual_sub_module_spec_rx/o;sub is_module_name($) {_is_string($_[0])&& $_[0]=~ /\A$module_name_rx\z/o}*is_valid_module_name=\&is_module_name;sub check_module_name($) {unless(&is_module_name){die +(_is_string($_[0])? "`$_[0]'" : "argument")." is not a module name\n"}}sub module_notional_filename($) {&check_module_name;my($name)=@_;$name =~ s!::!/!g;return$name.".pm"}BEGIN {*_WORK_AROUND_HINT_LEAKAGE="$]" < 5.011 &&!("$]" >= 5.009004 && "$]" < 5.010001)? sub(){1}: sub(){0};*_WORK_AROUND_BROKEN_MODULE_STATE="$]" < 5.009 ? sub(){1}: sub(){0}}BEGIN {if(_WORK_AROUND_BROKEN_MODULE_STATE){eval q{
sub Module::Runtime::__GUARD__::DESTROY {
delete $INC{$_[0]->[0]} if @{$_[0]};
}
@@ -6169,7 +6345,7 @@
MODULE_RUNTIME
$fatpacked{"Monitoring/Plugin.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MONITORING_PLUGIN';
- package Monitoring::Plugin;use Monitoring::Plugin::Functions qw(:codes %ERRORS %STATUS_TEXT @STATUS_CODES);use Params::Validate qw(:all);use 5.006;use strict;use warnings;use Carp;use base qw(Class::Accessor::Fast);Monitoring::Plugin->mk_accessors(qw(shortname perfdata messages opts threshold));use Exporter;our@ISA=qw(Exporter);our@EXPORT=(@STATUS_CODES);our@EXPORT_OK=qw(%ERRORS %STATUS_TEXT);our$VERSION="0.39";sub new {my$class=shift;my%args=validate(@_,{shortname=>0,usage=>0,version=>0,url=>0,plugin=>0,blurb=>0,extra=>0,license=>0,timeout=>0 },);my$shortname=Monitoring::Plugin::Functions::get_shortname(\%args);delete$args{shortname}if (exists$args{shortname});my$self={shortname=>$shortname,perfdata=>[],messages=>{warning=>[],critical=>[],ok=>[]},opts=>undef,threshold=>undef,};bless$self,$class;if (exists$args{usage}){require Monitoring::Plugin::Getopt;$self->opts(new Monitoring::Plugin::Getopt(%args))}return$self}sub add_perfdata {my ($self,%args)=@_;require Monitoring::Plugin::Performance;my$perf=Monitoring::Plugin::Performance->new(%args);push @{$self->perfdata},$perf}sub all_perfoutput {my$self=shift;return join(" ",map {$_->perfoutput}(@{$self->perfdata}))}sub set_thresholds {my$self=shift;require Monitoring::Plugin::Threshold;return$self->threshold(Monitoring::Plugin::Threshold->set_thresholds(@_))}sub plugin_exit {my$self=shift;Monitoring::Plugin::Functions::plugin_exit(@_,{plugin=>$self })}sub plugin_die {my$self=shift;Monitoring::Plugin::Functions::plugin_die(@_,{plugin=>$self })}sub nagios_exit {my$self=shift;Monitoring::Plugin::Functions::plugin_exit(@_,{plugin=>$self })}sub nagios_die {my$self=shift;Monitoring::Plugin::Functions::plugin_die(@_,{plugin=>$self })}sub die {my$self=shift;Monitoring::Plugin::Functions::plugin_die(@_,{plugin=>$self })}sub max_state {Monitoring::Plugin::Functions::max_state(@_)}sub max_state_alt {Monitoring::Plugin::Functions::max_state_alt(@_)}sub check_threshold {my$self=shift;my%args;if ($#_==0 && (!ref $_[0]|| ref $_[0]eq "ARRAY")){%args=(check=>shift)}else {%args=validate (@_,{check=>1,warning=>0,critical=>0,})}if (exists$args{warning}|| exists$args{critical}){$self->set_thresholds(warning=>$args{warning},critical=>$args{critical},)}elsif (defined$self->threshold){}elsif (defined$self->opts){$self->set_thresholds(warning=>$self->opts->warning,critical=>$self->opts->critical,)}else {return UNKNOWN}return$self->threshold->get_status($args{check})}sub add_arg {my$self=shift;$self->opts->arg(@_)if$self->_check_for_opts}sub getopts {my$self=shift;$self->opts->getopts(@_)if$self->_check_for_opts}sub _check_for_opts {my$self=shift;croak "You have to supply a 'usage' param to Monitoring::Plugin::new() if you want to use Getopts from your Monitoring::Plugin object." unless ref$self->opts()eq 'Monitoring::Plugin::Getopt';return$self}sub add_message {my$self=shift;my ($code,@messages)=@_;croak "Invalid error code '$code'" unless defined($ERRORS{uc$code})|| defined($STATUS_TEXT{$code});$code=$STATUS_TEXT{$code}if$STATUS_TEXT{$code};$code=lc$code;croak "Error code '$code' not supported by add_message" if$code eq 'unknown' || $code eq 'dependent';$self->messages($code,[])unless$self->messages->{$code};push @{$self->messages->{$code}},@messages}sub check_messages {my$self=shift;my%args=@_;for my$code (qw(critical warning ok)){my$messages=$self->messages->{$code}|| [];if ($args{$code}){unless (ref$args{$code}eq 'ARRAY'){if ($code eq 'ok'){$args{$code}=[$args{$code}]}else {croak "Invalid argument '$code'"}}push @{$args{$code}},@$messages}else {$args{$code}=$messages}}Monitoring::Plugin::Functions::check_messages(%args)}1;
+ package Monitoring::Plugin;use Monitoring::Plugin::Functions qw(:codes %ERRORS %STATUS_TEXT @STATUS_CODES);use Params::Validate qw(:all);use 5.006;use strict;use warnings;use Carp;use base qw(Class::Accessor::Fast);Monitoring::Plugin->mk_accessors(qw(shortname perfdata messages opts threshold));use Exporter;our@ISA=qw(Exporter);our@EXPORT=(@STATUS_CODES);our@EXPORT_OK=qw(%ERRORS %STATUS_TEXT);our$VERSION="0.40";sub new {my$class=shift;my%args=validate(@_,{shortname=>0,usage=>0,version=>0,url=>0,plugin=>0,blurb=>0,extra=>0,license=>0,timeout=>0 },);my$shortname=Monitoring::Plugin::Functions::get_shortname(\%args);delete$args{shortname}if (exists$args{shortname});my$self={shortname=>$shortname,perfdata=>[],messages=>{warning=>[],critical=>[],ok=>[]},opts=>undef,threshold=>undef,};bless$self,$class;if (exists$args{usage}){require Monitoring::Plugin::Getopt;$self->opts(new Monitoring::Plugin::Getopt(%args))}return$self}sub add_perfdata {my ($self,%args)=@_;require Monitoring::Plugin::Performance;my$perf=Monitoring::Plugin::Performance->new(%args);push @{$self->perfdata},$perf}sub all_perfoutput {my$self=shift;return join(" ",map {$_->perfoutput}(@{$self->perfdata}))}sub set_thresholds {my$self=shift;require Monitoring::Plugin::Threshold;return$self->threshold(Monitoring::Plugin::Threshold->set_thresholds(@_))}sub plugin_exit {my$self=shift;Monitoring::Plugin::Functions::plugin_exit(@_,{plugin=>$self })}sub plugin_die {my$self=shift;Monitoring::Plugin::Functions::plugin_die(@_,{plugin=>$self })}sub nagios_exit {my$self=shift;Monitoring::Plugin::Functions::plugin_exit(@_,{plugin=>$self })}sub nagios_die {my$self=shift;Monitoring::Plugin::Functions::plugin_die(@_,{plugin=>$self })}sub die {my$self=shift;Monitoring::Plugin::Functions::plugin_die(@_,{plugin=>$self })}sub max_state {Monitoring::Plugin::Functions::max_state(@_)}sub max_state_alt {Monitoring::Plugin::Functions::max_state_alt(@_)}sub check_threshold {my$self=shift;my%args;if ($#_==0 && (!ref $_[0]|| ref $_[0]eq "ARRAY")){%args=(check=>shift)}else {%args=validate (@_,{check=>1,warning=>0,critical=>0,})}if (exists$args{warning}|| exists$args{critical}){$self->set_thresholds(warning=>$args{warning},critical=>$args{critical},)}elsif (defined$self->threshold){}elsif (defined$self->opts){$self->set_thresholds(warning=>$self->opts->warning,critical=>$self->opts->critical,)}else {return UNKNOWN}return$self->threshold->get_status($args{check})}sub add_arg {my$self=shift;$self->opts->arg(@_)if$self->_check_for_opts}sub getopts {my$self=shift;$self->opts->getopts(@_)if$self->_check_for_opts}sub _check_for_opts {my$self=shift;croak "You have to supply a 'usage' param to Monitoring::Plugin::new() if you want to use Getopts from your Monitoring::Plugin object." unless ref$self->opts()eq 'Monitoring::Plugin::Getopt';return$self}sub add_message {my$self=shift;my ($code,@messages)=@_;croak "Invalid error code '$code'" unless defined($ERRORS{uc$code})|| defined($STATUS_TEXT{$code});$code=$STATUS_TEXT{$code}if$STATUS_TEXT{$code};$code=lc$code;croak "Error code '$code' not supported by add_message" if$code eq 'unknown' || $code eq 'dependent';$self->messages($code,[])unless$self->messages->{$code};push @{$self->messages->{$code}},@messages}sub check_messages {my$self=shift;my%args=@_;for my$code (qw(critical warning ok)){my$messages=$self->messages->{$code}|| [];if ($args{$code}){unless (ref$args{$code}eq 'ARRAY'){if ($code eq 'ok'){$args{$code}=[$args{$code}]}else {croak "Invalid argument '$code'"}}push @{$args{$code}},@$messages}else {$args{$code}=$messages}}Monitoring::Plugin::Functions::check_messages(%args)}1;
MONITORING_PLUGIN
$fatpacked{"Monitoring/Plugin/Config.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MONITORING_PLUGIN_CONFIG';
@@ -6181,17 +6357,17 @@
MONITORING_PLUGIN_EXITRESULT
$fatpacked{"Monitoring/Plugin/Functions.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MONITORING_PLUGIN_FUNCTIONS';
- package Monitoring::Plugin::Functions;use 5.006;use strict;use warnings;use File::Basename;use Params::Validate qw(:types validate);use Math::Calc::Units;our$VERSION="0.39";our@STATUS_CODES=qw(OK WARNING CRITICAL UNKNOWN DEPENDENT);require Exporter;our@ISA=qw(Exporter);our@EXPORT=(@STATUS_CODES,qw(plugin_exit plugin_die check_messages));our@EXPORT_OK=qw(%ERRORS %STATUS_TEXT @STATUS_CODES get_shortname max_state max_state_alt convert $value_re);our%EXPORT_TAGS=(all=>[@EXPORT,@EXPORT_OK ],codes=>[@STATUS_CODES ],functions=>[qw(plugin_exit plugin_die check_messages max_state max_state_alt convert) ],);use constant OK=>0;use constant WARNING=>1;use constant CRITICAL=>2;use constant UNKNOWN=>3;use constant DEPENDENT=>4;our%ERRORS=('OK'=>OK,'WARNING'=>WARNING,'CRITICAL'=>CRITICAL,'UNKNOWN'=>UNKNOWN,'DEPENDENT'=>DEPENDENT,);our%STATUS_TEXT=reverse%ERRORS;my$value=qr/[-+]?[\d\.]+/;our$value_re=qr/$value(?:e$value)?/;my$_fake_exit=0;sub _fake_exit {@_ ? $_fake_exit=shift : $_fake_exit};my$_use_die=0;sub _use_die {@_ ? $_use_die=shift : $_use_die};sub get_shortname {my$arg=shift;my$shortname=undef;return$arg->{shortname}if (defined($arg->{shortname}));$shortname=$arg->{plugin}if (defined($arg->{plugin}));$shortname=uc basename($shortname || $ENV{PLUGIN_NAME}|| $ENV{NAGIOS_PLUGIN}|| $0);$shortname =~ s/^CHECK_(?:BY_)?//;$shortname =~ s/\..*$//;return$shortname}sub max_state {return CRITICAL if grep {$_==CRITICAL}@_;return WARNING if grep {$_==WARNING}@_;return OK if grep {$_==OK}@_;return UNKNOWN if grep {$_==UNKNOWN}@_;return DEPENDENT if grep {$_==DEPENDENT}@_;return UNKNOWN}sub max_state_alt {return CRITICAL if grep {$_==CRITICAL}@_;return WARNING if grep {$_==WARNING}@_;return UNKNOWN if grep {$_==UNKNOWN}@_;return DEPENDENT if grep {$_==DEPENDENT}@_;return OK if grep {$_==OK}@_;return UNKNOWN}sub plugin_exit {my ($code,$message,$arg)=@_;if (defined$code && ($code eq 'return_code' || $code eq 'message')){if (int(@_ / 2)!=@_ / 2 && ref $_[$#_]){$arg=pop @_}else {undef$arg}my%arg=@_;$code=$arg{return_code};$message=$arg{message}}$arg ||= {};$code=$ERRORS{$code}if defined$code && exists$ERRORS{$code};$code=UNKNOWN unless defined$code && exists$STATUS_TEXT{$code};$message='' unless defined$message;if (ref$message && ref$message eq 'ARRAY'){$message=join(' ',map {chomp;$_}@$message)}else {chomp$message}my$output="$STATUS_TEXT{$code}";$output .= " - $message" if defined$message && $message ne '';my$shortname=($arg->{plugin}? $arg->{plugin}->shortname : undef);$shortname ||= get_shortname();$output="$shortname $output" if$shortname;if ($arg->{plugin}){my$plugin=$arg->{plugin};$output .= " | ".$plugin->all_perfoutput if$plugin->perfdata && $plugin->all_perfoutput}$output .= "\n";if ($_fake_exit){require Monitoring::Plugin::ExitResult;return Monitoring::Plugin::ExitResult->new($code,$output)}_plugin_exit($code,$output)}sub _plugin_exit {my ($code,$output)=@_;if ($_use_die){for (my$i=0;;$i++){@_=caller($i);last unless @_;if ($_[3]=~ m/die/){$!=$code;die($output)}}}print$output;exit$code}sub plugin_die {my ($arg1,$arg2,$rest)=@_;if (defined$arg1 && ($arg1 eq 'return_code' || $arg1 eq 'message')){return plugin_exit(@_)}elsif (defined$arg1 && (exists$ERRORS{$arg1}|| exists$STATUS_TEXT{$arg1})){return plugin_exit(@_)}elsif (defined$arg2 && (exists$ERRORS{$arg2}|| exists$STATUS_TEXT{$arg2})){return plugin_exit($arg2,$arg1,$rest)}else {return plugin_exit(UNKNOWN,$arg1,$arg2)}}sub die {plugin_die(@_)}sub convert {my ($value,$from,$to)=@_;my ($newval)=Math::Calc::Units::convert("$value $from",$to,'exact');return$newval}sub check_messages {my%arg=validate(@_,{critical=>{type=>ARRAYREF },warning=>{type=>ARRAYREF },ok=>{type=>ARRAYREF | SCALAR,optional=>1 },'join'=>{default=>' ' },join_all=>0,});$arg{join}=' ' unless defined$arg{join};my$code=OK;$code ||= CRITICAL if @{$arg{critical}};$code ||= WARNING if @{$arg{warning}};return$code unless wantarray;my$message='';if ($arg{join_all}){$message=join($arg{join_all},map {@$_ ? join($arg{'join'},@$_): ()}$arg{critical},$arg{warning},$arg{ok}? (ref$arg{ok}? $arg{ok}: [$arg{ok}]): [])}else {$message ||= join($arg{'join'},@{$arg{critical}})if$code==CRITICAL;$message ||= join($arg{'join'},@{$arg{warning}})if$code==WARNING;$message ||= ref$arg{ok}? join($arg{'join'},@{$arg{ok}}): $arg{ok}if$arg{ok}}return ($code,$message)}1;
+ package Monitoring::Plugin::Functions;use 5.006;use strict;use warnings;use File::Basename;use Params::Validate qw(:types validate);use Math::Calc::Units;our$VERSION="0.40";our@STATUS_CODES=qw(OK WARNING CRITICAL UNKNOWN DEPENDENT);require Exporter;our@ISA=qw(Exporter);our@EXPORT=(@STATUS_CODES,qw(plugin_exit plugin_die check_messages));our@EXPORT_OK=qw(%ERRORS %STATUS_TEXT @STATUS_CODES get_shortname max_state max_state_alt convert $value_re);our%EXPORT_TAGS=(all=>[@EXPORT,@EXPORT_OK ],codes=>[@STATUS_CODES ],functions=>[qw(plugin_exit plugin_die check_messages max_state max_state_alt convert) ],);use constant OK=>0;use constant WARNING=>1;use constant CRITICAL=>2;use constant UNKNOWN=>3;use constant DEPENDENT=>4;our%ERRORS=('OK'=>OK,'WARNING'=>WARNING,'CRITICAL'=>CRITICAL,'UNKNOWN'=>UNKNOWN,'DEPENDENT'=>DEPENDENT,);our%STATUS_TEXT=reverse%ERRORS;my$value=qr/[-+]?[\d\.]+/;our$value_re=qr/$value(?:e$value)?/;my$_fake_exit=0;sub _fake_exit {@_ ? $_fake_exit=shift : $_fake_exit};my$_use_die=0;sub _use_die {@_ ? $_use_die=shift : $_use_die};sub get_shortname {my$arg=shift;my$shortname=undef;return$arg->{shortname}if (defined($arg->{shortname}));$shortname=$arg->{plugin}if (defined($arg->{plugin}));$shortname=uc basename($shortname || $ENV{PLUGIN_NAME}|| $ENV{NAGIOS_PLUGIN}|| $0);$shortname =~ s/^CHECK_(?:BY_)?//;$shortname =~ s/\..*$//;return$shortname}sub max_state {return CRITICAL if grep {$_==CRITICAL}@_;return WARNING if grep {$_==WARNING}@_;return OK if grep {$_==OK}@_;return UNKNOWN if grep {$_==UNKNOWN}@_;return DEPENDENT if grep {$_==DEPENDENT}@_;return UNKNOWN}sub max_state_alt {return CRITICAL if grep {$_==CRITICAL}@_;return WARNING if grep {$_==WARNING}@_;return UNKNOWN if grep {$_==UNKNOWN}@_;return DEPENDENT if grep {$_==DEPENDENT}@_;return OK if grep {$_==OK}@_;return UNKNOWN}sub plugin_exit {my ($code,$message,$arg)=@_;if (defined$code && ($code eq 'return_code' || $code eq 'message')){if (int(@_ / 2)!=@_ / 2 && ref $_[$#_]){$arg=pop @_}else {undef$arg}my%arg=@_;$code=$arg{return_code};$message=$arg{message}}$arg ||= {};$code=$ERRORS{$code}if defined$code && exists$ERRORS{$code};$code=UNKNOWN unless defined$code && exists$STATUS_TEXT{$code};$message='' unless defined$message;if (ref$message && ref$message eq 'ARRAY'){$message=join(' ',map {chomp;$_}@$message)}else {chomp$message}my$output="$STATUS_TEXT{$code}";if (defined$message && $message ne ''){$output .= " - " unless$message =~ /^\s*\n/mxs;$output .= $message}my$shortname=($arg->{plugin}? $arg->{plugin}->shortname : undef);$shortname ||= get_shortname();$output="$shortname $output" if$shortname;if ($arg->{plugin}){my$plugin=$arg->{plugin};$output .= " | ".$plugin->all_perfoutput if$plugin->perfdata && $plugin->all_perfoutput}$output .= "\n";if ($_fake_exit){require Monitoring::Plugin::ExitResult;return Monitoring::Plugin::ExitResult->new($code,$output)}_plugin_exit($code,$output)}sub _plugin_exit {my ($code,$output)=@_;if ($_use_die){for (my$i=0;;$i++){@_=caller($i);last unless @_;if ($_[3]=~ m/die/){$!=$code;die($output)}}}print$output;exit$code}sub plugin_die {my ($arg1,$arg2,$rest)=@_;if (defined$arg1 && ($arg1 eq 'return_code' || $arg1 eq 'message')){return plugin_exit(@_)}elsif (defined$arg1 && (exists$ERRORS{$arg1}|| exists$STATUS_TEXT{$arg1})){return plugin_exit(@_)}elsif (defined$arg2 && (exists$ERRORS{$arg2}|| exists$STATUS_TEXT{$arg2})){return plugin_exit($arg2,$arg1,$rest)}else {return plugin_exit(UNKNOWN,$arg1,$arg2)}}sub die {plugin_die(@_)}sub convert {my ($value,$from,$to)=@_;my ($newval)=Math::Calc::Units::convert("$value $from",$to,'exact');return$newval}sub check_messages {my%arg=validate(@_,{critical=>{type=>ARRAYREF },warning=>{type=>ARRAYREF },ok=>{type=>ARRAYREF | SCALAR,optional=>1 },'join'=>{default=>' ' },join_all=>0,});$arg{join}=' ' unless defined$arg{join};my$code=OK;$code ||= CRITICAL if @{$arg{critical}};$code ||= WARNING if @{$arg{warning}};return$code unless wantarray;my$message='';if ($arg{join_all}){$message=join($arg{join_all},map {@$_ ? join($arg{'join'},@$_): ()}$arg{critical},$arg{warning},$arg{ok}? (ref$arg{ok}? $arg{ok}: [$arg{ok}]): [])}else {$message ||= join($arg{'join'},@{$arg{critical}})if$code==CRITICAL;$message ||= join($arg{'join'},@{$arg{warning}})if$code==WARNING;$message ||= ref$arg{ok}? join($arg{'join'},@{$arg{ok}}): $arg{ok}if$arg{ok}}return ($code,$message)}1;
MONITORING_PLUGIN_FUNCTIONS
$fatpacked{"Monitoring/Plugin/Getopt.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MONITORING_PLUGIN_GETOPT';
package Monitoring::Plugin::Getopt;use 5.006;use strict;use warnings;use File::Basename;use Getopt::Long qw(:config no_ignore_case bundling);use Carp;use Params::Validate qw(:all);use base qw(Class::Accessor);use Monitoring::Plugin::Functions;use Monitoring::Plugin::Config;use vars qw($VERSION);$VERSION=$Monitoring::Plugin::Functions::VERSION;my%DEFAULT=(timeout=>15,verbose=>0,license=>"This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY.
It may be used, redistributed and/or modified under the terms of the GNU
- General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).",);my@ARGS=({spec=>'usage|?',help=>"-?, --usage\n Print usage information",},{spec=>'help|h',help=>"-h, --help\n Print detailed help screen",},{spec=>'version|V',help=>"-V, --version\n Print version information",},{spec=>'extra-opts:s@',help=>"--extra-opts=[section][\@file]\n Read options from an ini file. See https://www.monitoring-plugins.org/doc/extra-opts.html\n for usage and examples.",},{spec=>'timeout|t=i',help=>"-t, --timeout=INTEGER\n Seconds before plugin times out (default: %s)",default=>$DEFAULT{timeout},},{spec=>'verbose|v+',help=>"-v, --verbose\n Show details for command-line debugging (can repeat up to 3 times)",default=>$DEFAULT{verbose},},);my%DEFER_ARGS=map {$_=>1}qw(timeout verbose);sub _die {my$self=shift;my ($msg)=@_;$msg .= "\n" unless substr($msg,-1)eq "\n";Monitoring::Plugin::Functions::_plugin_exit(3,$msg)}sub _attr {my$self=shift;my ($item,$extra)=@_;$extra='' unless defined$extra;return '' unless$self->{_attr}->{$item};$self->{_attr}->{$item}."\n" .$extra}sub _spec_to_help {my ($self,$spec,$label)=@_;my ($opts,$type)=split /=|:/,$spec,2;my$optional=($spec =~ m/:/);my (@short,@long);for (split /\|/,$opts){if (length $_==1){push@short,"-$_"}else {push@long,"--$_"}}my$help=join(', ',@short,@long);if ($type){if (!$label){if ($type eq 'i' || $type eq '+' || $type =~ /\d+/){$label='INTEGER'}else {$label='STRING'}}if ($optional){$help .= '[=' .$label .']'}else {$help .= '=' .$label}}elsif ($label){carp "Label specified, but there's no type in spec '$spec'"}$help .= "\n ";return$help}sub _options {my$self=shift;my@args=();my@defer=();for (@{$self->{_args}}){if (exists$DEFER_ARGS{$_->{name}}){push@defer,$_}else {push@args,$_}}my@options=();for my$arg (@args,@defer){my$help_array=ref$arg->{help}&& ref$arg->{help}eq 'ARRAY' ? $arg->{help}: [$arg->{help}];my$label_array=$arg->{label}&& ref$arg->{label}&& ref$arg->{label}eq 'ARRAY' ? $arg->{label}: [$arg->{label}];my$help_string='';for (my$i=0;$i <= $#$help_array;$i++){my$help=$help_array->[$i];if ($help =~ m/^\s*-/){$help_string .= $help}else {$help_string .= $self->_spec_to_help($arg->{spec},$label_array->[$i]).$help;$help_string .= "\n " if$i < $#$help_array}}if ($help_string =~ m/%s/){my$default=defined$arg->{default}? $arg->{default}: '';my$replaced=$help_string;$replaced =~ s|%s|$default|gmx;push@options,$replaced}else {push@options,$help_string}}return ' ' .join("\n ",@options)}sub _usage {my$self=shift;my$usage=$self->_attr('usage');$usage =~ s|%s|$self->{_attr}->{plugin}|gmx;return($usage)}sub _revision {my$self=shift;my$revision=sprintf "%s %s",$self->{_attr}->{plugin},$self->{_attr}->{version};$revision .= sprintf " [%s]",$self->{_attr}->{url}if$self->{_attr}->{url};$revision .= "\n";$revision}sub _help {my$self=shift;my$help='';$help .= $self->_revision ."\n";$help .= $self->_attr('license',"\n");$help .= $self->_attr('blurb',"\n");$help .= $self->_usage ? $self->_usage ."\n" : '';$help .= $self->_options ? $self->_options ."\n" : '';$help .= $self->_attr('extra',"\n");return$help}sub _process_specs_getopt_long {my$self=shift;my@opts=();for my$arg (@{$self->{_args}}){push@opts,$arg->{spec};my$spec=$arg->{spec};$spec =~ s/[=:].*$//;my$name=(split /\s*\|\s*/,$spec)[0];$arg->{name}=$name;if (defined$self->{$name}){$arg->{default}=$self->{$name}}else {$self->{$name}=$arg->{default}}}return@opts}sub _check_required_opts {my$self=shift;my@missing=();for my$arg (@{$self->{_args}}){if ($arg->{required}&&!defined$self->{$arg->{name}}){push@missing,$arg->{name}}}if (@missing){$self->_die($self->_usage ."\n" .join("\n",map {sprintf "Missing argument: %s",$_}@missing)."\n")}}sub _process_opts {my$self=shift;$self->_die($self->_usage)if$self->{usage};$self->_die($self->_revision)if$self->{version};$self->_die($self->_help)if$self->{help}}sub _load_config_section {my$self=shift;my ($section,$file,$flags)=@_;$section ||= $self->{_attr}->{plugin};my$Config;eval {$Config=Monitoring::Plugin::Config->read($file)};$self->_die($@)if ($@);$file ||= $Config->mp_getfile();$self->_die("Invalid section '$section' in config file '$file'")unless exists$Config->{$section};return$Config->{$section}}sub _setup_spec_index {my$self=shift;return if defined$self->{_spec};$self->{_spec}={map {$_->{name}=>$_->{spec}}@{$self->{_args}}}}sub _cmdline_value {my$self=shift;local $_=shift;if (m/\s/ && (m/^[^"']/ || m/[^"']$/)){return qq("$_")}elsif ($_ eq ''){return q("")}else {return $_}}sub _cmdline {my$self=shift;my ($hash)=@_;$hash ||= $self;$self->_setup_spec_index;my@args=();for my$key (sort keys %$hash){next if$key =~ m/^_/;next if exists$DEFAULT{$key}&& $hash->{$key}eq $DEFAULT{$key};next if grep {$key eq $_}qw(help usage version extra-opts);next unless defined$hash->{$key};my$spec=$self->{_spec}->{$key}|| '';if ($spec =~ m/[=:].+$/){for my$value (ref$hash->{$key}eq 'ARRAY' ? @{$hash->{$key}}: ($hash->{$key})){$value=$self->_cmdline_value($value);if (length($key)> 1){push@args,sprintf "--%s=%s",$key,$value}else {push@args,"-$key",$value}}}else {push@args,(length($key)> 1 ? '--' : '-').$key}}return wantarray ? @args : join(' ',@args)}sub _process_extra_opts {my$self=shift;my ($args)=@_;my$extopts_list=$args->{'extra-opts'};my@sargs=();for my$extopts (@$extopts_list){$extopts ||= $self->{_attr}->{plugin};my$section=$extopts;my$file='';if ($extopts =~ m/^([^@]*)@(.*?)\s*$/){$section=$1;$file=$2}my$shash=$self->_load_config_section($section,$file);push@sargs,$self->_cmdline($shash)}@ARGV=(@sargs,@{$self->{_attr}->{argv}});printf "[extra-opts] %s %s\n",$self->{_attr}->{plugin},join(' ',@ARGV)if$args->{verbose}&& $args->{verbose}>= 3}sub arg {my$self=shift;my%args;if ($_[0]=~ m/^(spec|help|required|default)$/ && scalar(@_)% 2==0){%args=validate(@_,{spec=>1,help=>1,default=>0,required=>0,label=>0,})}else {my@args=validate_pos(@_,1,1,0,0,0);%args=(spec=>$args[0],help=>$args[1],default=>$args[2],required=>$args[3],label=>$args[4],)}push @{$self->{_args}},\%args}sub getopts {my$self=shift;my@opt_array=$self->_process_specs_getopt_long;$self->{_attr}->{argv}=[@ARGV ];my$args1={};my$ok=GetOptions($args1,@opt_array);$self->_die($self->_usage)unless$ok;$self->_process_extra_opts($args1);$ok=GetOptions($self,@opt_array);$self->_die($self->_usage)unless$ok;$self->_process_opts;$self->_check_required_opts;$self->mk_ro_accessors(grep!/^_/,keys %$self);$SIG{ALRM}=sub {my$plugin=uc$self->{_attr}->{plugin};$plugin =~ s/^check_//;$self->_die(sprintf("%s UNKNOWN - plugin timed out (timeout %ss)",$plugin,$self->timeout))}}sub _init {my$self=shift;my$plugin=basename($ENV{PLUGIN_NAME}|| $ENV{NAGIOS_PLUGIN}|| $0);my%attr=validate(@_,{usage=>1,version=>0,url=>0,plugin=>{default=>$plugin },blurb=>0,extra=>0,'extra-opts'=>0,license=>{default=>$DEFAULT{license}},timeout=>{default=>$DEFAULT{timeout}},});$self->{timeout}=delete$attr{timeout};$self->{_attr}={%attr };chomp foreach values %{$self->{_attr}};$self->{_args}=[@ARGS ];$self}sub new {my$class=shift;my$self=bless {},$class;$self->_init(@_)}1;
+ General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).",);my@ARGS=({spec=>'usage|?',help=>"-?, --usage\n Print usage information",},{spec=>'help|h',help=>"-h, --help\n Print detailed help screen",},{spec=>'version|V',help=>"-V, --version\n Print version information",},{spec=>'extra-opts:s@',help=>"--extra-opts=[section][\@file]\n Read options from an ini file. See https://www.monitoring-plugins.org/doc/extra-opts.html\n for usage and examples.",},{spec=>'timeout|t=i',help=>"-t, --timeout=INTEGER\n Seconds before plugin times out (default: %s)",default=>$DEFAULT{timeout},},{spec=>'verbose|v+',help=>"-v, --verbose\n Show details for command-line debugging (can repeat up to 3 times)",default=>$DEFAULT{verbose},},);my%DEFER_ARGS=map {$_=>1}qw(timeout verbose);sub _die {my$self=shift;my ($msg)=@_;$msg .= "\n" unless substr($msg,-1)eq "\n";Monitoring::Plugin::Functions::_plugin_exit(3,$msg)}sub _attr {my$self=shift;my ($item,$extra)=@_;$extra='' unless defined$extra;return '' unless$self->{_attr}->{$item};$self->{_attr}->{$item}."\n" .$extra}sub _spec_to_help {my ($self,$spec,$label)=@_;my ($opts,$type)=split /=|:|!/,$spec,2;my$optional=($spec =~ m/:/);my$boolean=($spec =~ m/!/);my (@short,@long);for (split /\|/,$opts){if (length $_==1){push@short,"-$_"}else {push@long,$boolean ? "--[no-]$_" : "--$_"}}my$help=join(', ',@short,@long);if ($type){if (!$label){if ($type eq 'i' || $type eq '+' || $type =~ /\d+/){$label='INTEGER'}else {$label='STRING'}}if ($optional){$help .= '[=' .$label .']'}else {$help .= '=' .$label}}elsif ($label){carp "Label specified, but there's no type in spec '$spec'"}$help .= "\n ";return$help}sub _options {my$self=shift;my@args=();my@defer=();for (@{$self->{_args}}){if (exists$DEFER_ARGS{$_->{name}}){push@defer,$_}else {push@args,$_}}my@options=();for my$arg (@args,@defer){my$help_array=ref$arg->{help}&& ref$arg->{help}eq 'ARRAY' ? $arg->{help}: [$arg->{help}];my$label_array=$arg->{label}&& ref$arg->{label}&& ref$arg->{label}eq 'ARRAY' ? $arg->{label}: [$arg->{label}];my$help_string='';for (my$i=0;$i <= $#$help_array;$i++){my$help=$help_array->[$i];if ($help =~ m/^\s*-/){$help_string .= $help}else {$help_string .= $self->_spec_to_help($arg->{spec},$label_array->[$i]).$help;$help_string .= "\n " if$i < $#$help_array}}if ($help_string =~ m/%s/){my$default=defined$arg->{default}? $arg->{default}: '';my$replaced=$help_string;$replaced =~ s|%s|$default|gmx;push@options,$replaced}else {push@options,$help_string}}return ' ' .join("\n ",@options)}sub _usage {my$self=shift;my$usage=$self->_attr('usage');$usage =~ s|%s|$self->{_attr}->{plugin}|gmx;return($usage)}sub _revision {my$self=shift;my$revision=sprintf "%s %s",$self->{_attr}->{plugin},$self->{_attr}->{version};$revision .= sprintf " [%s]",$self->{_attr}->{url}if$self->{_attr}->{url};$revision .= "\n";$revision}sub _help {my$self=shift;my$help='';$help .= $self->_revision ."\n";$help .= $self->_attr('license',"\n");$help .= $self->_attr('blurb',"\n");$help .= $self->_usage ? $self->_usage ."\n" : '';$help .= $self->_options ? $self->_options ."\n" : '';$help .= $self->_attr('extra',"\n");return$help}sub _process_specs_getopt_long {my$self=shift;my@opts=();for my$arg (@{$self->{_args}}){push@opts,$arg->{spec};my$spec=$arg->{spec};$spec =~ s/[=:!].*$//;my$name=(split /\s*\|\s*/,$spec)[0];$arg->{name}=$name;if (defined$self->{$name}){$arg->{default}=$self->{$name}}else {$self->{$name}=$arg->{default}}}return@opts}sub _check_required_opts {my$self=shift;my@missing=();for my$arg (@{$self->{_args}}){if ($arg->{required}&&!defined$self->{$arg->{name}}){push@missing,$arg->{name}}}if (@missing){$self->_die($self->_usage ."\n" .join("\n",map {sprintf "Missing argument: %s",$_}@missing)."\n")}}sub _process_opts {my$self=shift;$self->_die($self->_usage)if$self->{usage};$self->_die($self->_revision)if$self->{version};$self->_die($self->_help)if$self->{help}}sub _load_config_section {my$self=shift;my ($section,$file,$flags)=@_;$section ||= $self->{_attr}->{plugin};my$Config;eval {$Config=Monitoring::Plugin::Config->read($file)};$self->_die($@)if ($@);defined$Config or $self->_die(Monitoring::Plugin::Config->errstr);$file ||= $Config->mp_getfile();$self->_die("Invalid section '$section' in config file '$file'")unless exists$Config->{$section};return$Config->{$section}}sub _setup_spec_index {my$self=shift;return if defined$self->{_spec};$self->{_spec}={map {$_->{name}=>$_->{spec}}@{$self->{_args}}}}sub _cmdline_value {my$self=shift;local $_=shift;if (m/\s/ && (m/^[^"']/ || m/[^"']$/)){return qq("$_")}elsif ($_ eq ''){return q("")}else {return $_}}sub _cmdline {my$self=shift;my ($hash)=@_;$hash ||= $self;$self->_setup_spec_index;my@args=();for my$key (sort keys %$hash){next if$key =~ m/^_/;next if exists$DEFAULT{$key}&& $hash->{$key}eq $DEFAULT{$key};next if grep {$key eq $_}qw(help usage version extra-opts);next unless defined$hash->{$key};my$spec=$self->{_spec}->{$key}|| '';if ($spec =~ m/[=:].+$/){for my$value (ref$hash->{$key}eq 'ARRAY' ? @{$hash->{$key}}: ($hash->{$key})){$value=$self->_cmdline_value($value);if (length($key)> 1){push@args,sprintf "--%s=%s",$key,$value}else {push@args,"-$key",$value}}}else {push@args,(length($key)> 1 ? '--' : '-').$key}}return wantarray ? @args : join(' ',@args)}sub _process_extra_opts {my$self=shift;my ($args)=@_;my$extopts_list=$args->{'extra-opts'};my@sargs=();for my$extopts (@$extopts_list){$extopts ||= $self->{_attr}->{plugin};my$section=$extopts;my$file='';if ($extopts =~ m/^([^@]*)@(.*?)\s*$/){$section=$1;$file=$2}my$shash=$self->_load_config_section($section,$file);push@sargs,$self->_cmdline($shash)}@ARGV=(@sargs,@{$self->{_attr}->{argv}});printf "[extra-opts] %s %s\n",$self->{_attr}->{plugin},join(' ',@ARGV)if$args->{verbose}&& $args->{verbose}>= 3}sub arg {my$self=shift;my%args;my%params=(spec=>1,help=>1,default=>0,required=>0,label=>0,);if (exists$params{$_[0]}&& @_ % 2==0){%args=validate(@_,\%params)}else {my@order=qw(spec help default required label);@args{@order}=validate_pos(@_,@params{@order})}push @{$self->{_args}},\%args}sub getopts {my$self=shift;my@opt_array=$self->_process_specs_getopt_long;$self->{_attr}->{argv}=[@ARGV ];my$args1={};my$ok=GetOptions($args1,@opt_array);$self->_die($self->_usage)unless$ok;$self->_process_extra_opts($args1);$ok=GetOptions($self,@opt_array);$self->_die($self->_usage)unless$ok;$self->_process_opts;$self->_check_required_opts;$self->mk_ro_accessors(grep!/^_/,keys %$self);$SIG{ALRM}=sub {my$plugin=uc$self->{_attr}->{plugin};$plugin =~ s/^CHECK[-_]//i;$self->_die(sprintf("%s UNKNOWN - plugin timed out (timeout %ss)",$plugin,$self->timeout))}}sub _init {my$self=shift;my$plugin=basename($ENV{PLUGIN_NAME}|| $ENV{NAGIOS_PLUGIN}|| $0);my%attr=validate(@_,{usage=>1,version=>0,url=>0,plugin=>{default=>$plugin },blurb=>0,extra=>0,'extra-opts'=>0,license=>{default=>$DEFAULT{license}},timeout=>{default=>$DEFAULT{timeout}},});$self->{timeout}=delete$attr{timeout};$self->{_attr}={%attr };chomp foreach values %{$self->{_attr}};$self->{_args}=[@ARGS ];$self}sub new {my$class=shift;my$self=bless {},$class;$self->_init(@_)}1;
MONITORING_PLUGIN_GETOPT
$fatpacked{"Monitoring/Plugin/Performance.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MONITORING_PLUGIN_PERFORMANCE';
- package Monitoring::Plugin::Performance;use 5.006;use strict;use warnings;use Carp;use base qw(Class::Accessor::Fast);__PACKAGE__->mk_ro_accessors(qw(label value uom warning critical min max));use Monitoring::Plugin::Functions;use Monitoring::Plugin::Threshold;use Monitoring::Plugin::Range;our ($VERSION)=$Monitoring::Plugin::Functions::VERSION;sub import {my ($class,%attr)=@_;$_=$attr{use_die}|| 0;Monitoring::Plugin::Functions::_use_die($_)}my$value=qr/[-+]?[\d\.,]+/;my$value_re=qr/$value(?:e$value)?/;my$value_with_negative_infinity=qr/$value_re|~/;sub _parse {my$class=shift;my$string=shift;$string =~ /^'?([^'=]+)'?=($value_re)([\w%]*);?($value_with_negative_infinity\:?$value_re?)?;?($value_with_negative_infinity\:?$value_re?)?;?($value_re)?;?($value_re)?/o;return undef unless ((defined $1 && $1 ne "")&& (defined $2 && $2 ne ""));my@info=($1,$2,$3,$4,$5,$6,$7);map {defined$info[$_]&& $info[$_]=~ s/,/./go}(1,3,4,5,6);my$performance_value;{my$not_value;local$SIG{__WARN__}=sub {$not_value++};$performance_value=$info[1]+0;return undef if$not_value}my$p=$class->new(label=>$info[0],value=>$performance_value,uom=>$info[2],warning=>$info[3],critical=>$info[4],min=>$info[5],max=>$info[6]);return$p}sub _nvl {my ($self,$value)=@_;defined$value ? $value : ''}sub perfoutput {my$self=shift;my$label=$self->label;if ($label =~ / /){$label="'$label'"}my$out=sprintf "%s=%s%s;%s;%s;%s;%s",$label,$self->value,$self->_nvl($self->uom),$self->_nvl($self->warning),$self->_nvl($self->critical),$self->_nvl($self->min),$self->_nvl($self->max);$out =~ s/;;$//;return$out}sub parse_perfstring {my ($class,$perfstring)=@_;my@perfs=();my$obj;while ($perfstring){$perfstring =~ s/^\s*//;if (@{[$perfstring =~ /=/g]}> 1){$perfstring =~ s/^(.*?=.*?)\s//;if (defined $1){$obj=$class->_parse($1)}else {$perfstring="";$obj=$class->_parse($perfstring)}}else {$obj=$class->_parse($perfstring);$perfstring=""}push@perfs,$obj if$obj}return@perfs}sub rrdlabel {my$self=shift;my$name=$self->clean_label;return substr($name,0,19)}sub clean_label {my$self=shift;my$name=$self->label;if ($name eq "/"){$name="root"}elsif ($name =~ s/^\///){$name =~ s/\//_/g}$name =~ s/\W/_/g;return$name}sub threshold {my$self=shift;return Monitoring::Plugin::Threshold->set_thresholds(warning=>$self->warning,critical=>$self->critical)}sub new {my$class=shift;my%arg=@_;if (my$threshold=delete$arg{threshold}){$arg{warning}||= $threshold->warning ."";$arg{critical}||= $threshold->critical .""}$class->SUPER::new(\%arg)}1;
+ package Monitoring::Plugin::Performance;use 5.006;use strict;use warnings;use Carp;use base qw(Class::Accessor::Fast);__PACKAGE__->mk_ro_accessors(qw(label value uom warning critical min max));use Monitoring::Plugin::Functions;use Monitoring::Plugin::Threshold;use Monitoring::Plugin::Range;our ($VERSION)=$Monitoring::Plugin::Functions::VERSION;sub import {my ($class,%attr)=@_;$_=$attr{use_die}|| 0;Monitoring::Plugin::Functions::_use_die($_)}my$value=qr/[-+]?[\d\.,]+/;my$value_re=qr/$value(?:e$value)?/;my$value_with_negative_infinity=qr/$value_re|~/;sub _parse {my$class=shift;my$string=shift;$string =~ /^'?([^'=]+)'?=($value_re)([\w%]*);?($value_with_negative_infinity\:?$value_re?)?;?($value_with_negative_infinity\:?$value_re?)?;?($value_re)?;?($value_re)?/o;return undef unless ((defined $1 && $1 ne "")&& (defined $2 && $2 ne ""));my@info=($1,$2,$3,$4,$5,$6,$7);map {defined$info[$_]&& $info[$_]=~ s/,/./go}(1,3,4,5,6);my$performance_value;{my$not_value;local$SIG{__WARN__}=sub {$not_value++};$performance_value=$info[1]+0;return undef if$not_value}my$p=$class->new(label=>$info[0],value=>$performance_value,uom=>$info[2],warning=>$info[3],critical=>$info[4],min=>$info[5],max=>$info[6]);return$p}sub _nvl {my ($self,$value)=@_;defined$value ? $value : ''}sub perfoutput {my$self=shift;my$label=$self->label;if ($label =~ / /){$label="'$label'"}my$value=$self->value;if ($value eq ''){$value='U'}my$out=sprintf "%s=%s%s;%s;%s;%s;%s",$label,$value,$self->_nvl($self->uom),$self->_nvl($self->warning),$self->_nvl($self->critical),$self->_nvl($self->min),$self->_nvl($self->max);$out =~ s/;;$//;return$out}sub parse_perfstring {my ($class,$perfstring)=@_;my@perfs=();my$obj;while ($perfstring){$perfstring =~ s/^\s*//;if (@{[$perfstring =~ /=/g]}> 1){$perfstring =~ s/^(.*?=.*?)\s//;if (defined $1){$obj=$class->_parse($1)}else {$perfstring="";$obj=$class->_parse($perfstring)}}else {$obj=$class->_parse($perfstring);$perfstring=""}push@perfs,$obj if$obj}return@perfs}sub rrdlabel {my$self=shift;my$name=$self->clean_label;return substr($name,0,19)}sub clean_label {my$self=shift;my$name=$self->label;if ($name eq "/"){$name="root"}elsif ($name =~ s/^\///){$name =~ s/\//_/g}$name =~ s/\W/_/g;return$name}sub threshold {my$self=shift;return Monitoring::Plugin::Threshold->set_thresholds(warning=>$self->warning,critical=>$self->critical)}sub new {my$class=shift;my%arg=@_;if (my$threshold=delete$arg{threshold}){$arg{warning}||= $threshold->warning ."";$arg{critical}||= $threshold->critical .""}$class->SUPER::new(\%arg)}1;
MONITORING_PLUGIN_PERFORMANCE
$fatpacked{"Monitoring/Plugin/Range.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MONITORING_PLUGIN_RANGE';
@@ -6227,7 +6403,7 @@
PARAMS_VALIDATEXS
$fatpacked{"Try/Tiny.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'TRY_TINY';
- package Try::Tiny;use 5.006;our$VERSION='0.28';use strict;use warnings;use Exporter 5.57 'import';our@EXPORT=our@EXPORT_OK=qw(try catch finally);use Carp;$Carp::Internal{+__PACKAGE__}++;BEGIN {my$su=$INC{'Sub/Util.pm'}&& defined&Sub::Util::set_subname;my$sn=$INC{'Sub/Name.pm'}&& eval {Sub::Name->VERSION(0.08)};unless ($su || $sn){$su=eval {require Sub::Util}&& defined&Sub::Util::set_subname;unless ($su){$sn=eval {require Sub::Name;Sub::Name->VERSION(0.08)}}}*_subname=$su ? \&Sub::Util::set_subname : $sn ? \&Sub::Name::subname : sub {$_[1]};*_HAS_SUBNAME=($su || $sn)? sub(){1}: sub(){0}}my%_finally_guards;sub try (&;@) {my ($try,@code_refs)=@_;my$wantarray=wantarray;my ($catch,@finally)=();for my$code_ref (@code_refs){if (ref($code_ref)eq 'Try::Tiny::Catch'){croak 'A try() may not be followed by multiple catch() blocks' if$catch;$catch=${$code_ref}}elsif (ref($code_ref)eq 'Try::Tiny::Finally'){push@finally,${$code_ref}}else {croak('try() encountered an unexpected argument (' .(defined$code_ref ? $code_ref : 'undef').') - perhaps a missing semi-colon before or')}}my$caller=caller;_subname("${caller}::try {...} "=>$try)if _HAS_SUBNAME;local$_finally_guards{guards}=[map {Try::Tiny::ScopeGuard->_new($_)}@finally ];my$prev_error=$@;my (@ret,$error);my$failed=not eval {$@=$prev_error;if ($wantarray){@ret=$try->()}elsif (defined$wantarray){$ret[0]=$try->()}else {$try->()};return 1};$error=$@;$@=$prev_error;if ($failed){push @$_,$error for @{$_finally_guards{guards}};if ($catch){for ($error){return$catch->($error)}}return}else {return$wantarray ? @ret : $ret[0]}}sub catch (&;@) {my ($block,@rest)=@_;croak 'Useless bare catch()' unless wantarray;my$caller=caller;_subname("${caller}::catch {...} "=>$block)if _HAS_SUBNAME;return (bless(\$block,'Try::Tiny::Catch'),@rest,)}sub finally (&;@) {my ($block,@rest)=@_;croak 'Useless bare finally()' unless wantarray;my$caller=caller;_subname("${caller}::finally {...} "=>$block)if _HAS_SUBNAME;return (bless(\$block,'Try::Tiny::Finally'),@rest,)}{package Try::Tiny::ScopeGuard;use constant UNSTABLE_DOLLARAT=>("$]" < '5.013002')? 1 : 0;sub _new {shift;bless [@_ ]}sub DESTROY {my ($code,@args)=@{$_[0]};local $@ if UNSTABLE_DOLLARAT;eval {$code->(@args);1}or do {warn "Execution of finally() block $code resulted in an exception, which " .'*CAN NOT BE PROPAGATED* due to fundamental limitations of Perl. ' .'Your program will continue as if this event never took place. ' ."Original exception text follows:\n\n" .(defined $@ ? $@ : '$@ left undefined...')."\n" }}}__PACKAGE__
+ package Try::Tiny;use 5.006;our$VERSION='0.30';use strict;use warnings;use Exporter 5.57 'import';our@EXPORT=our@EXPORT_OK=qw(try catch finally);use Carp;$Carp::Internal{+__PACKAGE__}++;BEGIN {my$su=$INC{'Sub/Util.pm'}&& defined&Sub::Util::set_subname;my$sn=$INC{'Sub/Name.pm'}&& eval {Sub::Name->VERSION(0.08)};unless ($su || $sn){$su=eval {require Sub::Util}&& defined&Sub::Util::set_subname;unless ($su){$sn=eval {require Sub::Name;Sub::Name->VERSION(0.08)}}}*_subname=$su ? \&Sub::Util::set_subname : $sn ? \&Sub::Name::subname : sub {$_[1]};*_HAS_SUBNAME=($su || $sn)? sub(){1}: sub(){0}}my%_finally_guards;sub try (&;@) {my ($try,@code_refs)=@_;my$wantarray=wantarray;my ($catch,@finally)=();for my$code_ref (@code_refs){if (ref($code_ref)eq 'Try::Tiny::Catch'){croak 'A try() may not be followed by multiple catch() blocks' if$catch;$catch=${$code_ref}}elsif (ref($code_ref)eq 'Try::Tiny::Finally'){push@finally,${$code_ref}}else {croak('try() encountered an unexpected argument (' .(defined$code_ref ? $code_ref : 'undef').') - perhaps a missing semi-colon before or')}}_subname(caller().'::try {...} '=>$try)if _HAS_SUBNAME;local$_finally_guards{guards}=[map {Try::Tiny::ScopeGuard->_new($_)}@finally ];my$prev_error=$@;my (@ret,$error);my$failed=not eval {$@=$prev_error;if ($wantarray){@ret=$try->()}elsif (defined$wantarray){$ret[0]=$try->()}else {$try->()};return 1};$error=$@;$@=$prev_error;if ($failed){push @$_,$error for @{$_finally_guards{guards}};if ($catch){for ($error){return$catch->($error)}}return}else {return$wantarray ? @ret : $ret[0]}}sub catch (&;@) {my ($block,@rest)=@_;croak 'Useless bare catch()' unless wantarray;_subname(caller().'::catch {...} '=>$block)if _HAS_SUBNAME;return (bless(\$block,'Try::Tiny::Catch'),@rest,)}sub finally (&;@) {my ($block,@rest)=@_;croak 'Useless bare finally()' unless wantarray;_subname(caller().'::finally {...} '=>$block)if _HAS_SUBNAME;return (bless(\$block,'Try::Tiny::Finally'),@rest,)}{package Try::Tiny::ScopeGuard;use constant UNSTABLE_DOLLARAT=>("$]" < '5.013002')? 1 : 0;sub _new {shift;bless [@_ ]}sub DESTROY {my ($code,@args)=@{$_[0]};local $@ if UNSTABLE_DOLLARAT;eval {$code->(@args);1}or do {warn "Execution of finally() block $code resulted in an exception, which " .'*CAN NOT BE PROPAGATED* due to fundamental limitations of Perl. ' .'Your program will continue as if this event never took place. ' ."Original exception text follows:\n\n" .(defined $@ ? $@ : '$@ left undefined...')."\n" }}}__PACKAGE__
TRY_TINY
s/^ //mg for values %fatpacked;
@@ -6282,7 +6458,7 @@
use strict;
my $PROGNAME = 'check_raid';
-my $VERSION = q/4.0.8/;
+my $VERSION = q/4.0.9/;
my $URL = 'https://github.com/glensc/nagios-plugin-check_raid';
my $BUGS_URL = 'https://github.com/glensc/nagios-plugin-check_raid#reporting-bugs';
diff -Nru nagios-plugins-contrib-22.20181105+1/check_raid/control nagios-plugins-contrib-23.20190206/check_raid/control
--- nagios-plugins-contrib-22.20181105+1/check_raid/control 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_raid/control 2019-02-06 12:45:06.000000000 +0000
@@ -1,12 +1,11 @@
Homepage: https://github.com/glensc/nagios-plugin-check_raid
Watch: https://github.com/glensc/nagios-plugin-check_raid "/glensc/nagios-plugin-check_raid/tree/([0-9.]+)"
Suggests: cciss-vol-status (>= 1.10), mpt-status
-Version: 4.0.8
+Version: 4.0.9
Uploaders: Bernd Zeimetz
Description: plugin to check sw/hw RAID status
The plugin looks for any known types of RAID configurations,
and checks them all.
- .
Supports:
- Adaptec AAC RAID via aaccli or afacli or arcconf
- AIX software RAID via lsvg
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/AUTHORS nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/AUTHORS
--- nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/AUTHORS 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/AUTHORS 1970-01-01 00:00:00.000000000 +0000
@@ -1,75 +0,0 @@
-Matteo Corti
-
-Thanks:
-
-* Many thanks to Kenny McCormack for his help on comp.unix.shell on
- how to implement a timeout
-* Many thanks to Dan Wallis for several patches and fixes
- (see the Changelog)
-* Many thanks to Tuomas Haarala for the -P option patch to
- check TLS certs using other protocols
-* Many thanks to Marcus Rejås for the -N and -n patches
-* Many thanks to Marc Fournier for
- - the == bashism fix
- - the mktemp error handling patch
-* Many thanks to Wolfgang Schricker for
- - the selfsigned bug report and cleanup fixes
- - the patch adding the possibility to check local files (-f option)
-* Many thanks to Yannick Gravel for the patch fixing the plugin output
- and the fix on the test order
-* Many thanks to Scott Worthington for the --critical and --warning hints
-* Many thanks to Lawren Quigley-Jones for
- - the -A,--noauth patch
- - the trap fix
-* Many thanks to Matthias Fuhrmeister for the -servername patch
-* Many thanks to Raphael Thoma for the patch allowing HTTP to be
- specified as protocol and the fix on -N with wildcards
-* Many thanks to Sven Nierlein for the client certificate authentication patch
-* Many thanks to Rob Yamry for the help in debugging a problem with
- certain versions of OpenSSL and TLS extensions
-* Many thanks to Jim Hopp for the "No certificate returned" enhancement patch
-* Many thanks to Javier Gonel for the TLS servername patch
-* Many thanks to Christian Ruppert for the XMPP patch
-* Many thanks to Robin H. Johnson for the 'timeout' patch
-* Many thanks to Max Winterstein for the SSL version patch
-* Many thanks to Colin Smith for the RPM build Makefile patch
-* Many thanks to Andreas Dijkman for the RPM dependencies patch
-* Many thanks to Lawren Quigley-Jones for the common name patch
-* Many thanks to Ryan Nowakowski for the OCSP patch
-* Many thanks to Jérémy Lecour for the review and corrections
-* Many thanks to Mark Ruys for the OCSP patch
-* Many thanks to Milan Koudelka for the serial number patch
-* Many thanks to Konstantin Shalygin for the UTF-8 patch
-* Many thanks to Sam Richards for the SNI patch
-* Many thanks to Sergei Shmanko (https://github.com/sshmanko) for the wildcard
- certificate patch
-* Many thanks to juckerf (https://github.com/juckerf) for patch to increase
- control over which SSL/TLS versions to use
-* Many thanks to Rolf Eike Beer for the IRC and SMTP check patch
-* Many thanks to Viktor Szépe for the formatting and style patches
-* Many thanks to Philippe Kueck for the CN patch
-* Many thanks to Ricardo (https://github.com/bb-Ricardo) and xert (https://github.com/xert) for the date timestamp patch
-* Many thanks to xert for the SSLLabs patch
-* Many thanks to Leynos (https://github.com/leynos) for the OCSP proxy patch
-* Many thanks to Philippe Kueck for the selection of the cipher authentication
-* Many thanks to Jalonet (https://github.com/jalonet) for the file/PEM patch
-* Many thanks to Sander Cornelissen (https://github.com/scornelissen85) for the multiple CNs patch
-* Many thanks to Pavel Rochnyak (https://github.com/rpv-tomsk) for the issuer certificate cache patch and
- the wildcard support in alternative names
-* Many thanks to Vamp898 (https://github.com/Vamp898) for the LDAP patch
-* Many thanks to Emilian Ertel for the curl and date patches
-* Many thanks to Kosta Velikov for the grep patch
-* Many thanks to Vojtech Horky for the OpenSSL 1.1 patch
-* Many thanks to Nicolas Lafont (https://github.com/ManicoW) for the Common Name fix
-* Many thanks to d7415 (https://github.com/d7415) for the -help patch
-* Many thanks to Łukasz Wąsikowski (https://github.com/IdahoPL) for the curl and date display patches
-* Many thanks to booboo-at-gluga-de (https://github.com/booboo-at-gluga-de) for the CRL patch
-* Many thanks to Georg (https://github.com/gbotti) for the fingerprint patch
-* Many thanks to Wim van Ravesteijn (https://github.com/wimvr) for the DER encoded CRL files patch
-* Many thanks to yasirathackersdotmu (https://github.com/yasirathackersdotmu)
-* Many thanks to Christoph Moench-Tegeder (https://github.com/moench-tegeder) for the curl patch
-* Many thanks to Dan Pritts for the --terse patch
-* Many thanks to eeertel (https://github.com/eeertel) for the SNI warning patch
-* Many thanks to Vojtech Horky (https://github.com/vhotspur) for the --format patch
-* Many thanks to Markus Frosch (https://github.com/lazyfrosch) for the cleanup patch
-* Many thanks to Ricardo Bartels (https://github.com/bb-Ricardo) for the patches fixing unit tests, long output on Linux, extending the issuer checks to the whole chain
\ No newline at end of file
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/ChangeLog nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/ChangeLog
--- nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/ChangeLog 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/ChangeLog 1970-01-01 00:00:00.000000000 +0000
@@ -1,534 +0,0 @@
-2018-08-10 Matteo Corti
-
- * check_ssl_cert: disabling OCSP checks if no OCSP host is found
-
-2018-07-20 Matteo Corti
-
- * check_ssl_cert: Applied a patch from Markus Frosch to fix the cleanup of temporary files
-
-2018-07-01 Matteo Corti
-
- * check_ssl_cert: do not trap on EXIT
- * check_ssl_cert: remove temporary file when no signals are trapped
-
-2018-06-28 Matteo Corti
-
- * check_ssl_cert: fixed a bug in the deletion of temporary files when a signal is caught
-
-2018-06-25 Matteo Corti
-
- * check_ssl_cert: added a check to require OCSP stapling
-
-2018-04-29 Matteo Corti
-
- * check_ssl_cert: Remooved the SNI name check patch (see #78)
-
-2018-04-19 Matteo Corti
-
- * check_ssl_cert: Merged the SNI name check patch
-
-2018-04-17 Matteo Corti
-
- * check_ssl_cert: Merged the --terse patch, added performance data to the terse output and reordered the help
-
-2018-04-12 Matteo Corti
-
- * Makefile: Checks if the copyright year is correct. make test is now dependent on make dist
-
-2018-04-06 Matteo Corti
-
- * check_ssl_cert: Added UTF8 output
-
-2018-04-05 Matteo Corti
-
- * check_ssl_cert: Added debugging output for cURL
-
-2018-03-29 Matteo Corti
-
- * check_ssl_cert: Fixed a bug introduced in the last verstion
-
-2018-03-28 Matteo Corti
-
- * check_ssl_cert: Removed cURL dependency when not checking SSL Labs
-
-2018-03-17 Matteo Corti
-
- * check_ssl_cert: Added support for TLS 1.3
-
-2018-03-06 Matteo Corti
-
- * check_ssl_cert: Fixed OCSP check with LibreSSL
- * check_ssl_cert: Lists the number or default root certificates in debug mode
-
-2018-01-19 Matteo Corti
-
- * check_ssl_cert: Fixed a bug processing more than one OCSP host
-
-2017-12-15 Matteo Corti
-
- * check_ssl_cert: Fixed a bug in the specification of the xmpphost parameter
-
-2017-12-14 Matteo Corti
-
- * check_ssl_cert: Added an option to specify the 'to' attribute of the XMPP stream element
-
-2017-11-29 Wim van Ravesteijn https://github.com/wimvr
-
- * check_ssl_cert: Support for DER encoded CRL files
-
-2017-11-28 Georg https://github.com/gbotti
-
- * check_ssl_cert: added --fingerprint to check the SHA1 fingerprint of the certificate
-
-2017-11-17 Matteo Corti
-
- * check_ssl_cert (fetch_certificate): adding support for -xmpphost if available
-
-2017-11-16 Matteo Corti
-
- * check_ssl_cert (fetch_certificate): fixing XMPP support
-
-2017-11-16
-
- * check_ssl_cert (fetch_certificate): adding support for IPv6 addresses
-
-2017-09-18 Bernd Stroessenreuther
-
- * check_ssl_cert: with -f option you now can also pass a certificate revocation list (CRL) to check its validity period
-
-2017-09-10 Matteo Corti
-
- * check_ssl_cert: OCSP check is now terminated by a timeout
-
-2017-09-09 Matteo Corti
-
- * check_ssl_cert: The SAN requirement is now optional
-
-2017-07-28 Matteo Corti
-
- * check_ssl_cert: Use openssl s_client's -help option to test for SNI support (thanks to d7415)
-
-2017-07-24 Matteo Corti
-
- * check_ssl_cert: Fix in the Common Name parsing
-
-2017-06-23 Matteo Corti
-
- * check_ssl_cert: Checks for missing subjectAlternativeName extension
-
-2017-06-15 Matteo Corti
-
- * check_ssl_cert: Do not try to check OCSP if the protocol is not HTTP or HTTPS
-
-2017-05-15 Matteo Corti
-
- * check_ssl_cert: Fixed a problem with the detection of OCSP URLs
-
-2017-05-02 Matteo Corti
-
- * check_ssl_cert: Added --location to curl to follow redirects
- * check_ssl_cert: Fixed the indentation of EOF in the embedded Perl script
- * check_ssl_cert: Added --force-date-perl to force the usage of Perl for date computations and a test to be sure no errors in Perl are left undetected
-
-2017-04-28 Matteo Corti
-
- * check_ssl_cert: Fixed a bug occurring when more than one issuNer URI is present
-
-2017-03-07 Matteo Corti
-
- * check_ssl_cert: Added LDAP support
-
-2017-03-01 Matteo Corti
-
- * check_ssl_cert: By errors it makes more sense to show the supplied host instead of the CN
-
-2017-02-16 Matteo Corti
-
- * check_ssl_cert: Support for newer OpenSSL versions (1.1)
-
-2017-02-10 Matteo Corti
-
- * check_ssl_cert: Added the --sni option
-
-2017-02-08 Matteo Corti
-
- * check_ssl_cert: Patch from Pavel Rochnyak: Changed the CN output when --altnames is used
-
-2017-02-02 Matteo Corti
-
- * check_ssl_cert: Fixed the command line argument parsing
- * check_ssl_cert: Fixed -servername
-
-2017-01-29 Matteo Corti
-
- * check_ssl_cert: Added patches from Pavel Rochnyak for the issuer certificate cache patch
- and the wildcard support in alternative names
-
-2016-12-23 Matteo Corti
-
- * check_ssl_cert: Added patch to specify multiple CNs (see https://github.com/matteocorti/check_ssl_cert/pull/35)
-
-2016-12-13 Matteo Corti
-
- * check_ssl_cert: fixed a minor problem with --debug
-
-2016-12-06 Matteo Corti
-
- * check_ssl_cert: fixed a problem when specifying a CN beginnging with *
-
-2016-12-04 Matteo Corti
-
- * check_ssl_cert: fixed problem when file is returing PEM certificate on newer Linux distributions
-
-2016-09-19 Matteo Corti
-
- * check_ssl_cert: enabling proxy support in the OCSP check (thanks to Leynos)
-
-2016-08-04 Matteo Corti
-
- * check_ssl_cert: disabling OCSP checks when no issuer URI is found
-
-2016-07-29 Matteo Corti
-
- * check_ssl_cert: fixed case insensitive comparison of CNs
-
-2016-07-29 https://github.com/bb-Ricardo
-
- * check_ssl_cert: calculate expiration primary with date
-
-2016-07-12 Matteo Corti
-
- * check_ssl_cert: fixed the parsing of the CN field
-
-2016-06-25 Matteo Corti
-
- * check_ssl_cert: fixed OSCP header on old OpenSSL versions
-
-2016-06-24 Matteo Corti
-
- * check_ssl_cert: OCSP is now default
-
- * check_ssl_certe: Fixed OCSP host
-
-2016-06-15 Matteo Corti
-
- * check_ssl_cert: Better curl error handling
-
-2016-06-10 Matteo Corti
-
- * check_ssl_cert: Added an option to clear the cached result at SSLLabs
-
-2016-06-01 juckerf (https://github.com/juckerf)
-
- * check_ssl_cert: Increase control over which SSL/TLS versions to use
-
-2016-05-17 Matteo Corti
-
- * check_ssl_cert: added more debugging info (-v is automatic if -d is spefied, system info and cert written to a file)
-
-2016-04-27 Matteo Corti
-
- * check_ssl_cert: Fixes a bug in the OpenSSL error parsing
-
-2016-04-05 Matteo Corti
-
- * check_ssl_cert: In case of an s_client error does not output the full (ugly) error. The error is shown in verbose mode
-
-2016-03-29 Sergei Shmanko
-
- * check_ssl_cert: Fix wildcard match regex, add additional unit tests
-
-2016-03-21 Matteo Corti
-
- * check_ssl_cert (exec_with_timeout): issues a critical status
- when using the 'timout' utility
-
-2016-03-19 Matteo Corti
-
- * check_ssl_cert: fixed CN parsing on non-GNU systems
-
-2016-03-19 Sergei https://github.com/sshmanko
-
- * check_ssl_cert: handle wildcard certificates
-
-2016-03-10 Matteo Corti
-
- * check_ssl_cert (check_attr): Better handling of verification errors
-
-2016-03-09 Matteo Corti
-
- * check_ssl_cert (convert_ssl_lab_grade): accepts lowercase letters for SSL Labs grades
- * check_ssl_cert (check_attr): waits for SSL Labs results
-
-2016-03-08 Matteo Corti
-
- * check_ssl_cert: Tries to extract an error message from SSL Labs
- if no status is returned
-
-2016-03-07 Sam Richards
- * check_ssl_cert: Support SNI even when we don't want to check cn
-
-2016-03-07 Matteo Corti
-
- * check_ssl_cert: DNS errors by SSL Labs are ignored (as they are just
- a sign that the result is not cached)
-
-2016-03-03 Matteo Corti
-
- * check_ssl_cert: Initial support for SSL Labs checks
-
-2016-03-01 Matteo Corti
-
- * check_ssl_cert: Fixed a bug which prevented the check on the expiration
-
-2015-10-31 Matteo Corti
-
- * check_ssl_cert: added a patch to check the certificate's serial number
- (thanks to Milan Koudelka)
-
-2015-10-20 Matteo Corti
-
- * check_ssl_cert: fixex a problem with OCSP paths w/o URLs
-
-2015-04-07 Matteo Corti
-
- * check_ssl_cert: corrected some typos (thanks to Jérémy Lecour)
- * check_ssl_cert: removed check on the openssl binary name
-
-2014-10-21 Matteo Corti
-
- * check_ssl_cert: added a patch to check revocation via OCSP (thanks
- to Ryan Nowakowski)
-
-2014-02-28 Matteo Corti
-
- * Makefile: added a target to build an rpm
-
-2013-12-23 Matteo Corti
-
- * check_ssl_cert: added the --tls1 option to force TLS 1
-
-2013-10-09 Matteo Corti
-
- * check_ssl_cert: whole script reviewed with shellcheck
-
-2013-10-01 Matteo Corti
-
- * check_ssl_cert: fixes with shellcheck (quoting)
-
-2013-07-29 Matteo Corti
-
- * check_ssl_cert: Added an option to force a given SSL version
-
-2013-03-02 Matteo Corti
-
- * check_ssl_cert: Fixed a bug occuring with TLS and multiple names in
- the certificate
-
-2012-12-07 Matteo Corti
-
- * check_ssl_cert: removed "test -a/-o" (test has an undefined
- behavior with more than 4 elements)
-
- * check_ssl_cert: fixed #122 (-N was always comparing the CN with 'localhost')
-
-2012-11-16 Matteo Corti
-
- * simplified the sourcing of the script file for testing
-
-2012-10-11 Matteo Corti
-
- * added some unit tests with shUnit2
-
-2012-09-19 Matteo Corti
-
- * check_ssl_cert: improved the "No certificate returned" error message
-
-2012-07-13 Matteo Corti
-
- * check_ssl_cert: added the number of days from or to expiration in the
- plugin output
-
-2012-07-11 Matteo Corti
-
- * check_ssl_cert: fixed a bug with Perl date computation on some systems
-
-2012-07-06 Matteo Corti
-
- * check_ssl_cert: performance data in days
- * check_ssl_cert: long output (certificate attributes)
-
-2012-04-05 Matteo Corti
-
- * check_ssl_cert: handle broken OpenSSL clients (-servername not working)
-
-2012-04-04 Matteo Corti
-
- * check_ssl_cert: removed an hard coded reference to the error number by the
- SSL chain verification
-
-2011-10-22 Matteo Corti
-
- * check_ssl_cert: added a --altnames option to match the CN to alternative
- names
-
-2011-09-01 Matteo Corti
-
- * check_ssl_cert: applied a patch from Sven Nierlein
- (certificate authentication)
-
-2011-03-10 Matteo Corti
-
- * check_ssl_cert: allows http to specified as protocol
- (thanks to Raphael Thoma)
- * check_ssl_cert: fixes the -N check for certs with wildcards
- (thanks to Raphael Thoma)
-
-2011-01-24 Matteo Corti
-
- * check_ssl_cert: added an option to specify the openssl executable
-
-2010-12-16 Dan Wallis
-
- * check_ssl_cert: Sets $VERBOSE to avoid using value supplied by Nagios
- * check_ssl_cert: Quotes regular expression for grep to avoid shell globbing
-
-2010-12-09 Matteo Corti
-
- * check_ssl_cert.spec: standardized the RPM package name
-
- * check_ssl_cert: added support for the TLS servername extension
- (thanks to Matthias Fuhrmeister)
-
-2010-11-02 Matteo Corti
-
- * INSTALL: specifies that expect is needed for timeouts
-
-2010-10-29 Matteo Corti
-
- * README: specifies that expect is needed for timeouts
-
-2010-10-28 Matteo Corti
-
- * check_ssl_cert: trap on more signals (thanks to Lawren Quigley-Jones)
-
-2010-10-14 Matteo Corti
-
- * check_ssl_cert: added a patch from Yannick Gravel putting the
- chain verification at the end of the tests
-
-2010-10-01 Matteo Corti
-
- * check_ssl_cert: added a patch from Lawren Quigley-Jones which
- implements a new command line argument (-A) to disable the
- certificate chain check
-
-2010-09-15 Matteo Corti
-
- * check_ssl_cert: fixed option processing (bug #78)
-
-2010-08-26 Dan Wallis
-
- * check_ssl_cert: overloads --rootcert for use with directories as
- well as files (-CApath versus -CAfile)
-
-2010-07-21 Matteo Corti
-
- * check_ssl_cert: added a patch from Marc Fournier to check the creation of the temporary files
- * check_ssl_cert: added the --temp option to specify where to store the temporary files
-
-2010-07-10 Matteo Corti
-
- * check_ssl_cert: improved the error messages
- * check_ssl_cert: checks for certificates without email addresses (if -e is specified)
-
-2010-07-09 Matteo Corti
-
- * check_ssl_cert: added a "long" version for all the command line options
- * check_ssl_cert: added a critical and warning option for the certificate validity (in days)
- * check_ssl_cert: the plugin always issues a critical warning if the certificate is expired
- * check_ssl_cert: added a man page
-
-2010-07-07 Matteo Corti
-
- * check_ssl_cert: [Wolfgang Schricker patch] Add -f to check local files
-
-2010-07-01 Matteo Corti
-
- * check_ssl_cert: [Yannick Gravel patch] Restore displaying the CN in every messages:
- a previous patch changed something and only
- critical were adjusted.
- * check_ssl_cert: [Yannick Gravel patch] Adjust what is displayed after the from in
- the OK message to display the matched ISSUER
- (CN or O).
-
-2010-06-08 Matteo Corti
-
- * check_ssl_cert: added the -s option to allow self signed certificates
-
-2010-03-11 Matteo Corti
-
- * check_ssl_cert: fixed the == bashism
-
-2010-03-08 Matteo Corti
-
- * check_ssl_cert: applied patch from Marcus Rejås with the -n and -N options
-
-2009-12-02 Matteo Corti
-
- * check_ssl_cert: check if the issuer matches the O= or the CN= field of the Root Cert
-
-2009-11-30 Matteo Corti
-
- * check_ssl_cert: cleaned up error messages if the CN is not yet known
- * check_ssl_cert: added certificate chain verification
- * check_ssl_cert: allow backslashes escaped in the error messages (e.g., for \n used by Nagios 3)
- * check_ssl_cert: -r can be used to specify a root certificate to be used for the verification
-
-2009-03-31 Matteo Corti
-
- * check_ssl_cert: standard timeout of 15 seconds (can be set with the -t option)
-
-2009-03-30 Matteo Corti
-
- * check_ssl_cert: -P option to specify the protocol
-
-2008-05-13 Matteo Corti
-
- * check_ssl_cert: applied a patch from Dan Wallis to output the CN
- in all the messages
-
-2008-02-28 Matteo Corti
-
- * check_ssl_cert: shortened the error message in case of no connection
- (only the first line is reported)
-
-2008-02-25 Matteo Corti
-
- * check_ssl_cert: [Dan Wallis patch] removed nmap dependency
- * check_ssl_cert: [Dan Wallis patch] mktemp for the temporaries
- * check_ssl_cert: [Dan Wallis patch] using trap to cleanup temporaries
- * check_ssl_cert: [Dan Wallis patch] POSIX compliance and cleanup
- * check_ssl_cert: [Dan Wallis patch] POSIX compliance and cleanup
- * check_ssl_cert: [Dan Wallis patch] better handling of missing
- certificate and non resolvable host
- * check_ssl_cert: [Dan Wallis patch] stricter check for "notAfter" in the
- certificate analysis
-
-2007-09-04 Matteo Corti
-
- * check_ssl_cert: better error messages (both the actual and the
- expected values are displayed)
-
-2007-08-31 Matteo Corti
-
- * check_ssl_cert: new options to enforce email and
- organization. Temporary files are now removed before termination
-
-2007-08-15 Matteo Corti
-
- * check_ssl_cert: openssl s_client closes the connection cleanly
-
-2007-08-10 Matteo Corti
-
- * check_ssl_cert: initial release
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert
--- nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert 1970-01-01 00:00:00.000000000 +0000
@@ -1,2308 +0,0 @@
-#!/bin/sh
-#
-# check_ssl_cert
-#
-# Checks an X.509 certificate:
-# - checks if the server is running and delivers a valid certificate
-# - checks if the CA matches a given pattern
-# - checks the validity
-#
-# See the INSTALL file for installation instructions
-#
-# Copyright (c) 2007-2012 ETH Zurich.
-# Copyright (c) 2007-2018 Matteo Corti
-#
-# This module is free software; you can redistribute it and/or modify it
-# under the terms of GNU general public license (gpl) version 3.
-# See the LICENSE file for details.
-
-################################################################################
-# Constants
-
-VERSION=1.73.0
-SHORTNAME="SSL_CERT"
-
-VALID_ATTRIBUTES=",startdate,enddate,subject,issuer,serial,modulus,serial,hash,email,ocsp_uri,fingerprint,"
-
-SIGNALS="HUP INT QUIT TERM ABRT"
-
-# return value for the creation of temporary files
-TEMPFILE=""
-
-################################################################################
-# Functions
-
-################################################################################
-# Prints usage information
-# Params
-# $1 error message (optional)
-usage() {
-
- if [ -n "$1" ] ; then
- echo "Error: $1" 1>&2
- fi
-
- #### The following line is 80 characters long (helps to fit the help text in a standard terminal)
- ######--------------------------------------------------------------------------------
-
- echo
- echo "Usage: check_ssl_cert -H host [OPTIONS]"
- echo
- echo "Arguments:"
- echo " -H,--host host server"
- echo
- echo "Options:"
- echo " -A,--noauth ignore authority warnings (expiration only)"
- echo " --altnames matches the pattern specified in -n with alternate"
- echo " names too"
- echo " -C,--clientcert path use client certificate to authenticate"
- echo " --clientpass phrase set passphrase for client certificate."
- echo " -c,--critical days minimum number of days a certificate has to be valid"
- echo " to issue a critical status"
- echo " --curl-bin path path of the curl binary to be used"
- echo " -d,--debug produces debugging output"
- echo " --ecdsa cipher selection: force ECDSA authentication"
- echo " -e,--email address pattern to match the email address contained in the"
- echo " certificate"
- echo " -f,--file file local file path (works with -H localhost only)"
- echo " with -f you can not only pass a x509 certificate file"
- echo " but also a certificate revocation list (CRL) to check"
- echo " the validity period"
- echo " --file-bin path path of the file binary to be used"
- echo " --fingerprint SHA1 pattern to match the SHA1-Fingerprint"
- echo " --force-perl-date force the usage of Perl for date computations"
- echo " --format FORMAT format output template on success, for example"
- echo " \"%SHORTNAME% OK %CN% from '%CA_ISSUER_MATCHED%'\""
- echo " -h,--help,-? this help message"
- echo " --ignore-exp ignore expiration date"
- echo " --ignore-ocsp do not check revocation with OCSP"
- echo " --ignore-sig-alg do not check if the certificate was signed with SHA1"
- echo " or MD5"
- echo " --ignore-ssl-labs-cache Forces a new check by SSL Labs (see -L)"
- echo " -i,--issuer issuer pattern to match the issuer of the certificate"
- echo " --issuer-cert-cache dir directory where to store issuer certificates cache"
- echo " -L,--check-ssl-labs grade SSL Labs assessment"
- echo " (please check https://www.ssllabs.com/about/terms.html)"
- echo " --long-output list append the specified comma separated (no spaces) list"
- echo " of attributes to the plugin output on additional lines"
- echo " Valid attributes are:"
- echo " enddate, startdate, subject, issuer, modulus,"
- echo " serial, hash, email, ocsp_uri and fingerprint."
- echo " 'all' will include all the available attributes."
- echo " -n,--cn name pattern to match the CN of the certificate (can be"
- echo " specified multiple times)"
- echo " --no_ssl2 disable SSL version 2"
- echo " --no_ssl3 disable SSL version 3"
- echo " --no_tls1 disable TLS version 1"
- echo " --no_tls1_1 disable TLS version 1.1"
- echo " --no_tls1_2 disable TLS version 1.2"
- echo " -N,--host-cn match CN with the host name"
- echo " -o,--org org pattern to match the organization of the certificate"
- echo " --openssl path path of the openssl binary to be used"
- echo " -p,--port port TCP port"
- echo " -P,--protocol protocol use the specific protocol"
- echo " {http|smtp|pop3|imap|ftp|xmpp|irc|ldap}"
- echo " http: default"
- echo " smtp,pop3,imap,ftp,ldap: switch to TLS"
- echo " -s,--selfsigned allows self-signed certificates"
- echo " --serial serialnum pattern to match the serial number"
- echo " --sni name sets the TLS SNI (Server Name Indication) extension"
- echo " in the ClientHello message to 'name'"
- echo " --ssl2 forces SSL version 2"
- echo " --ssl3 forces SSL version 3"
- echo " --require-ocsp-stapling require OCSP stapling"
- echo " --require-san require the presence of a Subject Alternative Name"
- echo " extension"
- echo " -r,--rootcert path root certificate or directory to be used for"
- echo " certificate validation"
- echo " --rsa cipher selection: force RSA authentication"
- echo " --temp dir directory where to store the temporary files"
- echo " --terse terse output"
- echo " -t,--timeout seconds timeout after the specified time"
- echo " (defaults to 15 seconds)"
- echo " --tls1 force TLS version 1"
- echo " --tls1_1 force TLS version 1.1"
- echo " --tls1_2 force TLS version 1.2"
- echo " --tls1_3 force TLS version 1.3"
- echo " -v,--verbose verbose output"
- echo " -V,--version version"
- echo " -w,--warning days minimum number of days a certificate has to be valid"
- echo " to issue a warning status"
- echo " --xmpphost name specifies the host for the 'to' attribute of the stream element"
- echo
- echo "Deprecated options:"
- echo " --days days minimum number of days a certificate has to be valid"
- echo " (see --critical and --warning)"
- echo " --ocsp check revocation via OCSP"
- echo " -S,--ssl version force SSL version (2,3)"
- echo " (see: --ssl2 or --ssl3)"
- echo
- echo "Report bugs to https://github.com/matteocorti/check_ssl_cert/issues"
- echo
-
- exit 3
-
-}
-
-################################################################################
-# trap passing the signal name
-# see https://stackoverflow.com/questions/2175647/is-it-possible-to-detect-which-trap-signal-in-bash/2175751#2175751
-trap_with_arg() {
- func="$1" ; shift
- for sig ; do
- # shellcheck disable=SC2064
- trap "$func $sig" "$sig"
- done
-}
-
-################################################################################
-# Cleanup temporary files
-remove_temporary_files() {
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] cleaning up temporary files"
- # shellcheck disable=SC2086
- echo $TEMPORARY_FILES | tr '\ ' '\n' | sed 's/^/[DBG] /'
- fi
- # shellcheck disable=SC2086
- if [ -n "$TEMPORARY_FILES" ]; then
- rm -f $TEMPORARY_FILES
- fi
-}
-
-################################################################################
-# Cleanup when exiting
-cleanup() {
- SIGNAL=$1
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] signal caught $SIGNAL"
- fi
- remove_temporary_files
- # shellcheck disable=SC2086
- trap - $SIGNALS
- exit
-}
-
-create_temporary_file() {
-
- # create a temporary file
- TEMPFILE="$( mktemp -t "${0##*/}XXXXXX" 2> /dev/null )"
- if [ -z "${TEMPFILE}" ] || [ ! -w "${TEMPFILE}" ] ; then
- unknown 'temporary file creation failure.'
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] temporary file $TEMPFILE created"
- fi
-
- # add the file to the list of temporary files
- TEMPORARY_FILES="$TEMPORARY_FILES $TEMPFILE"
-
-}
-
-################################################################################
-# Exits with a critical message
-# Params
-# $1 error message
-critical() {
- if [ -n "${HOST}" ] ; then
- tmp=" ${HOST}"
- fi
- remove_temporary_files
- printf '%s CRITICAL%s: %s%s%s\n' "${SHORTNAME}" "${tmp}" "$1" "${PERFORMANCE_DATA}" "${LONG_OUTPUT}"
- exit 2
-}
-
-################################################################################
-# Exits with a warning message
-# Param
-# $1 warning message
-warning() {
- if [ -n "${HOST}" ] ; then
- tmp=" ${HOST}"
- fi
- remove_temporary_files
- printf '%s WARN%s: %s%s%s\n' "${SHORTNAME}" "${tmp}" "$1" "${PERFORMANCE_DATA}" "${LONG_OUTPUT}"
- exit 1
-}
-
-################################################################################
-# Exits with an 'unknown' status
-# Param
-# $1 message
-unknown() {
- if [ -n "${HOST}" ] ; then
- tmp=" ${HOST}"
- fi
- remove_temporary_files
- printf '%s UNKNOWN%s: %s\n' "${SHORTNAME}" "${tmp}" "$1"
- exit 3
-}
-
-################################################################################
-# Executes command with a timeout
-# Params:
-# $1 timeout in seconds
-# $2 command
-# Returns 1 if timed out 0 otherwise
-exec_with_timeout() {
-
- time=$1
-
- # start the command in a subshell to avoid problem with pipes
- # (spawn accepts one command)
- command="/bin/sh -c \"$2\""
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing with timeout (${time}s): $2"
- fi
-
- if [ -n "${TIMEOUT_BIN}" ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] ${TIMEOUT_BIN} $time $command"
- fi
-
- eval "${TIMEOUT_BIN} $time $command" > /dev/null 2>&1
-
- if [ $? = 137 ] ; then
- critical "Timeout after ${time} seconds"
- fi
-
- elif [ -n "${EXPECT}" ] ; then
-
- expect -c "set echo \"-noecho\"; set timeout $time; spawn -noecho $command; expect timeout { exit 1 } eof { exit 0 }"
-
- if [ $? = 1 ] ; then
- critical "Timeout after ${time} seconds"
- fi
-
- else
-
- eval "${command}"
-
- fi
-
-}
-
-################################################################################
-# Checks if a given program is available and executable
-# Params
-# $1 program name
-# Returns 1 if the program exists and is executable
-check_required_prog() {
-
- PROG=$(command -v "$1" 2> /dev/null)
-
- if [ -z "$PROG" ] ; then
- critical "cannot find program: $1"
- fi
-
- if [ ! -x "$PROG" ] ; then
- critical "$PROG is not executable"
- fi
-
-}
-
-################################################################################
-# Converts SSL Labs grades to a numeric value
-# (see https://www.ssllabs.com/downloads/SSL_Server_Rating_Guide.pdf)
-# Params
-# $1 program name
-# Sets NUMERIC_SSL_LAB_GRADE
-convert_ssl_lab_grade() {
-
- GRADE="$1"
-
- unset NUMERIC_SSL_LAB_GRADE
-
- case "${GRADE}" in
- 'A+'|'a+')
- # Value not in documentation
- NUMERIC_SSL_LAB_GRADE=85
- shift
- ;;
- A|a)
- NUMERIC_SSL_LAB_GRADE=80
- shift
- ;;
- 'A-'|'a-')
- # Value not in documentation
- NUMERIC_SSL_LAB_GRADE=75
- shift
- ;;
- B|b)
- NUMERIC_SSL_LAB_GRADE=65
- shift
- ;;
- C|c)
- NUMERIC_SSL_LAB_GRADE=50
- shift
- ;;
- D|d)
- NUMERIC_SSL_LAB_GRADE=35
- shift
- ;;
- E|e)
- NUMERIC_SSL_LAB_GRADE=20
- shift
- ;;
- F|f)
- NUMERIC_SSL_LAB_GRADE=0
- shift
- ;;
- T|t)
- # No trust: value not in documentation
- NUMERIC_SSL_LAB_GRADE=0
- shift
- ;;
- M|m)
- # Certificate name mismatch: value not in documentation
- NUMERIC_SSL_LAB_GRADE=0
- shift
- ;;
- *)
- unknown "Connot convert SSL Lab grade ${GRADE}"
- ;;
- esac
-
-}
-
-################################################################################
-# Tries to fetch the certificate
-
-fetch_certificate() {
-
- RET=0
-
- # IPv6 addresses need brackets in a URI
- if [ "${HOST}" != "${HOST#*[0-9].[0-9]}" ]; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] ${HOST} is an IPv4 address"
- fi
- elif [ "${HOST}" != "${HOST#*:[0-9a-fA-F]}" ]; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] ${HOST} is an IPv6 address"
- fi
- if [ -z "${HOST##*[*}" ] ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] ${HOST} is already specified with brakcets"
- fi
- else
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] adding brackets to ${HOST}"
- fi
- HOST="[${HOST}]"
- fi
- else
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] ${HOST} is not an IP address"
- fi
- fi
-
- # Check if a protocol was specified (if not HTTP switch to TLS)
- if [ -n "${PROTOCOL}" ] && [ "${PROTOCOL}" != "http" ] && [ "${PROTOCOL}" != "https" ] ; then
-
- case "${PROTOCOL}" in
- smtp)
- exec_with_timeout "$TIMEOUT" "echo -e 'QUIT\\r' | $OPENSSL s_client ${CLIENT} ${CLIENTPASS} -starttls ${PROTOCOL} -connect $HOST:$PORT ${SERVERNAME} -verify 6 ${ROOT_CA} ${SSL_VERSION} ${SSL_VERSION_DISABLED} ${SSL_AU} 2> ${ERROR} 1> ${CERT}"
- RET=$?
- ;;
- irc)
- exec_with_timeout "$TIMEOUT" "echo -e 'QUIT\\r' | $OPENSSL s_client ${CLIENT} ${CLIENTPASS} -connect $HOST:$PORT ${SERVERNAME} -verify 6 ${ROOT_CA} ${SSL_VERSION} ${SSL_VERSION_DISABLED} ${SSL_AU} 2> ${ERROR} 1> ${CERT}"
- RET=$?
- ;;
- pop3|imap|ftp|ldap)
- exec_with_timeout "$TIMEOUT" "echo 'Q' | $OPENSSL s_client ${CLIENT} ${CLIENTPASS} -starttls ${PROTOCOL} -connect $HOST:$PORT ${SERVERNAME} -verify 6 ${ROOT_CA} ${SSL_VERSION} ${SSL_VERSION_DISABLED} ${SSL_AU} 2> ${ERROR} 1> ${CERT}"
- RET=$?
- ;;
- xmpp)
- exec_with_timeout "$TIMEOUT" "echo 'Q' | $OPENSSL s_client ${CLIENT} ${CLIENTPASS} -starttls ${PROTOCOL} -connect $HOST:$XMPPPORT ${XMPPHOST} -verify 6 ${ROOT_CA} ${SSL_VERSION} ${SSL_VERSION_DISABLED} ${SSL_AU} 2> ${ERROR} 1> ${CERT}"
- RET=$?
- ;;
- *)
- unknown "Error: unsupported protocol ${PROTOCOL}"
- ;;
- esac
-
- elif [ -n "${FILE}" ] ; then
-
- if [ "${HOST}" = "localhost" ] ; then
- exec_with_timeout "$TIMEOUT" "/bin/cat '${FILE}' 2> ${ERROR} 1> ${CERT}"
- RET=$?
- else
- unknown "Error: option 'file' works with -H localhost only"
- fi
-
- else
-
- exec_with_timeout "$TIMEOUT" "echo 'Q' | $OPENSSL s_client ${CLIENT} ${CLIENTPASS} -connect $HOST:$PORT ${SERVERNAME} -showcerts -verify 6 ${ROOT_CA} ${SSL_VERSION} ${SSL_VERSION_DISABLED} ${SSL_AU} 2> ${ERROR} 1> ${CERT}"
- RET=$?
-
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] storing a copy of the retrieved certificate in ${HOST}.crt"
- cp "${CERT}" "${HOST}.crt"
-
- echo "[DBG] storing a copy of the OpenSSL errors in ${HOST}.error"
- cp "${ERROR}" "${HOST}.error"
-
- fi
-
- if [ "${RET}" -ne 0 ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- sed 's/^/[DBG] SSL error: /' "${ERROR}"
- fi
-
- # s_client could verify the server certificate because the server requires a client certificate
- if grep -q '^Acceptable client certificate CA names' "${CERT}" ; then
-
- if [ -n "${VERBOSE}" ] ; then
- echo "The server requires a client certificate"
- fi
-
- else
-
- # Try to clean up the error message
- # Remove the 'verify and depth' lines
- # Take the 1st line (seems OK with the use cases I tested)
- ERROR_MESSAGE=$(
- grep -v '^depth' "${ERROR}" \
- | grep -v '^verify' \
- | head -n 1
- )
- critical "SSL error: ${ERROR_MESSAGE}"
-
- fi
-
- fi
-
-}
-
-################################################################################
-# Adds metric to performance data
-# Params
-# $1 performance data in nagios plugin format,
-# see https://nagios-plugins.org/doc/guidelines.html#AEN200
-add_performance_data() {
- if [ -z "${PERFORMANCE_DATA}" ]; then
- PERFORMANCE_DATA="|${1}"
- else
- PERFORMANCE_DATA="${PERFORMANCE_DATA} $1"
- fi
-}
-
-################################################################################
-# Prepares sed-style command for variable replacement
-# Params
-# $1 variable name (e.g. SHORTNAME)
-# $2 variable value (e.g. SSL_CERT)
-var_for_sed() {
- echo "s|%$1%|$( echo "$2" | sed -e 's#|#\\\\|#g' )|g"
-}
-
-################################################################################
-# Main
-################################################################################
-main() {
-
- # Default values
- DEBUG=""
- OPENSSL=""
- FILE_BIN=""
- CURL_BIN=""
- IGNORE_SSL_LABS_CACHE=""
- PORT="443"
- XMPPPORT="5222"
- XMPPHOST=""
- SNI=""
- TIMEOUT="15"
- VERBOSE=""
- FORCE_PERL_DATE=""
- REQUIRE_SAN=""
- REQUIRE_OCSP_STAPLING=""
- OCSP="1" # enabled by default
- FORMAT=""
-
- # Set the default temp dir if not set
- if [ -z "${TMPDIR}" ] ; then
- TMPDIR="/tmp"
- fi
-
- ################################################################################
- # Process command line options
- #
- # We do no use getopts since it is unable to process long options
-
- while true; do
-
- case "$1" in
- ########################################
- # Options without arguments
- -A|--noauth)
- NOAUTH=1
- shift
- ;;
- --altnames)
- ALTNAMES=1
- shift
- ;;
- -d|--debug)
- DEBUG=1
- VERBOSE=1
- shift
- ;;
- -h|--help|-\?)
- usage
- exit 0
- ;;
- --force-perl-date)
- FORCE_PERL_DATE=1
- shift
- ;;
- --ignore-exp)
- NOEXP=1
- shift
- ;;
- --ignore-sig-alg)
- NOSIGALG=1
- shift
- ;;
- --ignore-ssl-labs-cache)
- IGNORE_SSL_LABS_CACHE="&startNew=on"
- shift
- ;;
- --no_ssl2)
- SSL_VERSION_DISABLED="${SSL_VERSION_DISABLED} -no_ssl2"
- shift
- ;;
- --no_ssl3)
- SSL_VERSION_DISABLED="${SSL_VERSION_DISABLED} -no_ssl3"
- shift
- ;;
- --no_tls1)
- SSL_VERSION_DISABLED="${SSL_VERSION_DISABLED} -no_tls1"
- shift
- ;;
- --no_tls1_1)
- SSL_VERSION_DISABLED="${SSL_VERSION_DISABLED} -no_tls1_1"
- shift
- ;;
- --no_tls1_2)
- SSL_VERSION_DISABLED="${SSL_VERSION_DISABLED} -no_tls1_2"
- shift
- ;;
- -N|--host-cn)
- COMMON_NAME="__HOST__"
- shift
- ;;
- -s|--selfsigned)
- SELFSIGNED=1
- shift
- ;;
- --rsa)
- SSL_AU="-cipher aRSA"
- shift
- ;;
- --ecdsa)
- SSL_AU="-cipher aECDSA"
- shift
- ;;
- --ssl2)
- SSL_VERSION="-ssl2"
- shift
- ;;
- --ssl3)
- SSL_VERSION="-ssl3"
- shift
- ;;
- --tls1)
- SSL_VERSION="-tls1"
- shift
- ;;
- --tls1_1)
- SSL_VERSION="-tls1_1"
- shift
- ;;
- --tls1_2)
- SSL_VERSION="-tls1_2"
- shift
- ;;
- --tls1_3)
- SSL_VERSION="-tls1_3"
- shift
- ;;
- --ocsp)
- # deprecated
- shift
- ;;
- --ignore-ocsp)
- OCSP=""
- shift
- ;;
- --terse)
- TERSE=1
- shift
- ;;
- -v|--verbose)
- VERBOSE=1
- shift
- ;;
- -V|--version)
- echo "check_ssl_cert version ${VERSION}"
- exit 3
- ;;
- ########################################
- # Options with arguments
- -c|--critical)
- if [ $# -gt 1 ]; then
- CRITICAL="$2"
- shift 2
- else
- unknown "-c,--critical requires an argument"
- fi
- ;;
- --curl-bin)
- if [ $# -gt 1 ]; then
- CURL_BIN="$2"
- shift 2
- else
- unknown "--curl-bin requires an argument"
- fi
- ;;
- # Deprecated option: used to be as --warning
- --days)
- if [ $# -gt 1 ]; then
- WARNING="$2"
- shift 2
- else
- unknown "-d,--days requires an argument"
- fi
- ;;
- -e|--email)
- if [ $# -gt 1 ]; then
- ADDR="$2"
- shift 2
- else
- unknown "-e,--email requires an argument"
- fi
- ;;
- -f|--file)
- if [ $# -gt 1 ]; then
- FILE="$2"
- shift 2
- else
- unknown "-f,--file requires an argument"
- fi
- ;;
- --file-bin)
- if [ $# -gt 1 ]; then
- FILE_BIN="$2"
- shift 2
- else
- unknown "--file-bin requires an argument"
- fi
- ;;
- --format)
- if [ $# -gt 1 ]; then
- FORMAT="$2"
- shift 2
- else
- unknown "-format requires an argument"
- fi
- ;;
- -H|--host)
- if [ $# -gt 1 ]; then
- HOST="$2"
- shift 2
- else
- unknown "-H,--host requires an argument"
- fi
- ;;
- -i|--issuer)
- if [ $# -gt 1 ]; then
- ISSUER="$2"
- shift 2
- else
- unknown "-i,--issuer requires an argument"s
- fi
- ;;
- --issuer-cert-cache)
- if [ $# -gt 1 ]; then
- ISSUER_CERT_CACHE="$2"
- shift 2
- else
- unknown "--issuer-cert-cache requires an argument"
- fi
- ;;
- -L|--check-ssl-labs)
- if [ $# -gt 1 ]; then
- SSL_LAB_ASSESSMENT="$2"
- shift 2
- else
- unknown "-L|--check-ssl-labs requires an argument"
- fi
- ;;
- --serial)
- if [ $# -gt 1 ]; then
- SERIAL_LOCK="$2"
- shift 2
- else
- unknown "--serial requires an argument"
- fi
- ;;
- --fingerprint)
- if [ $# -gt 1 ]; then
- FINGERPRINT_LOCK="$2"
- shift 2
- else
- unknown "--fingerprint requires an argument - SHA1 Fingerprint"
- fi
- ;;
- --long-output)
- if [ $# -gt 1 ]; then
- LONG_OUTPUT_ATTR="$2"
- shift 2
- else
- unknown "--long-output requires an argument"
- fi
- ;;
- -n|--cn)
- if [ $# -gt 1 ]; then
- if [ -n "${COMMON_NAME}" ]; then
- COMMON_NAME="${COMMON_NAME} ${2}"
- else
- COMMON_NAME="${2}"
- fi
- shift 2
- else
- unknown "-n,--cn requires an argument"
- fi
- ;;
- -o|--org)
- if [ $# -gt 1 ]; then
- ORGANIZATION="$2"
- shift 2
- else
- unknown "-o,--org requires an argument"
- fi
- ;;
- --openssl)
- if [ $# -gt 1 ]; then
- OPENSSL="$2"
- shift 2
- else
- unknown "--openssl requires an argument"
- fi
- ;;
- -p|--port)
- if [ $# -gt 1 ]; then
- PORT="$2"
- XMPPPORT="$2"
- shift 2
- else
- unknown "-p,--port requires an argument"
- fi
- ;;
- -P|--protocol)
- if [ $# -gt 1 ]; then
- PROTOCOL="$2"
- shift 2
- else
- unknown "-P,--protocol requires an argument"
- fi
- ;;
- -r|--rootcert)
- if [ $# -gt 1 ]; then
- ROOT_CA="$2"
- shift 2
- else
- unknown "-r,--rootcert requires an argument"
- fi
- ;;
- -C|--clientcert)
- if [ $# -gt 1 ]; then
- CLIENT_CERT="$2"
- shift 2
- else
- unknown "-c,--clientcert requires an argument"
- fi
- ;;
- --clientpass)
- if [ $# -gt 1 ]; then
- CLIENT_PASS="$2"
- shift 2
- else
- unknown "--clientpass requires an argument"
- fi
- ;;
- --require-ocsp-stapling)
- REQUIRE_OCSP_STAPLING=1
- shift
- ;;
- --require-san)
- REQUIRE_SAN=1
- shift
- ;;
- --sni)
- if [ $# -gt 1 ]; then
- SNI="$2"
- shift 2
- else
- unknown "--sni requires an argument"
- fi
- ;;
- -S|--ssl)
- if [ $# -gt 1 ]; then
-
- if [ "$2" = "2" ] || [ "$2" = "3" ] ; then
- SSL_VERSION="-ssl${2}"
- shift 2
- else
- unknown "invalid argument for --ssl"
- fi
-
- else
-
- unknown "--ssl requires an argument"
-
- fi
- ;;
- -t|--timeout)
- if [ $# -gt 1 ]; then
- TIMEOUT="$2"
- shift 2
- else
- unknown "-t,--timeout requires an argument"
- fi
- ;;
- --temp)
- if [ $# -gt 1 ] ; then
- # Override TMPDIR
- TMPDIR="$2"
- shift 2
- else
- unknown "--temp requires an argument"
- fi
- ;;
- -w|--warning)
- if [ $# -gt 1 ]; then
- WARNING="$2"
- shift 2
- else
- unknown "-w,--warning requires an argument"
- fi
- ;;
- --xmpphost)
- if [ $# -gt 1 ]; then
- XMPPHOST="$2"
- shift 2
- else
- unknown "--xmpphost requires an argument"
- fi
- ;;
- ########################################
- # Special
- --)
- shift
- break
- ;;
- -*)
- unknown "invalid option: ${1}"
- ;;
- *)
- if [ -n "$1" ] ; then
- unknown "invalid option: ${1}"
- fi
- break
- ;;
- esac
-
- done
-
- ################################################################################
- # Set COMMON_NAME to hostname if -N was given as argument
- if [ "$COMMON_NAME" = "__HOST__" ] ; then
- COMMON_NAME="${HOST}"
- fi
-
- ################################################################################
- # Sanity checks
-
- ###############
- # Check options
- if [ -z "${HOST}" ] ; then
- usage "No host specified"
- fi
-
- if [ -n "${ALTNAMES}" ] && [ -z "${COMMON_NAME}" ] ; then
- unknown "--altnames requires a common name to match (--cn or --host-cn)"
- fi
-
- if [ -n "${ROOT_CA}" ] ; then
-
- if [ ! -r "${ROOT_CA}" ] ; then
- unknown "Cannot read root certificate ${ROOT_CA}"
- fi
-
- if [ -d "${ROOT_CA}" ] ; then
- ROOT_CA="-CApath ${ROOT_CA}"
- elif [ -f "${ROOT_CA}" ] ; then
- ROOT_CA="-CAfile ${ROOT_CA}"
- else
- unknown "Root certificate of unknown type $(file "${ROOT_CA}" 2> /dev/null)"
- fi
-
- fi
-
- if [ -n "${CLIENT_CERT}" ] ; then
-
- if [ ! -r "${CLIENT_CERT}" ] ; then
- unknown "Cannot read client certificate ${CLIENT_CERT}"
- fi
-
- fi
-
- if [ -n "${CRITICAL}" ] ; then
-
- if ! echo "${CRITICAL}" | grep -q '^[0-9][0-9]*$' ; then
- unknown "invalid number of days ${CRITICAL}"
- fi
-
- fi
-
- if [ -n "${WARNING}" ] ; then
-
- if ! echo "${WARNING}" | grep -q '^[0-9][0-9]*$' ; then
- unknown "invalid number of days ${WARNING}"
- fi
-
- fi
-
- if [ -n "${CRITICAL}" ] && [ -n "${WARNING}" ] ; then
-
- if [ "${WARNING}" -le "${CRITICAL}" ] ; then
- unknown "--warning (${WARNING}) is less than or equal to --critical (${CRITICAL})"
- fi
-
- fi
-
- if [ -n "${TMPDIR}" ] ; then
-
- if [ ! -d "${TMPDIR}" ] ; then
- unknown "${TMPDIR} is not a directory";
- fi
-
- if [ ! -w "${TMPDIR}" ] ; then
- unknown "${TMPDIR} is not writable";
- fi
-
- fi
-
- if [ -n "${OPENSSL}" ] ; then
-
- if [ ! -x "${OPENSSL}" ] ; then
- unknown "${OPENSSL} ist not an executable"
- fi
-
- #if ! "${OPENSSL}" list-standard-commands | grep -q s_client ; then
- # unknown "${OPENSSL} ist not an openssl executable"
- #fi
-
- fi
-
- if [ -n "${SSL_LAB_ASSESSMENT}" ] ; then
- convert_ssl_lab_grade "${SSL_LAB_ASSESSMENT}"
- SSL_LAB_ASSESSMENT_NUMERIC="${NUMERIC_SSL_LAB_GRADE}"
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] ROOT_CA = ${ROOT_CA}"
- fi
-
- #######################
- # Check needed programs
-
- # OpenSSL
- if [ -z "${OPENSSL}" ] ; then
- check_required_prog openssl
- OPENSSL=$PROG
- fi
-
- # file
- if [ -z "${FILE_BIN}" ] ; then
- check_required_prog file
- FILE_BIN=$PROG
- fi
-
- # curl
- if [ -z "${CURL_BIN}" ] ; then
- if [ -n "${SSL_LAB_ASSESSMENT}" ] || [ -n "${OCSP}" ] ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] cURL binary needed. SSL Labs = ${SSL_LAB_ASSESSMENT}, OCSP = ${OCSP}"
- echo "[DBG] cURL binary not specified"
- fi
- check_required_prog curl
- CURL_BIN=$PROG
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] cURL available: ${CURL_BIN}"
- fi
- else
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] cURL binary not needed. SSL Labs = ${SSL_LAB_ASSESSMENT}, OCSP = ${OCSP}"
- fi
- fi
- fi
-
- # Expect (optional)
- EXPECT="$(command -v expect 2> /dev/null)"
- test -x "${EXPECT}" || EXPECT=""
- if [ -n "${VERBOSE}" ] ; then
- if [ -z "${EXPECT}" ] ; then
- echo "expect not available"
- else
- echo "expect available (${EXPECT})"
- fi
- fi
-
- # Timeout (optional)
- TIMEOUT_BIN="$(command -v timeout 2> /dev/null)"
- test -x "${TIMEOUT_BIN}" || TIMEOUT_BIN=""
- if [ -n "${VERBOSE}" ] ; then
-
- if [ -z "${TIMEOUT_BIN}" ] ; then
- echo "timeout not available"
- else
- echo "timeout available (${TIMEOUT_BIN})"
- fi
-
- fi
-
- if [ -z "${TIMEOUT_BIN}" ] && [ -z "${EXPECT}" ] && [ -n "${VERBOSE}" ] ; then
- echo "disabling timeouts"
- fi
-
- PERL="$(command -v perl 2> /dev/null)"
-
- if [ -n "${DEBUG}" ] && [ -n "${PERL}" ] ; then
- echo "[DBG] perl available: ${PERL}"
- fi
-
- DATEBIN="$(command -v date 2> /dev/null)"
-
- if [ -n "${DEBUG}" ] && [ -n "${DATEBIN}" ] ; then
- echo "[DBG] date available: ${DATEBIN}"
- fi
-
- DATETYPE=""
-
- if ! "${DATEBIN}" +%s >/dev/null 2>&1 ; then
-
- # Perl with Date::Parse (optional)
- test -x "${PERL}" || PERL=""
- if [ -z "${PERL}" ] && [ -n "${VERBOSE}" ] ; then
- echo "Perl not found: disabling date computations"
- fi
-
- if ! ${PERL} -e "use Date::Parse;" > /dev/null 2>&1 ; then
-
- if [ -n "${VERBOSE}" ] ; then
- echo "Perl module Date::Parse not installed: disabling date computations"
- fi
-
- PERL=""
-
- else
-
- if [ -n "${VERBOSE}" ] ; then
- echo "Perl module Date::Parse installed: enabling date computations"
- fi
-
- DATETYPE="PERL"
-
- fi
-
- else
-
- if $DATEBIN --version >/dev/null 2>&1 ; then
- DATETYPE="GNU"
- else
- DATETYPE="BSD"
- fi
-
- if [ -n "${VERBOSE}" ] ; then
- echo "found ${DATETYPE} date with timestamp support: enabling date computations"
- fi
-
- fi
-
- if [ -n "${FORCE_PERL_DATE}" ] ; then
- DATETYPE="PERL"
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] check_ssl_cert version: ${VERSION}"
- echo "[DBG] OpenSSL binary: ${OPENSSL}"
- echo "[DBG] OpenSSL version: $( ${OPENSSL} version )"
-
- OPENSSL_DIR="$( ${OPENSSL} version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/' )"
-
- echo "[DBG] OpenSSL configuration directory: ${OPENSSL_DIR}"
-
- DEFAULT_CA=0
- if [ -f "${OPENSSL_DIR}"/cert.pem ] ; then
- DEFAULT_CA="$( grep -c BEGIN "${OPENSSL_DIR}"/cert.pem )"
- elif [ -f "${OPENSSL_DIR}"/certs ] ; then
- DEFAULT_CA="$( grep -c BEGIN "${OPENSSL_DIR}"/certs )"
- fi
- echo "[DBG] ${DEFAULT_CA} root certificates installed by default"
-
- echo "[DBG] System info: $( uname -a )"
- echo "[DBG] Date computation: ${DATETYPE}"
- fi
-
- ################################################################################
- # Check if openssl s_client supports the -servername option
- #
- # openssl s_client now has a -help option, so we can use that.
- # Some older versions support -servername, but not -help
- # => We supply an invalid command line option to get the help
- # on standard error for these intermediate versions.
- #
- SERVERNAME=
- if ${OPENSSL} s_client -help 2>&1 | grep -q -- -servername || ${OPENSSL} s_client not_a_real_option 2>&1 | grep -q -- -servername; then
-
- if [ -n "${SNI}" ]; then
- SERVERNAME="-servername ${SNI}"
- else
- SERVERNAME="-servername ${HOST}"
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] '${OPENSSL} s_client' supports '-servername': using ${SERVERNAME}"
- fi
-
- else
-
- if [ -n "${VERBOSE}" ] ; then
- echo "'${OPENSSL} s_client' does not support '-servername': disabling virtual server support"
- fi
-
- fi
-
- ################################################################################
- # Check if openssl s_client supports the -xmpphost option
- #
- if ${OPENSSL} s_client -help 2>&1 | grep -q -- -xmpphost ; then
-
- XMPPHOST="-xmpphost ${XMPPHOST:-$HOST}"
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] '${OPENSSL} s_client' supports '-xmpphost': using ${XMPPHOST}"
- fi
-
- else
-
- if [ -n "${XMPPHOST}" ] ; then
- unknown " s_client' does not support '-xmpphost'"
- fi
-
- XMPPHOST=
-
- if [ -n "${VERBOSE}" ] ; then
- echo "'${OPENSSL} s_client' does not support '-xmpphost': disabling 'to' attribute"
- fi
-
- fi
-
- ################################################################################
- # check if openssl s_client supports the SSL TLS version
- if [ -n "${SSL_VERSION}" ] ; then
- if ! "${OPENSSL}" s_client -help 2>&1 | grep -q -- "${SSL_VERSION}" ; then
- unknown "OpenSSL does not support the ${SSL_VERSION} version"
- fi
- fi
-
- ################################################################################
- # Fetch the X.509 certificate
-
- # Temporary storage for the certificate and the errors
- create_temporary_file; CERT=$TEMPFILE
- create_temporary_file; ERROR=$TEMPFILE
-
- if [ -n "${OCSP}" ] ; then
-
- create_temporary_file; ISSUER_CERT_TMP=$TEMPFILE
- create_temporary_file; ISSUER_CERT_TMP2=$TEMPFILE
-
- fi
-
- if [ -n "${REQUIRE_OCSP_STAPLING}" ] ; then
- create_temporary_file; OCSP_RESPONSE_TMP=$TEMPFILE
- fi
-
- if [ -n "${VERBOSE}" ] ; then
- echo "downloading certificate to ${TMPDIR}"
- fi
-
- CLIENT=""
- if [ -n "${CLIENT_CERT}" ] ; then
- CLIENT="-cert ${CLIENT_CERT}"
- fi
-
- CLIENTPASS=""
- if [ -n "${CLIENT_PASS}" ] ; then
- CLIENTPASS="-pass pass:${CLIENT_PASS}"
- fi
-
- # Cleanup before program termination
- # Using named signals to be POSIX compliant
- # shellcheck disable=SC2086
- trap_with_arg cleanup $SIGNALS
-
- fetch_certificate
-
- if grep -q 'sslv3\ alert\ unexpected\ message' "${ERROR}" ; then
-
- if [ -n "${SERVERNAME}" ] ; then
-
- # Some OpenSSL versions have problems with the -servername option
- # We try without
- if [ -n "${VERBOSE}" ] ; then
- echo "'${OPENSSL} s_client' returned an error: trying without '-servername'"
- fi
-
- SERVERNAME=""
- fetch_certificate
-
- fi
-
- if grep -q 'sslv3\ alert\ unexpected\ message' "${ERROR}" ; then
-
- critical "cannot fetch certificate: OpenSSL got an unexpected message"
-
- fi
-
- fi
-
- if grep -q "BEGIN X509 CRL" "${CERT}" ; then
- # we are dealing with a CRL file
- OPENSSL_COMMAND="crl"
- OPENSSL_PARAMS="-nameopt utf8,oneline,-esc_msb"
- OPENSSL_ENDDATE_OPTION="-nextupdate"
- else
- # look if we are dealing with a regular certificate file (x509)
- if ! grep -q "CERTIFICATE" "${CERT}" ; then
-
- if [ -n "${FILE}" ] ; then
- if "${OPENSSL}" crl -in "${CERT}" -inform DER | grep -q "BEGIN X509 CRL" ; then
- if [ -n "${VERBOSE}" ] ; then
- echo "File is DER encoded CRL"
- fi
- OPENSSL_COMMAND="crl"
- OPENSSL_PARAMS="-inform DER -nameopt utf8,oneline,-esc_msb"
- OPENSSL_ENDDATE_OPTION="-nextupdate"
- else
- critical "'${FILE}' is not a valid certificate file"
- fi
- else
- # See
- # http://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n
- #
- # - create a branch label via :a
- # - the N command appends a newline and and the next line of the input
- # file to the pattern space
- # - if we are before the last line, branch to the created label $!ba
- # ($! means not to do it on the last line (as there should be one final newline))
- # - finally the substitution replaces every newline with a space on
- # the pattern space
- ERROR_MESSAGE="$(sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/; /g' "${ERROR}")"
- if [ -n "${VERBOSE}" ] ; then
- echo "Error: ${ERROR_MESSAGE}"
- fi
- critical "No certificate returned"
- fi
- else
- # parameters for regular x509 certifcates
- OPENSSL_COMMAND="x509"
- OPENSSL_PARAMS="-nameopt utf8,oneline,-esc_msb"
- OPENSSL_ENDDATE_OPTION="-enddate"
- fi
-
- fi
-
- if [ -n "${VERBOSE}" ] ; then
- echo "parsing the ${OPENSSL_COMMAND} certificate file"
- fi
-
- ################################################################################
- # Parse the X.509 certificate or crl
-
- # shellcheck disable=SC2086
- DATE="$($OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" ${OPENSSL_ENDDATE_OPTION} -noout | sed -e "s/^notAfter=//" -e "s/^nextUpdate=//")"
-
- if [ ${OPENSSL_COMMAND} = "crl" ]; then
- CN=""
- SUBJECT=""
- SERIAL=0
- OCSP_URI=""
- VALID_ATTRIBUTES=",lastupdate,nextupdate,issuer,"
- # shellcheck disable=SC2086
- ISSUERS="$($OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" -issuer -noout)"
- else
- # we need to remove everything before 'CN = ', to remove an eventual email supplied with / and additional elements (after ', ')
- # shellcheck disable=SC2086
- CN="$($OPENSSL x509 -in "${CERT}" -subject -noout ${OPENSSL_PARAMS} |
- sed -e "s/^.*[[:space:]]*CN[[:space:]]=[[:space:]]//" -e "s/\\/[[:alpha:]][[:alpha:]]*=.*\$//" -e "s/,.*//" )"
-
- # shellcheck disable=SC2086
- SUBJECT="$($OPENSSL x509 -in "${CERT}" -subject -noout ${OPENSSL_PARAMS})"
-
- SERIAL="$($OPENSSL x509 -in "${CERT}" -serial -noout | sed -e "s/^serial=//")"
-
- FINGERPRINT="$($OPENSSL x509 -in "${CERT}" -fingerprint -sha1 -noout | sed -e "s/^SHA1 Fingerprint=//")"
-
- # TO DO: we just take the first result: a loop over all the hosts should
- # shellcheck disable=SC2086
- OCSP_URI="$($OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" -ocsp_uri -noout | head -n 1)"
-
- # count the certificates in the chain
- NUM_CERTIFICATES=$(grep -c -- "-BEGIN CERTIFICATE-" "${CERT}")
-
- # start with first certificate
- CERT_IN_CHAIN=1
- # shellcheck disable=SC2086
- while [ $CERT_IN_CHAIN -le $NUM_CERTIFICATES ]; do
- if [ -n "$ISSUERS" ]; then
- ISSUERS="$ISSUERS\\n"
- fi
- # shellcheck disable=SC2086
- ISSUERS="$ISSUERS$(sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' "${CERT}" | \
- awk -v n=$CERT_IN_CHAIN '/-BEGIN CERTIFICATE-/{l++} (l==n) {print}' | \
- $OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -issuer -noout)"
-
- CERT_IN_CHAIN=$(( CERT_IN_CHAIN + 1 ))
- done
- fi
-
- # Handle properly openssl x509 -issuer -noout output format differences:
- # OpenSSL 1.1.0: issuer=C = XY, ST = Alpha, L = Bravo, O = Charlie, CN = Charlie SSL CA
- # OpenSSL 1.0.2: issuer= /C=XY/ST=Alpha/L=Bravo/O=Charlie/CN=Charlie SSL CA 3
- # shellcheck disable=SC2086
- ISSUERS=$(echo "$ISSUERS" | sed 's/\\n/\n/g' | sed -e "s/^.*\\/CN=//" -e "s/^.* CN = //" -e "s/^.*, O = //" -e "s/\\/[A-Za-z][A-Za-z]*=.*\$//" -e "s/, [A-Za-z][A-Za-z]* =.*\$//")
-
- # we just consider the first URI
- # shellcheck disable=SC2086
- ISSUER_URI="$($OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" -text -noout | grep "CA Issuers" | head -n 1 | sed -e "s/^.*CA Issuers - URI://")"
-
- if [ -z "${ISSUER_URI}" ] ; then
- if [ -n "${VERBOSE}" ] ; then
- echo "cannot find the CA Issuers in the certificate: disabling OCSP checks"
- fi
- OCSP=""
- elif ! echo "${ISSUER_URI}" | grep -qi '^http' ; then
- if [ -n "${VERBOSE}" ] ; then
- echo "unable to fetch the CA issuer certificate (unsupported protocol)"
- fi
- OCSP=""
- fi
-
- # Check OCSP stapling
- if [ -n "${REQUIRE_OCSP_STAPLING}" ] ; then
-
- if [ -n "${VERBOSE}" ] ; then
- echo "checking OCSP stapling"
- fi
-
- exec_with_timeout "$TIMEOUT" "echo QUIT | openssl s_client -connect ${HOST}:${PORT} ${SERVERNAME} -status 2> /dev/null | grep -A 17 'OCSP response:' > $OCSP_RESPONSE_TMP"
-
- if [ -n "${DEBUG}" ] ; then
- sed 's/^/[DBG]\ /' "${OCSP_RESPONSE_TMP}"
- fi
-
- if ! grep -q 'Next Update' "${OCSP_RESPONSE_TMP}" ; then
- critical "OCSP stapling not enabled"
- else
- if [ -n "${VERBOSE}" ] ; then
- echo " OCSP stapling enabled"
- fi
- fi
-
- fi
-
- # shellcheck disable=SC2086
- SIGNATURE_ALGORITHM="$($OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" -text -noout | grep 'Signature Algorithm' | head -n 1)"
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] ${SUBJECT}"
- echo "[DBG] CN = ${CN}"
- # shellcheck disable=SC2162
- echo "$ISSUERS" | while read LINE; do
- echo "[DBG] CA = ${LINE}"
- done
- echo "[DBG] SERIAL = ${SERIAL}"
- echo "[DBG] FINGERPRINT= ${FINGERPRINT}"
- echo "[DBG] OCSP_URI = ${OCSP_URI}"
- echo "[DBG] ISSUER_URI = ${ISSUER_URI}"
- echo "[DBG] ${SIGNATURE_ALGORITHM}"
- fi
-
- if echo "${SIGNATURE_ALGORITHM}" | grep -q "sha1" ; then
-
- if [ -n "${NOSIGALG}" ] ; then
-
- if [ -n "${VERBOSE}" ] ; then
- echo "${OPENSSL_COMMAND} Certificate is signed with SHA-1"
- fi
-
- else
-
- critical "${OPENSSL_COMMAND} Certificate is signed with SHA-1"
-
- fi
-
- fi
-
- if echo "${SIGNATURE_ALGORITHM}" | grep -qi "md5" ; then
-
- if [ -n "${NOSIGALG}" ] ; then
-
- if [ -n "${VERBOSE}" ] ; then
- echo "${OPENSSL_COMMAND} Certificate is signed with MD5"
- fi
-
- else
-
- critical "${OPENSSL_COMMAND} Certificate is signed with MD5"
-
- fi
-
- fi
-
- ################################################################################
- # Generate the long output
- if [ -n "${LONG_OUTPUT_ATTR}" ] ; then
-
- check_attr() {
- ATTR="$1"
- if ! echo "${VALID_ATTRIBUTES}" | grep -q ",${ATTR}," ; then
- unknown "Invalid certificate attribute: ${ATTR}"
- else
- # shellcheck disable=SC2086
- value="$(${OPENSSL} "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" -noout -nameopt utf8,oneline,-esc_msb -"${ATTR}" | sed -e "s/.*=//")"
- LONG_OUTPUT="${LONG_OUTPUT}\\n${ATTR}: ${value}"
- fi
-
- }
-
- # Split on comma
- if [ "${LONG_OUTPUT_ATTR}" = "all" ] ; then
- LONG_OUTPUT_ATTR="${VALID_ATTRIBUTES}"
- fi
- attributes=$( echo ${LONG_OUTPUT_ATTR} | tr ',' "\\n" )
- for attribute in $attributes ; do
- check_attr "${attribute}"
- done
-
- LONG_OUTPUT="$(echo "$LONG_OUTPUT" | sed 's/\\n/\n/g')"
-
- fi
-
- ################################################################################
- # Compute for how many days the certificate will be valid
- if [ -n "${DATETYPE}" ]; then
-
- # shellcheck disable=SC2086
- CERT_END_DATE=$($OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" -noout ${OPENSSL_ENDDATE_OPTION} | sed -e "s/.*=//")
-
- OLDLANG=$LANG
- LANG=en_US
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] Date computations: ${DATETYPE}"
- fi
-
- case "${DATETYPE}" in
- "BSD")
- DAYS_VALID=$(( ( $(${DATEBIN} -jf "%b %d %T %Y %Z" "${CERT_END_DATE}" +%s) - $(${DATEBIN} +%s) ) / 86400 ))
- ;;
-
- "GNU")
- DAYS_VALID=$(( ( $(${DATEBIN} -d "${CERT_END_DATE}" +%s) - $(${DATEBIN} +%s) ) / 86400 ))
- ;;
-
- "PERL")
- # Warning: some shell script formatting tools will indent the EOF! (should be at position 0)
- if ! DAYS_VALID=$(perl - "${CERT_END_DATE}" <<-"EOF"
- use strict;
- use warnings;
- use Date::Parse;
- my $cert_date = str2time( $ARGV[0] );
- my $days = int (( $cert_date - time ) / 86400 + 0.5);
- print "$days\n";
-EOF
- ) ; then
- # somethig went wrong with the embedded Perl code: check the indentation of EOF
- unknown "Error computing the certificate validity with Perl"
- fi
- ;;
- esac
-
- LANG=$OLDLANG
-
- if [ -n "${VERBOSE}" ] ; then
-
- if [ "${DAYS_VALID}" -ge 0 ] ; then
- echo "The certificate will expire in ${DAYS_VALID} day(s)"
- else
- echo "The certificate expired "$((- DAYS_VALID))" day(s) ago"
- fi
-
- fi
- add_performance_data "days=$DAYS_VALID;${WARNING};${CRITICAL};;"
-
- fi
-
- ################################################################################
- # Check the presence of a subjectAlternativeName (required for Chrome)
-
- # shellcheck disable=SC2086
- SUBJECT_ALTERNATIVE_NAME=$($OPENSSL "${OPENSSL_COMMAND}" ${OPENSSL_PARAMS} -in "${CERT}" -text |
- grep --after-context=1 "509v3 Subject Alternative Name:" |
- tail -n 1 |
- sed -e "s/DNS://g" |
- sed -e "s/,//g" |
- sed -e "s/^\\ *//"
- )
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] subjectAlternativeName = ${SUBJECT_ALTERNATIVE_NAME}"
- fi
- if [ -n "${REQUIRE_SAN}" ] && [ -z "${SUBJECT_ALTERNATIVE_NAME}" ] && [ ${OPENSSL_COMMAND} != "crl" ] ; then
- critical "The certificate for this site does not contain a Subject Alternative Name extension containing a domain name or IP address."
- fi
-
- ################################################################################
- # Check the CN
- if [ -n "$COMMON_NAME" ] ; then
-
- ok=""
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] check CN: ${CN}"
- fi
-
- # Common name is case insensitive: using grep for comparison (and not 'case' with 'shopt -s nocasematch' as not defined in POSIX
-
- if echo "${CN}" | grep -q -i "^\\*\\." ; then
-
- # Match the domain
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the common name ${CN} begins with a '*'"
- echo "[DBG] checking if the common name matches ^$(echo "${CN}" | cut -c 3-)\$"
- fi
- if echo "${COMMON_NAME}" | grep -q -i "^$(echo "${CN}" | cut -c 3-)\$" ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the common name ${COMMON_NAME} matches ^$( echo "${CN}" | cut -c 3- )\$"
- fi
- ok="true"
-
- fi
-
- # Or the literal with the wildcard
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] checking if the common name matches ^$(echo "${CN}" | sed -e 's/[.]/[.]/g' -e 's/[*]/[A-Za-z0-9\-]*/' )\$"
- fi
- if echo "${COMMON_NAME}" | grep -q -i "^$(echo "${CN}" | sed -e 's/[.]/[.]/g' -e 's/[*]/[A-Za-z0-9\-]*/' )\$" ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the common name ${COMMON_NAME} matches ^$(echo "${CN}" | sed -e 's/[.]/[.]/g' -e 's/[*]/[A-Za-z0-9\-]*/' )\$"
- fi
- ok="true"
- fi
-
- # Or if both are exactly the same
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] checking if the common name matches ^${CN}\$"
- fi
- if echo "${COMMON_NAME}" | grep -q -i "^${CN}\$" ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the common name ${COMMON_NAME} matches ^${CN}\$"
- fi
- ok="true"
- fi
-
- else
-
- if echo "${COMMON_NAME}" | grep -q -i "^${CN}$" ; then
- ok="true"
- fi
-
- fi
-
- # Check alternate names
- if [ -n "${ALTNAMES}" ] && [ -z "$ok" ]; then
-
- for cn in ${COMMON_NAME} ; do
-
- ok=""
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] checking altnames against ${cn}"
- fi
-
- for alt_name in ${SUBJECT_ALTERNATIVE_NAME} ; do
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] check Altname: ${alt_name}"
- fi
-
- if echo "${alt_name}" | grep -q -i "^\\*\\." ; then
-
- # Match the domain
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the altname ${alt_name} begins with a '*'"
- echo "[DBG] checking if the common name matches ^$(echo "${alt_name}" | cut -c 3-)\$"
- fi
- if echo "${cn}" | grep -q -i "^$(echo "${alt_name}" | cut -c 3-)\$" ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the common name ${cn} matches ^$( echo "${alt_name}" | cut -c 3- )\$"
- fi
- ok="true"
-
- fi
-
- # Or the literal with the wildcard
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] checking if the common name matches ^$(echo "${alt_name}" | sed -e 's/[.]/[.]/g' -e 's/[*]/[A-Za-z0-9\-]*/' )\$"
- fi
- if echo "${cn}" | grep -q -i "^$(echo "${alt_name}" | sed -e 's/[.]/[.]/g' -e 's/[*]/[A-Za-z0-9\-]*/' )\$" ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the common name ${cn} matches ^$(echo "${alt_name}" | sed -e 's/[.]/[.]/g' -e 's/[*]/[A-Za-z0-9\-]*/' )\$"
- fi
- ok="true"
- fi
-
- # Or if both are exactly the same
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] checking if the common name matches ^${alt_name}\$"
- fi
- if echo "${cn}" | grep -q -i "^${alt_name}\$" ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] the common name ${cn} matches ^${alt_name}\$"
- fi
- ok="true"
- fi
-
- else
-
- if echo "${cn}" | grep -q -i "^${alt_name}$" ; then
- ok="true"
- fi
-
- fi
-
- if [ -n "$ok" ] ; then
- #fail=$cn
- break;
- fi
-
- done
-
- if [ -z "$ok" ] ; then
- fail=$cn
- break;
- fi
-
- done
-
- fi
-
- if [ -n "$fail" ] ; then
- critical "invalid CN ('$CN' does not match '$fail')"
- fi
-
- if [ -z "$ok" ] ; then
- critical "invalid CN ('$CN' does not match '$COMMON_NAME')"
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] CN check finished"
- fi
-
- fi
-
- ################################################################################
- # Check the issuer
- if [ -n "${ISSUER}" ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] check ISSUER: ${ISSUER}"
- fi
-
- ok=""
- CA_ISSUER_MATCHED=$(echo "${ISSUERS}" | grep "^${ISSUER}\$" | head -n1)
-
- if [ -n "${CA_ISSUER_MATCHED}" ]; then
- ok="true"
- else
- # this looks ugly but preserves spaces in CA name
- critical "invalid CA ('${ISSUER}' does not match '$(echo "${ISSUERS}" | tr '\n' '|' | sed "s/|\$//g" | sed "s/|/\\' or \\'/g")')"
- fi
-
- else
-
- CA_ISSUER_MATCHED="$(echo "${ISSUERS}" | head -n1)"
-
- fi
-
- ################################################################################
- # Check the serial number
- if [ -n "${SERIAL_LOCK}" ] ; then
-
- ok=""
-
- if echo "${SERIAL}" | grep -q "^${SERIAL_LOCK}\$" ; then
- ok="true"
- fi
-
- if [ -z "$ok" ] ; then
- critical "invalid serial number ('${SERIAL}' does not match '${SERIAL_LOCK}')"
- fi
-
- fi
- ################################################################################
- # Check the Fingerprint
- if [ -n "${FINGERPRINT_LOCK}" ] ; then
-
- ok=""
-
- if echo "${FINGERPRINT}" | grep -q "^${FINGERPRINT_LOCK}\$" ; then
- ok="true"
- fi
-
- if [ -z "$ok" ] ; then
- critical "invalid SHA1 Fingerprint ('${FINGERPRINT}' does not match '${FINGERPRINT_LOCK}')"
- fi
-
- fi
-
- ################################################################################
- # Check the validity
- if [ -z "${NOEXP}" ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] Checking expiration date"
- fi
-
- if [ ${OPENSSL_COMMAND} = "x509" ]; then
- # x509 certificates (default)
-
- # We always check expired certificates
- if ! $OPENSSL x509 -in "${CERT}" -noout -checkend 0 > /dev/null ; then
- critical "${OPENSSL_COMMAND} certificate is expired (was valid until $DATE)"
- fi
-
- if [ -n "${CRITICAL}" ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing: $OPENSSL x509 -in ${CERT} -noout -checkend $(( CRITICAL * 86400 ))"
- fi
-
- if ! $OPENSSL x509 -in "${CERT}" -noout -checkend $(( CRITICAL * 86400 )) > /dev/null ; then
- critical "${OPENSSL_COMMAND} certificate will expire in ${DAYS_VALID} day(s) on $DATE"
- fi
-
- fi
-
- if [ -n "${WARNING}" ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing: $OPENSSL x509 -in ${CERT} -noout -checkend $(( WARNING * 86400 ))"
- fi
-
- if ! $OPENSSL x509 -in "${CERT}" -noout -checkend $(( WARNING * 86400 )) > /dev/null ; then
- warning "${OPENSSL_COMMAND} certificate will expire in ${DAYS_VALID} day(s) on $DATE"
- fi
-
- fi
- elif [ ${OPENSSL_COMMAND} = "crl" ]; then
- # CRL certificates
-
- # We always check expired certificates
- if [ "${DAYS_VALID}" -lt 1 ] ; then
- critical "${OPENSSL_COMMAND} certificate is expired (was valid until $DATE)"
- fi
-
- if [ -n "${CRITICAL}" ] ; then
- if [ "${DAYS_VALID}" -lt "${CRITICAL}" ] ; then
- critical "${OPENSSL_COMMAND} certificate will expire in ${DAYS_VALID} day(s) on $DATE"
- fi
-
- fi
-
- if [ -n "${WARNING}" ] ; then
- if [ "${DAYS_VALID}" -lt "${WARNING}" ] ; then
- warning "${OPENSSL_COMMAND} certificate will expire in ${DAYS_VALID} day(s) on $DATE"
- fi
-
- fi
- fi
-
- fi
-
- ################################################################################
- # Check SSL Labs
- if [ -n "${SSL_LAB_ASSESSMENT}" ] ; then
-
- if [ -n "${VERBOSE}" ] ; then
- echo "Checking SSL Labs assessment"
- fi
-
- while true; do
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing ${CURL_BIN} --silent \"https://api.ssllabs.com/api/v2/analyze?host=${HOST}${IGNORE_SSL_LABS_CACHE}\""
- fi
-
- JSON="$(${CURL_BIN} --silent "https://api.ssllabs.com/api/v2/analyze?host=${HOST}${IGNORE_SSL_LABS_CACHE}")"
- CURL_RETURN_CODE=$?
-
- if [ ${CURL_RETURN_CODE} -ne 0 ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] curl returned ${CURL_RETURN_CODE}: ${CURL_BIN} --silent \"https://api.ssllabs.com/api/v2/analyze?host=${HOST}${IGNORE_SSL_LABS_CACHE}\""
- fi
-
- unknown "Error checking SSL Labs: curl returned ${CURL_RETURN_CODE}, see 'man curl' for details"
-
- fi
-
- JSON="$(printf '%s' "${JSON}" | tr '\n' ' ' )"
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] Checking SSL Labs: ${CURL_BIN} --silent \"https://api.ssllabs.com/api/v2/analyze?host=${HOST}\""
- echo "[DBG] SSL Labs JSON: ${JSON}"
- fi
-
- # We clear the cache only on the first run
- IGNORE_SSL_LABS_CACHE=""
-
- SSL_LABS_HOST_STATUS=$(echo "${JSON}" \
- | sed 's/.*"status":[ ]*"\([^"]*\)".*/\1/')
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] SSL Labs status: ${SSL_LABS_HOST_STATUS}"
- fi
-
- case "${SSL_LABS_HOST_STATUS}" in
- 'ERROR')
- SSL_LABS_STATUS_MESSAGE=$(echo "${JSON}" \
- | sed 's/.*"statusMessage":[ ]*"\([^"]*\)".*/\1/')
- critical "Error checking SSL Labs: ${SSL_LABS_STATUS_MESSAGE}"
- ;;
- 'READY')
- if ! echo "${JSON}" | grep -q "grade" ; then
-
- # Something went wrong
- SSL_LABS_STATUS_MESSAGE=$(echo "${JSON}" \
- | sed 's/.*"statusMessage":[ ]*"\([^"]*\)".*/\1/')
- critical "SSL Labs error: ${SSL_LABS_STATUS_MESSAGE}"
-
- else
-
- SSL_LABS_HOST_GRADE=$(echo "${JSON}" \
- | sed 's/.*"grade":[ ]*"\([^"]*\)".*/\1/')
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] SSL Labs grade: ${SSL_LABS_HOST_GRADE}"
- fi
-
- if [ -n "${VERBOSE}" ] ; then
- echo "SSL Labs grade: ${SSL_LABS_HOST_GRADE}"
- fi
-
- convert_ssl_lab_grade "${SSL_LABS_HOST_GRADE}"
- SSL_LABS_HOST_GRADE_NUMERIC="${NUMERIC_SSL_LAB_GRADE}"
-
- add_performance_data "ssllabs=${SSL_LABS_HOST_GRADE_NUMERIC}%;;${SSL_LAB_ASSESSMENT_NUMERIC}"
-
- # Check the grade
- if [ "${SSL_LABS_HOST_GRADE_NUMERIC}" -lt "${SSL_LAB_ASSESSMENT_NUMERIC}" ] ; then
- critical "SSL Labs grade is ${SSL_LABS_HOST_GRADE} (instead of ${SSL_LAB_ASSESSMENT})"
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] SSL Labs grade (converted): ${SSL_LABS_HOST_GRADE_NUMERIC}"
- fi
-
- # We have a result: exit
- break
-
- fi
- ;;
- 'IN_PROGRESS')
- # Data not yet available: warn and continue
- if [ -n "${VERBOSE}" ] ; then
- echo "Warning: no cached data by SSL Labs, check initiated"
- fi
- ;;
- 'DNS')
- if [ -n "${VERBOSE}" ] ; then
- echo 'SSL Labs cannot resolve the domain name'
- fi
- ;;
- *)
- # Try to extract a message
- SSL_LABS_ERROR_MESSAGE=$(echo "${JSON}" \
- | sed 's/.*"message":[ ]*"\([^"]*\)".*/\1/')
-
- if [ -z "${SSL_LABS_ERROR_MESSAGE}" ] ; then
- SSL_LABS_ERROR_MESSAGE="${JSON}"
- fi
-
- critical "Cannot check status on SSL Labs: ${SSL_LABS_ERROR_MESSAGE}"
- esac
-
- WAIT_TIME=60
- if [ -n "${VERBOSE}" ] ; then
- echo "Waiting ${WAIT_TIME} seconds"
- fi
-
- sleep "${WAIT_TIME}"
-
- done
-
- fi
-
- ################################################################################
- # Check revocation via OCSP
- if [ -n "${OCSP}" ]; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] Checking revokation via OCSP"
- fi
-
- ISSUER_HASH="$($OPENSSL x509 -in "${CERT}" -noout -issuer_hash)"
-
- if [ -z "${ISSUER_HASH}" ] ; then
- unknown 'unable to find issuer certificate hash.'
- fi
-
- if [ -n "${ISSUER_CERT_CACHE}" ] ; then
-
- if [ -r "${ISSUER_CERT_CACHE}/${ISSUER_HASH}.crt" ]; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] Found cached Issuer Certificate: ${ISSUER_CERT_CACHE}/${ISSUER_HASH}.crt"
- fi
- ISSUER_CERT="${ISSUER_CERT_CACHE}/${ISSUER_HASH}.crt"
-
- else
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] Not found cached Issuer Certificate: ${ISSUER_CERT_CACHE}/${ISSUER_HASH}.crt"
- fi
-
- fi
-
- fi
-
- if [ -z "${ISSUER_CERT}" ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] OCSP: fetching issuer certificate ${ISSUER_URI} to ${ISSUER_CERT_TMP}"
- fi
-
- exec_with_timeout "$TIMEOUT" "${CURL_BIN} --silent --location ${ISSUER_URI} > ${ISSUER_CERT_TMP}"
-
- if [ -n "${DEBUG}" ] ; then
-
- echo "[DBG] OCSP: issuer certificate type: $(${FILE_BIN} "${ISSUER_CERT_TMP}" | sed 's/.*://' )"
-
- fi
-
- # check the result
- if ! "${FILE_BIN}" "${ISSUER_CERT_TMP}" | grep -E -q ': (ASCII|PEM)' ; then
-
- if "${FILE_BIN}" "${ISSUER_CERT_TMP}" | grep -q ': data' ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] OCSP: converting issuer certificate from DER to PEM"
- fi
-
- cp "${ISSUER_CERT_TMP}" "${ISSUER_CERT_TMP2}"
-
- $OPENSSL x509 -inform DER -outform PEM -in "${ISSUER_CERT_TMP2}" -out "${ISSUER_CERT_TMP}"
-
- else
-
- unknown "Unable to fetch OCSP issuer certificate."
-
- fi
-
- fi
-
- if [ -n "${DEBUG}" ] ; then
-
- # remove trailing /
- FILE_NAME=${ISSUER_URI%/}
-
- # remove everything up to the last slash
- FILE_NAME=${FILE_NAME##*/}
-
- echo "[DBG] OCSP: storing a copy of the retrieved issuer certificate to ${FILE_NAME}"
-
- cp "${ISSUER_CERT_TMP}" "${FILE_NAME}"
- fi
-
- if [ -n "${ISSUER_CERT_CACHE}" ] ; then
- if [ ! -w "${ISSUER_CERT_CACHE}" ]; then
-
- unknown "Issuer certificates cache ${ISSUER_CERT_CACHE} is not writeable!"
-
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] Storing Issuer Certificate to cache: ${ISSUER_CERT_CACHE}/${ISSUER_HASH}.crt"
- fi
-
- cp "${ISSUER_CERT_TMP}" "${ISSUER_CERT_CACHE}/${ISSUER_HASH}.crt"
-
- fi
-
- ISSUER_CERT=${ISSUER_CERT_TMP}
-
- fi
- OCSP_HOST="$(echo "${OCSP_URI}" | sed -e "s@.*//\\([^/]\\+\\)\\(/.*\\)\\?\$@\\1@g" | sed 's/^http:\/\///' | sed 's/\/.*//' )"
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] OCSP: host = ${OCSP_HOST}"
- fi
-
- if [ -n "${OCSP_HOST}" ] ; then
-
- # check if -header is supported
- OCSP_HEADER=""
-
- # ocsp -header is supported in OpenSSL versions from 1.0.0, but not documented until 1.1.0
- # so we check if the major version is greater than 0
- if "${OPENSSL}" version | grep -q '^LibreSSL' || [ "$( ${OPENSSL} version | sed -e 's/OpenSSL \([0-9]\).*/\1/g' )" -gt 0 ] ; then
-
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] openssl ocsp supports the -header option"
- fi
-
- # the -header option was first accepting key and value separated by space. The newer versions are using key=value
- KEYVALUE=""
- if openssl ocsp -help 2>&1 | grep header | grep -q 'key=value' ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] openssl ocsp -header requires 'key=value'"
- fi
- KEYVALUE=1
- else
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] openssl ocsp -header requires 'key value'"
- fi
- fi
-
- # http_proxy is sometimes lower- and sometimes uppercase. Programs usually check both
- # shellcheck disable=SC2154
- if [ -n "${http_proxy}" ] ; then
- HTTP_PROXY="${http_proxy}"
- fi
-
- if [ -n "${HTTP_PROXY:-}" ] ; then
-
- if [ -n "${KEYVALUE}" ] ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing $OPENSSL ocsp -no_nonce -issuer ${ISSUER_CERT} -cert ${CERT} -host ${HTTP_PROXY#*://} -path ${OCSP_URI} -header HOST=${OCSP_HOST}"
- fi
- OCSP_RESP="$($OPENSSL ocsp -no_nonce -issuer "${ISSUER_CERT}" -cert "${CERT}" -host "${HTTP_PROXY#*://}" -path "${OCSP_URI}" -header HOST="${OCSP_HOST}" 2>&1 )"
- else
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing $OPENSSL ocsp -no_nonce -issuer ${ISSUER_CERT} -cert ${CERT} -host ${HTTP_PROXY#*://} -path ${OCSP_URI} -header HOST ${OCSP_HOST}"
- fi
- OCSP_RESP="$($OPENSSL ocsp -no_nonce -issuer "${ISSUER_CERT}" -cert "${CERT}" -host "${HTTP_PROXY#*://}" -path "${OCSP_URI}" -header HOST "${OCSP_HOST}" 2>&1 )"
- fi
-
- else
-
- if [ -n "${KEYVALUE}" ] ; then
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing $OPENSSL ocsp -no_nonce -issuer ${ISSUER_CERT} -cert ${CERT} -url ${OCSP_URI} ${OCSP_HEADER} -header HOST=${OCSP_HOST}"
- fi
- OCSP_RESP="$($OPENSSL ocsp -no_nonce -issuer "${ISSUER_CERT}" -cert "${CERT}" -url "${OCSP_URI}" -header "HOST=${OCSP_HOST}" 2>&1 )"
- else
- if [ -n "${DEBUG}" ] ; then
- echo "[DBG] executing $OPENSSL ocsp -no_nonce -issuer ${ISSUER_CERT} -cert ${CERT} -url ${OCSP_URI} ${OCSP_HEADER} -header HOST ${OCSP_HOST}"
- fi
- OCSP_RESP="$($OPENSSL ocsp -no_nonce -issuer "${ISSUER_CERT}" -cert "${CERT}" -url "${OCSP_URI}" -header HOST "${OCSP_HOST}" 2>&1 )"
- fi
-
- fi
-
- if [ -n "${DEBUG}" ] ; then
- echo "${OCSP_RESP}" | sed 's/^/[DBG] OCSP: response = /'
- fi
-
- if echo "${OCSP_RESP}" | grep -qi "revoked" ; then
- critical "certificate is revoked"
- elif ! echo "${OCSP_RESP}" | grep -qi "good" ; then
-
- if [ -n "${HTTP_PROXY:-}" ] ; then
- OCSP_RESP="$($OPENSSL ocsp -no_nonce -issuer "${ISSUER_CERT}" -cert "${CERT}" -host "${HTTP_PROXY#*://}" -path "${OCSP_URI}" "${OCSP_HEADER}" 2>&1 )"
- else
- OCSP_RESP="$($OPENSSL ocsp -no_nonce -issuer "${ISSUER_CERT}" -cert "${CERT}" -url "${OCSP_URI}" "${OCSP_HEADER}" 2>&1 )"
- fi
- critical "${OCSP_RESP}"
-
- fi
-
- else
-
- if [ -n "${VERBOSE}" ] ; then
- echo "openssl ocsp does not support the -header option: disabling OCSP checks"
- fi
-
- fi
-
- else
-
- if [ -n "${VERBOSE}" ] ; then
- echo "no OCSP host found: disabling OCSP checks"
- fi
-
- fi
-
- fi
-
- ################################################################################
- # Check the organization
- if [ -n "$ORGANIZATION" ] ; then
-
- ORG=$($OPENSSL x509 -in "${CERT}" -subject -noout | sed -e "s/.*\\/O=//" -e "s/\\/.*//")
-
- if ! echo "$ORG" | grep -q "^$ORGANIZATION" ; then
- critical "invalid organization ('$ORGANIZATION' does not match '$ORG')"
- fi
-
- fi
-
- ################################################################################
- # Check the organization
- if [ -n "$ADDR" ] ; then
-
- EMAIL=$($OPENSSL x509 -in "${CERT}" -email -noout)
-
- if [ -n "${VERBOSE}" ] ; then
- echo "checking email (${ADDR}): ${EMAIL}"
- fi
-
- if [ -z "${EMAIL}" ] ; then
- critical "the certificate does not contain an email address"
- fi
-
- if ! echo "$EMAIL" | grep -q "^$ADDR" ; then
- critical "invalid email ($ADDR does not match $EMAIL)"
- fi
-
- fi
-
- ################################################################################
- # Check if the certificate was verified
- if [ -z "${NOAUTH}" ] && grep -q '^verify\ error:' "${ERROR}" ; then
-
- if grep -q '^verify\ error:num=[0-9][0-9]*:self\ signed\ certificate' "${ERROR}" ; then
-
- if [ -z "${SELFSIGNED}" ] ; then
- critical "Cannot verify certificate, self signed certificate"
- else
- SELFSIGNEDCERT="self signed "
- fi
-
- else
-
- if [ -n "${DEBUG}" ] ; then
- sed 's/^/[DBG] Error: /' "${ERROR}"
- fi
-
- # Process errors
- details=$( grep '^verify\ error:' "${ERROR}" | sed 's/verify\ error:num=[0-9]*://' | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/, /g' )
- critical "Cannot verify certificate: ${details}"
-
- fi
-
- fi
-
- ################################################################################
- # If we get this far, assume all is well. :)
-
- # If --altnames was specified or if the certificate is wildcard,
- # then we show the specified CN in addition to the certificate CN
- CHECKEDNAMES=""
- if [ -n "${ALTNAMES}" ] && [ -n "${COMMON_NAME}" ] && [ "${CN}" != "${COMMON_NAME}" ]; then
- CHECKEDNAMES="(${COMMON_NAME}) "
- elif [ -n "${COMMON_NAME}" ] && echo "${CN}" | grep -q -i "^\\*\\." ; then
- CHECKEDNAMES="(${COMMON_NAME}) "
- fi
-
- if [ -n "${DAYS_VALID}" ] ; then
- # nicer formatting
- if [ "${DAYS_VALID}" -gt 1 ] ; then
- DAYS_VALID=" (expires in ${DAYS_VALID} days)"
- elif [ "${DAYS_VALID}" -eq 1 ] ; then
- DAYS_VALID=" (expires tomorrow)"
- elif [ "${DAYS_VALID}" -eq 0 ] ; then
- DAYS_VALID=" (expires today)"
- elif [ "${DAYS_VALID}" -eq -1 ] ; then
- DAYS_VALID=" (expired yesterday)"
- else
- DAYS_VALID=" (expired ${DAYS_VALID} days ago)"
- fi
- fi
-
- if [ -n "${SSL_LABS_HOST_GRADE}" ] ; then
- SSL_LABS_HOST_GRADE=", SSL Labs grade: ${SSL_LABS_HOST_GRADE}"
- fi
-
- if [ -z "${CN}" ]; then
- DISPLAY_CN=""
- else
- DISPLAY_CN="'${CN}' "
- fi
-
- if [ -z "$FORMAT" ]; then
- if [ -n "${TERSE}" ]; then
- FORMAT="%SHORTNAME% OK %CN% %DAYS_VALID%"
- else
- FORMAT="%SHORTNAME% OK - %OPENSSL_COMMAND% %SELFSIGNEDCERT%certificate %DISPLAY_CN%%CHECKEDNAMES%from '%CA_ISSUER_MATCHED%' valid until %DATE%%DAYS_VALID%%SSL_LABS_HOST_GRADE%"
- fi
- fi
-
- if [ -n "${TERSE}" ]; then
- EXTRA_OUTPUT="${PERFORMANCE_DATA}"
- else
- EXTRA_OUTPUT="${LONG_OUTPUT}${PERFORMANCE_DATA}"
- fi
-
- echo "${FORMAT}${EXTRA_OUTPUT}" | sed \
- -e "$( var_for_sed CA_ISSUER_MATCHED "${CA_ISSUER_MATCHED}" )" \
- -e "$( var_for_sed CHECKEDNAMES "${CHECKEDNAMES}" )" \
- -e "$( var_for_sed CN "${CN}" )" \
- -e "$( var_for_sed DATE "${DATE}" )" \
- -e "$( var_for_sed DAYS_VALID "${DAYS_VALID}" )" \
- -e "$( var_for_sed DISPLAY_CN "${DISPLAY_CN}" )" \
- -e "$( var_for_sed OPENSSL_COMMAND "${OPENSSL_COMMAND}" )" \
- -e "$( var_for_sed SELFSIGNEDCERT "${SELFSIGNEDCERT}" )" \
- -e "$( var_for_sed SHORTNAME "${SHORTNAME}" )" \
- -e "$( var_for_sed SSL_LABS_HOST_GRADE "${SSL_LABS_HOST_GRADE}" )"
-
- remove_temporary_files
-
- exit 0
-
-}
-
-if [ -z "${SOURCE_ONLY}" ]; then
- main "${@}"
-fi
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.1 nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.1
--- nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.1 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.1 1970-01-01 00:00:00.000000000 +0000
@@ -1,208 +0,0 @@
-.\" Process this file with
-.\" groff -man -Tascii foo.1
-.\"
-.TH "check_ssl_cert" 1 "September, 2018" "1.73.0" "USER COMMANDS"
-.SH NAME
-check_ssl_cert \- checks the validity of X.509 certificates
-.SH SYNOPSIS
-.BR "check_ssl_cert " "-H host [OPTIONS]"
-.SH DESCRIPTION
-.B check_ssl_cert
-A Nagios plugin to check an X.509 certificate:
- - checks if the server is running and delivers a valid certificate
- - checks if the CA matches a given pattern
- - checks the validity
-.SH ARGUMENTS
-.TP
-.BR "-H,--host" " host"
-server
-.SH OPTIONS
-.TP
-.BR "-A,--noauth"
-ignore authority warnings (expiration only)
-.TP
-.BR " --altnames"
-matches the pattern specified in -n with alternate names too
-.TP
-.BR "-C,--clientcert" " path"
-use client certificate to authenticate
-.TP
-.BR " --clientpass" " phrase"
-set passphrase for client certificate.
-.TP
-.BR "-c,--critical" " days"
-minimum number of days a certificate has to be valid to issue a critical status
-.TP
-.BR " --curl-bin" " path"
-path of the curl binary to be used"
-.TP
-.BR "-d,--debug"
-produces debugging output
-.TP
-.BR " --ecdsa"
-cipher selection: force ECDSA authentication
-.TP
-.BR "-e,--email" " address"
-pattern to match the email address contained in the certificate
-.TP
-.BR "-f,--file" " file"
-local file path (works with -H localhost only) with -f you can not only pass a x509 certificate file but also a certificate revocation list (CRL) to check the validity period
-.TP
-.BR " --file-bin" " path"
-path of the file binary to be used
-.TP
-.BR " --fingerprint" " SHA1"
-pattern to match the SHA1-Fingerprint
-.TP
-.BR " --force-perl-date"
-force the usage of Perl for date computations
-.TP
-.BR " --format" " FORMAT"
-custom output format (e.g. "%SHORTNAME% OK %CN% from '%CA_ISSUER_MATCHED%'")
-.TP
-.BR "-h,--help,-?"
-this help message
-.TP
-.BR " --ignore-exp"
-ignore expiration date
-.TP
-.BR " --ignore-ocsp"
-do not check revocation with OCSP
-.TP
-.BR " --ignore-sig-alg"
-do not check if the certificate was signed with SHA1 or MD5
-.TP
-.BR " --ignore-ssl-labs-cache"
-Forces a new check by SSL Labs (see -L)
-.TP
-.BR " --issuer-cert-cache" " dir"
-directory where to store issuer certificates cache
-.TP
-.BR "-i,--issuer" " issuer"
-pattern to match the issuer of the certificate
-.TP
-.BR "-L,--check-ssl-labs grade"
-SSL Labs assestment (please check https://www.ssllabs.com/about/terms.html)
-.TP
-.BR " --long-output" " list"
-append the specified comma separated (no spaces) list of attributes to the plugin output on additional lines.
-Valid attributes are: enddate, startdate, subject, issuer, modulus, serial, hash, email, ocsp_uri and fingerprint. 'all' will include all the available attributes.
-.TP
-.BR "-n,--cn" " name"
-pattern to match the CN of the certificate (can be specified multiple times)
-.TP
-.BR " --no_ssl2"
-disable SSL version 2
-.TP
-.BR " --no_ssl3"
-disable SSL version 3
-.TP
-.BR " --no_tls1"
-disable TLS version 1
-.TP
-.BR " --no_tls1_1"
-disable TLS version 1.1
-.TP
-.BR " --no_tls1_2"
-disable TLS version 1.2
-.TP
-.BR "-N,--host-cn"
-match CN with the host name
-.TP
-.BR "-o,--org" " org"
-pattern to match the organization of the certificate
-.TP
-.BR " --openssl" " path"
-path of the openssl binary to be used
-.TP
-.BR "-p,--port" " port"
-TCP port
-.TP
-.BR "-P,--protocol" " protocol"
-use the specific protocol: http (default), irc or smtp,pop3,imap,ftp,ldap (switch to TLS)
-.TP
-.BR "-s,--selfsigned"
-allows self-signed certificates
-.TP
-.BR " --serial serialnum"
-pattern to match the serial number
-.TP
-.BR " --sni name"
-sets the TLS SNI (Server Name Indication) extension in the ClientHello message to 'name'
-.TP
-.BR " --ssl2"
-force SSL version 2
-.TP
-.BR " --ssl3"
-force SSL version 3
-.TP
-.BR " --require-ocsp-stapling"
-require OCSP stapling
-.TP
-.BR " --require-san"
-require the presence of a Subject Alternative Name extension
-.TP
-.BR "-r,--rootcert" " cert"
-root certificate or directory to be used for certficate validation (passed to openssl's -CAfile or -CApath)
-.TP
-.BR " --rsa"
-cipher selection: force RSA authentication
-.TP
-.BR " --temp" " dir"
-directory where to store the temporary files
-.TP
-.BR " --terse"
-terse output (also see --verbose)
-.TP
-.BR "-t,--timeout"
-seconds timeout after the specified time (defaults to 15 seconds)
-.TP
-.BR " --tls1"
-force TLS version 1
-.TP
-.BR " --tls1_1"
-force TLS version 1.1
-.TP
-.BR " --tls1_2"
-force TLS version 1.2
-.TP
-.BR " --tls1_3"
-force TLS version 1.3
-.TP
-.BR "-v,--verbose"
-verbose output (also see --terse)
-.TP
-.BR "-V,--version"
-version
-.TP
-.BR "-w,--warning" " days"
-minimum number of days a certificate has to be valid to issue a warning status
-.TP
-.BR " --xmpphost" " name"
-specifies the host for the "to" attribute of the stream element
-.SH DEPRECATED OPTIONS
-.TP
-.BR "-d,--days" " days"
-minimum number of days a certificate has to be valid (see --critical and --warning)
-.TP
-.BR " --ocsp"
-check revocation via OCSP
-.TP
-.BR "-S,--ssl" " version"
-force SSL version (2,3) (see: --ssl2 or --ssl3)
-
-.SH MULTIPLE CERTIFICATES
-If the host has multiple certificates and the installed openssl version supports the -servername option it is possible to specify the TLS SNI (Server Name Idetificator) with the -N (or --host-cn) option.
-
-.SH "SEE ALSO"
-x509(1), openssl(1), expect(1), timeout(1)
-.SH "EXIT STATUS"
-check_ssl_cert returns a zero exist status if it finds no errors, 1 for warnings, 2 for a critical errors and 3 for unknown problems
-.SH BUGS
-Please report bugs to:
-
-https://github.com/matteocorti/check_ssl_cert/issues
-.SH AUTHOR
-Matteo Corti (matteo (at) corti.li )
-See the AUTHORS file for the complete list of contributors
-
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.spec nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.spec
--- nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.spec 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/check_ssl_cert.spec 1970-01-01 00:00:00.000000000 +0000
@@ -1,365 +0,0 @@
-%define version 1.73.0
-%define release 0
-%define sourcename check_ssl_cert
-%define packagename nagios-plugins-check_ssl_cert
-%define nagiospluginsdir %{_libdir}/nagios/plugins
-
-# No binaries in this package
-%define debug_package %{nil}
-
-Summary: A Nagios plugin to check X.509 certificates
-Name: %{packagename}
-Version: %{version}
-Obsoletes: check_ssl_cert
-Release: %{release}%{?dist}
-License: GPLv3+
-Packager: Matteo Corti
-Group: Applications/System
-BuildRoot: %{_tmppath}/%{packagename}-%{version}-%{release}-root-%(%{__id_u} -n)
-URL: https://github.com/matteocorti/check_ssl_cert
-Source: https://github.com/matteocorti/check_ssl_cert/releases/download/v%{version}/check_ssl_cert-%{version}.tar.gz
-
-Requires: nagios-plugins expect perl(Date::Parse)
-
-%description
-Checks an X.509 certificate:
- - checks if the server is running and delivers a valid certificate
- - checks if the CA matches a given pattern
- - checks the validity
-
-%prep
-%setup -q -n %{sourcename}-%{version}
-
-%build
-
-%install
-make DESTDIR=${RPM_BUILD_ROOT}%{nagiospluginsdir} MANDIR=${RPM_BUILD_ROOT}%{_mandir} install
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root,-)
-%doc AUTHORS ChangeLog NEWS README.md TODO COPYING VERSION COPYRIGHT
-%attr(0755, root, root) %{nagiospluginsdir}/check_ssl_cert
-%{_mandir}/man1/%{sourcename}.1*
-
-%changelog
-* Mon Sep 10 2018 Matteo Corti - 1.73.0-0
-- Updated to 1.73.0
-
-* Sun Jul 30 2018 Matteo Corti - 1.72.0-0
-- Updated to 1.72.0
-
-* Sun Jul 30 2018 Matteo Corti - 1.71.0-0
-- Updated to 1.71.0
-
-* Mon Jun 28 2018 Matteo Corti - 1.70.0-0
-- Updated to 1.70.0
-
-* Mon Jun 25 2018 Matteo Corti - 1.69.0-0
-- Updated to 1.69.0
-
-* Sun Apr 29 2018 Matteo Corti - 1.68.0-0
-- Updated to 1.68.0
-
-* Tue Apr 17 2018 Matteo Corti - 1.67.0-0
-- Updated to 1.67.0
-
-* Fri Apr 6 2018 Matteo Corti - 1.66.0-0
-- Updated to 1.66.0
-
-* Thu Mar 29 2018 Matteo Corti - 1.65.0-0
-- Updated to 1.65.0
-
-* Wed Mar 28 2018 Matteo Corti - 1.64.0-0
-- Updated to 1.64.0
-
-* Sat Mar 17 2018 Matteo Corti - 1.63.0-0
-- Updated to 1.63.0
-
-* Tue Mar 6 2018 Matteo Corti - 1.62.0-0
-- Updated to 1.62.0
-
-* Fri Jan 19 2018 Matteo Corti - 1.61.0-0
-- Updated to 1.61.0
-
-* Fri Dec 15 2017 Matteo Corti - 1.60.0-0
-- Updated to 1.60.0
-
-* Thu Dec 14 2017 Matteo Corti - 1.59.0-0
-- Updated to 1.59.0
-
-* Wed Nov 29 2017 Matteo Corti - 1.58.0-0
-- Updated to 1.58.0
-
-* Tue Nov 28 2017 Matteo Corti - 1.57.0-0
-- Updated to 1.57.0
-
-* Fri Nov 17 2017 Matteo Corti - 1.56.0-0
-- Updated to 1.56.0
-
-* Thu Nov 16 2017 Matteo Corti - 1.55.0-0
-- Updated to 1.55.0
-
-* Tue Sep 19 2017 Matteo Corti - 1.54.0-0
-- Updated to 1.54.0
-
-* Sun Sep 10 2017 Matteo Corti - 1.53.0-0
-- Updated to 1.53.0
-
-* Sat Sep 9 2017 Matteo Corti - 1.52.0-0
-- Updated to 1.52.0
-
-* Fri Jul 28 2017 Matteo Corti - 1.51.0-0
-- Updated to 1.51.0
-
-* Mon Jul 24 2017 Matteo Corti - 1.50.0-0
-- Updated to 1.50.0
-
-* Mon Jul 17 2017 Matteo Corti - 1.49.0-0
-- Updated to 1.49.0
-
-* Fri Jun 23 2017 Matteo Corti - 1.48.0-0
-- Updated to 1.48.0
-
-* Thu Jun 15 2017 Matteo Corti - 1.47.0-0
-- Updated to 1.47.0
-
-* Mon May 15 2017 Matteo Corti - 1.46.0-0
-- Updated to 1.46.0
-
-* Tue May 2 2017 Matteo Corti - 1.45.0-0
-- Updated to 1.45.0
-
-* Fri Apr 28 2017 Matteo Corti - 1.44.0-0
-- Updated to 1.44.0
-
-* Thu Mar 7 2017 Matteo Corti - 1.43.0-0
-- Updated to 1.43.0
-
-* Thu Feb 16 2017 Matteo Corti - 1.42.0-0
-- Updated to 1.42.0
-
-* Wed Feb 10 2017 Matteo Corti - 1.41.0-0
-- Updated to 1.41.0
-
-* Wed Feb 8 2017 Matteo Corti - 1.40.0-0
-- Updated to 1.40.0
-
-* Thu Feb 2 2017 Matteo Corti - 1.39.0-0
-- Updated to 1.39.0
-
-* Thu Feb 2 2017 Matteo Corti - 1.38.2-0
-- Updated to 1.38.2
-
-* Sun Jan 29 2017 Matteo Corti - 1.38.1-0
-- Updated to 1.38.1
-
-* Sat Jan 28 2017 Matteo Corti - 1.38.0-0
-- Updated to 1.38.0
-
-* Fri Dec 23 2016 Matteo Corti - 1.37.0-0
-- Updated to 1.37.0
-
-* Tue Dec 13 2016 Matteo Corti - 1.36.2-0
-- Updated to 1.36.2
-
-* Tue Dec 06 2016 Matteo Corti - 1.36.1-0
-- Updated to 1.36.1
-
-* Sun Dec 04 2016 Matteo Corti - 1.36.0-0
-- Updated to 1.36.0
-
-* Tue Oct 18 2016 Matteo Corti - 1.35.0-0
-- Updated to 1.35.0
-
-* Mon Sep 19 2016 Matteo Corti - 1.34.0-0
-- Updated to 1.34.0
-
-* Thu Aug 4 2016 Matteo Corti - 1.33.0-0
-- Updated to 1.33.0
-
-* Fri Jul 29 2016 Matteo Corti - 1.32.0-0
-- Updated to 1.32.0
-
-* Tue Jul 12 2016 Matteo Corti - 1.31.0-0
-- Updated to 1.31.0
-
-* Thu Jun 30 2016 Matteo Corti - 1.30.0-0
-- Updated to 1.30.0
-
-* Wed Jun 15 2016 Matteo Corti - 1.29.0-0
-- Updated to 1.29.0
-
-* Wed Jun 01 2016 Matteo Corti - 1.28.0-0
-- Updated to 1.28.0
-
-* Wed Apr 27 2016 Matteo Corti - 1.27.0-0
-- Updated to 1.27.0
-
-* Tue Mar 29 2016 Matteo Corti - 1.26.0-0
-- Updated to 1.26.0
-
-* Mon Mar 21 2016 Matteo Corti - 1.25.0-0
-- Updated to 1.25.0
-
-* Wed Mar 9 2016 Matteo Corti - 1.24.0-0
-- Updated to 1.24.0
-
-* Mon Mar 7 2016 Matteo Corti - 1.23.0-0
-- Updated to 1.23.0
-
-* Thu Mar 3 2016 Matteo Corti - 1.22.0-0
-- Updated to 1.22.0
-
-* Tue Mar 1 2016 Matteo Corti - 1.21.0-0
-- Updated to 1.21.0
-
-* Fri Feb 26 2016 Matteo Corti - 1.20.0-0
-- Updated to 1.20.0
-
-* Thu Feb 25 2016 Matteo Corti - 1.19.0-0
-- Updated to 1.19.0
-
-* Sat Oct 31 2015 Matteo Corti - 1.18.0-0
-- Updated to 1.18.0
-
-* Tue Oct 20 2015 Matteo Corti - 1.17.2-0
-- Updated to 1.17.2
-
-* Tue Apr 7 2015 Matteo Corti - 1.17.1-0
-- Updated to 1.17.1
-
-* Tue Oct 21 2014 Matteo Corti - 1.17.0-0
-- Updated to 1.17.0
-
-* Fri Jun 6 2014 Matteo Corti - 1.16.2-0
-- updated to 1.16.2
-
-* Thu May 22 2014 Andreas Dijkman - 1.16.1-1
-- Added noarch as buildarch
-- Added expect and perl(Date::Parse) dependency
-
-* Fri Feb 28 2014 Matteo Corti - 1.16.1-0
-- Updated to 1.16.1 (rpm make target)
-
-* Mon Dec 23 2013 Matteo Corti - 1.16.0-0
-- Udated to 1.16.0 (force TLS)
-
-* Mon Jul 29 2013 Matteo Corti - 1.15.0-0
-- Updated to 1.15.0 (force SSL version)
-
-* Sun May 12 2013 Matteo Corti - 1.14.6-0
-- Updated to 1.16.6 (timeout and XMPP support)
-
-* Sat Mar 2 2013 Matteo Corti - 1.14.5-0
-- Updated to 1.14.5 (TLS and multiple names fix)
-
-* Fri Dec 7 2012 Matteo Corti - 1.14.4-0
-- Updated to 1.14.4 (bug fix release)
-
-* Wed Sep 19 2012 Matteo Corti - 1.14.3-0
-- Updated to 1.14.3
-
-* Fri Jul 13 2012 Matteo Corti - 1.14.2-0
-- Updated to 1.14.2
-
-* Wed Jul 11 2012 Matteo Corti - 1.14.1-0
-- Updated to 1.14.1
-
-* Fri Jul 6 2012 Matteo Corti - 1.14.0-0
-- updated to 1.14.0
-
-* Thu Apr 5 2012 Matteo Corti - 1.13.0-0
-- updated to 1.13.0
-
-* Wed Apr 4 2012 Matteo Corti - 1.12.0-0
-- updated to 1.12.0 (bug fix release)
-
-* Sat Oct 22 2011 Matteo Corti - 1.11.0-0
-- ipdated to 1.10.1 (--altnames option)
-
-* Thu Sep 1 2011 Matteo Corti - 1.10.0-0
-- apllied patch from Sven Nierlein for client certificate authentication
-
-* Thu Mar 10 2011 Matteo Corti - 1.9.1-0
-- updated to 1.9.1: allows http as protocol and fixes -N with wildcards
-
-* Mon Jan 24 2011 Matteo Corti - 1.9.0-0
-- updated to 1.9.0: --openssl option
-
-* Thu Dec 16 2010 Dan Wallis - 1.8.1-0
-- Fixed bugs with environment bleeding & shell globbing
-
-* Thu Dec 9 2010 Matteo Corti - 1.8.0-0
-- added support for TLS servername extension
-
-* Thu Oct 28 2010 Matteo Corti - 1.7.7-0
-- Fixed a bug in the signal specification
-
-* Thu Oct 28 2010 Matteo Corti - 1.7.6-0
-- better temporary file clean up
-
-* Thu Oct 14 2010 Matteo Corti - 1.7.5-0
-- updated to 1.7.5 (fixed the check order)
-
-* Fri Oct 1 2010 Matteo Corti - 1.7.4-0
-- added -A command line option
-
-* Wed Sep 15 2010 Matteo Corti - 1.7.3-0
-- Fixed a bug in the command line options processing
-
-* Thu Aug 26 2010 Dan Wallis - 1.7.2-0
-- updated to 1.7.2 (cat and expect fixes)
-
-* Thu Aug 26 2010 Dan Wallis - 1.7.1-0
-- updated to 1.7.1 ("-verify 6" revert)
-
-* Thu Aug 26 2010 Dan Wallis - 1.7.0-0
-
-* Wed Jul 21 2010 Matteo Corti - 1.6.1-0
-- updated to 1.6.0 (--temp option)
-
-* Fri Jul 9 2010 Matteo Corti - 1.6.0-0
-- updated to version 1.6.0 (long options, --critical and --warning, man page)
-
-* Wed Jul 7 2010 Matteo Corti - 1.5.2-0
-- updated to version 1.5.2 (Wolfgang Schricker patch, see ChangeLog)
-
-* Thu Jul 1 2010 Matteo Corti - 1.5.1-0
-- updated to version 1.5.1 (Yannick Gravel patch, see ChangeLog)
-
-* Tue Jun 8 2010 Matteo Corti - 1.5.0-0
-- updated to version 1.5.0 (-s option to allow self signed certificates)
-
-* Thu Mar 11 2010 Matteo Corti - 1.4.4-0
-- updated to 1.4.4 (bug fix release)
-
-* Tue Mar 9 2010 Matteo Corti - 1.4.3-0
-- updated to 1.4.3 (-n and -N options)
-
-* Wed Dec 2 2009 Matteo Corti - 1.4.2-0
-- updated to 1.4.2
-
-* Mon Nov 30 2009 Matteo Corti - 1.4.1-0
-- updated to 1.4.1 (-r option)
-
-* Mon Nov 30 2009 Matteo Corti - 1.4.0-0
-- Updated to 1.4.0: verify the certificate chain
-
-* Mon Mar 30 2009 Matteo Corti - 1.3.0-0
-- Tuomas Haarala patch: -P option
-
-* Tue May 13 2008 Matteo Corti - 1.2.2-0
-- Dan Wallis patch to include the CN in the messages
-
-* Mon Feb 25 2008 Matteo Corti - 1.2.1-0
-- Dan Wallis patches (error checking, see ChangeLog)
-
-* Mon Feb 25 2008 Matteo Corti - 1.2.0-0
-- Dan Wallis patches (see the ChangeLog)
-
-* Mon Sep 24 2007 Matteo Corti - 1.1.0-0
-- first RPM package
-
diff -Nru nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/COPYING nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/COPYING
--- nagios-plugins-contrib-22.20181105+1/check_ssl_cert/check_ssl_cert-1.73.0/COPYING 2018-11-05 00:02:43.000000000 +0000
+++ nagios-plugins-contrib-23.20190206/check_ssl_cert/check_ssl_cert-1.73.0/COPYING 1970-01-01 00:00:00.000000000 +0000
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- 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 3 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, see