Quellcode durchsuchen

Merge branch 'maint' into patch-2

Bryan Heden vor 7 Jahren
Ursprung
Commit
6a5ba79142

+ 1 - 0
.gitignore

@@ -4,6 +4,7 @@ cscope.out
 nbproject/
 .kdev4/
 plugins.kdev4
+plugins.project
 
 # In all paths
 NP-VERSION-FILE

+ 3 - 0
Makefile.am

@@ -29,6 +29,9 @@ dist-hook:
 install-root:
 	cd plugins-root && $(MAKE) $@
 
+install-packager:
+	cd plugins-root && $(MAKE) $@
+
 test test-debug:
 	cd lib && $(MAKE) $@
 	if test "$(PERLMODS_DIR)" != ""; then cd perlmods && $(MAKE) $@; fi

+ 44 - 0
NEWS

@@ -1,5 +1,48 @@
 This file documents the major additions and syntax changes between releases.
 
+2.3.0 xxxx-xx-xx
+	ENHANCEMENTS
+	Added directory plugins-python containing three Python plugins
+	Add plugin remove_perfdata to remove perfdata from specified plugin's output
+	Added warning_string/critical_string to struct thresholds for storing originally parsed strings
+	check_http: New parameter `--verify-host` will check if -H hostname matches the SSL certificate
+	check_ping: plugin output will now include hostname and IP address
+	check_disk_smb: Add configfile feature
+	check_apt: Add --only-critical switch
+	check_mailq: Add support for opensmtpd
+	check_mailq: Add mailq -C option for config dir or config file
+	check_disk: Add -s option to show status for each path/partition
+	check_mailq.pl: Add option for opensmtpd (brigriffin)
+	check_procs: Add FreeBSD jail support (Mathieu Arnold)
+	check_procs: Allow process to be excluded from check_procs (Marcel Klein)
+	check_ldap: Add support for checking LDAP cert age (Guillaume Rousse)
+	check_icmp: Add Jitter, MOS, Score (Alessandro Ren)
+	check_radius: Add calling-station-id (cejkar)
+	ssl_utils: Added certificate expiry data in OK status (check_http, check_smtp, check_tcp) (Matt Capra)
+
+
+2.2.2 xxxx-xx-xx
+	FIXES
+	check_disk: autofs being mounted despite '-l'. Fixed, and also excluded some system "fake" mountpoints
+	check_ntp_time: Periodically returns "Socket timeout" when one of several ntp server doesn't respond
+	check_ntp_time calls `write` on a UDP socket without a successful call to `connect`
+	check_mysql_query & mysql_query: extra-opts causes crash
+	check_log does not check for "-O oldlog"
+	check_log lost ability to use regexes for query (-q) in 2.1.4
+	fix configure.ac for FreeBSD SWAPFORMAT
+	Fix --no-body
+	check_wave produces lots of errors if required arguments are not provided
+	check_disk_smb.pl added additional smb support
+	check_http Additional header/status checking
+	check_http When checking certificate, don't check content/status
+	Fix ax_with_python not crashing on Python3 (Michael Orlitzky)
+	Fix rpmbuild errors (Josh Coughlan)
+	check_ping: FreeBSD ping working natively
+	check_sensors: Fix fault test with --ignore-fault
+	check_snmp: Fix perfdata not adhering to plugin dev guidelines
+	check_snmp: warning/critical perfdata is returned properly
+
+
 2.2.1 2017-04-19
 	FIXES
 	check_users: not accepting zero as the threshold
@@ -17,6 +60,7 @@ This file documents the major additions and syntax changes between releases.
 	check_mailq: Nullmailer Regex is not working for Ubuntu 16.04
 	check_swap: Downstream Fedora patch: Prevent check_swap from returning OK, if no swap activated
 	Building RPMs on Amazon Linux - Add 'install-root' on line 165 of spec file
+	check_http: Memory allocation error
 
 
 2.2.0 2017-01-19

+ 21 - 0
THANKS.in

@@ -18,6 +18,7 @@ Andreas Ericsson
 Andreas Seemueller
 Andrew Berglund
 Andrew Elwell
+Andrew Penniman
 Andrew Widdersheim
 Andy Brist
 Andy Doran
@@ -42,23 +43,28 @@ Booker C. Bense
 Bradley Baetz
 Brian De Wolf
 Brian Landers
+brigriffin
 Bryan Irvine
 Carlos Canau
 Carole Verdon
+cejkar
 Charles-Henri Larose
 Charlie Cook
 Chester Hosey
 Chris Grim
+Chris Heath
 Chris Pepper
 Chris Wilson
 Christian G Warden
 Christian Mies
+Christian Schmidt
 Christian Schneemann
 Christoph Kron
 Christoph Schell
 Christopher Maser
 Christopher Schultz
 Cire Iriarte
+Claudio Kuenzler
 Cliff Rice
 Collin Fair
 Cove Schneider
@@ -119,6 +125,7 @@ Gianluca Varisco
 Grant Byers
 Greg Bowser
 Guenther Mair
+Guillaume Rousse
 Gunnar Beutner
 Gunnar Hellekson
 Guy Van Den Bergh
@@ -174,6 +181,7 @@ John Rouillard
 John Sivak
 John Warburton
 Jon Hallett
+Jon Stockton
 Jon Vandegrift
 Jonas Genannt
 Jonas Genannt
@@ -181,6 +189,7 @@ Jonathan Milby
 Jonathan Rozes
 Joseph Gooch
 Josip Rodin
+Josh Coughlan
 Juan Carlos Fernandez
 Julien Touche
 Julius Kriukas
@@ -196,10 +205,13 @@ Konstantin Khomoutov
 Kyle Tucker
 Lance Albertson
 Larry Low
+Lars Michelsen
 Lars Stavholm
 Lars Vogdt
 Laurent Licour
 Laurent Vaslin
+Lee Clemens
+Leonid Vasiliev
 Lionel Cons
 Lonny Selinger
 Luca Corti
@@ -209,11 +221,13 @@ Lynne Lawrence
 Marc Huffnagle
 Marc Poulin
 Marc Remy
+Marcel Klein
 Marcel Kuiper
 Marco Beck
 Marcos Della
 Mario Trangoni
 Mario Witte
+Mark A. Ziesemer
 Mark Favas
 Mark Jewiss
 Mark Keisler
@@ -221,7 +235,9 @@ Markus Baertschi
 Marlo Bell
 Martin Foster
 Matej Vela
+Mathieu Arnold
 Mathieu Masseboeuf
+Matt Capra
 Matt Garrett
 Matt Perry
 Matt Pounsett
@@ -240,10 +256,12 @@ Michael Bakker
 Michael Haro
 Michael Markstaller
 Michael Musikhin
+Michael Orlitzky
 Michael Tiernan
 Mikael Falkvidd
 Mike Emigh
 Mike McHenry
+mwennrich
 Myke Place
 Nathan Shafer
 Neil Prockter
@@ -344,8 +362,10 @@ StoneISStephan
 Stuart Webster
 Stéphane Bortzmeyer
 Stéphane Urbanovski
+Subito
 Sven Meyer
 Sven Schaffranneck
+Syl Robataille
 Thomas Nilsen
 Thomas Schimpke
 Tilman Koschnick
@@ -359,6 +379,7 @@ Tom Shields
 Tomasz Pilat
 Torsten Werner
 Trevor McDonald
+Troy Lea
 Truongchinh Nguyen
 Vaclav Ovsik
 Valdimir Ivaschenko

+ 46 - 3
configure.ac

@@ -786,6 +786,16 @@ then
 	ac_cv_ps_cols=10
 	AC_MSG_RESULT([$ac_cv_ps_command])
 
+dnl jails on FreeBSD:
+elif ps -axwo 'stat comm vsz rss user uid pid ppid jid args' 2>/dev/null | \
+	egrep -i "^ *STAT +COMMAND +VSZ +RSS +USER +UID +PID +PPID +JID +COMMAND" > /dev/null
+then
+	ac_cv_ps_varlist="procstat,&procuid,&procpid,&procppid,&procjid,&procvsz,&procrss,&procpcpu,procprog,&pos"
+	ac_cv_ps_command="$PATH_TO_PS -axwo 'stat uid pid ppid jid vsz rss pcpu comm args'"
+	ac_cv_ps_format="%s %d %d %d %d %d %d %f %s %n"
+	ac_cv_ps_cols=10
+	AC_MSG_RESULT([$ac_cv_ps_command])
+
 dnl Some gnu/linux systems (debian for one) don't like -axwwo and need axwwo.
 dnl so test for this first...
 elif ps axwwo 'stat comm vsz rss user uid pid ppid args' 2>/dev/null | \
@@ -1065,6 +1075,12 @@ AC_ARG_WITH(ping_command,
 		[sets syntax for ICMP ping]),
 	with_ping_command=$withval,)
 
+dnl AS I WAS LOOKING INTO THIS... (Bryan Heden 09/2017)
+dnl Ping packets first was a bit confusing
+dnl it doesn't actually mean "packet count first"
+dnl it means packets come before specifying host
+dnl If a timeout is specified, that comes first
+
 AC_MSG_CHECKING(for ICMP ping syntax)
 ac_cv_ping_packets_first=no
 ac_cv_ping_has_timeout=no
@@ -1114,6 +1130,14 @@ then
 	ac_cv_ping_packets_first=yes
 	AC_MSG_RESULT([$with_ping_command])
 
+elif $PATH_TO_PING -n -t 10 -c 1 127.0.0.1 2>/dev/null | \
+  egrep -i "^round-trip|^rtt" >/dev/null
+then
+  with_ping_command="$PATH_TO_PING -n -t %d -c %d %s"
+  ac_cv_ping_packets_first=yes
+  ac_cv_ping_has_timeout=yes
+  AC_MSG_RESULT([$with_ping_command])
+
 elif $PATH_TO_PING -n -c 1 127.0.0.1 2>/dev/null | \
 	egrep -i "^round-trip|^rtt" >/dev/null
 then
@@ -1230,6 +1254,14 @@ elif test "x$PATH_TO_PING6" != "x"; then
 		ac_cv_ping6_packets_first=yes
 		AC_MSG_RESULT([$with_ping6_command])
 
+  elif $PATH_TO_PING6 -n -X 10 -c 1 ::1 2>/dev/null | \
+    egrep -i "^round-trip|^rtt" >/dev/null
+  then
+    with_ping6_command="$PATH_TO_PING6 -n -X %d -c %d %s"
+    ac_cv_ping6_packets_first=yes
+    ac_cv_ping_has_timeout=yes
+    AC_MSG_RESULT([$with_ping6_command])
+
 	elif $PATH_TO_PING6 -n -c 1 ::1 2>/dev/null | \
 		egrep -i "^round-trip|^rtt" >/dev/null
 	then
@@ -1266,7 +1298,7 @@ elif test "x$PATH_TO_PING6" != "x"; then
 	then
 		with_ping6_command="$PATH_TO_PING6 -n -s 56 -c %d %s"
 		ac_cv_ping6_packets_first=yes
-		AC_MSG_RESULT([$with_ping_command])
+		AC_MSG_RESULT([$with_ping6_command])
 
 	elif $PATH_TO_PING6 -n -c 1 ::1 2>/dev/null | \
 		egrep -i "^round-trip|^rtt" >/dev/null
@@ -1329,7 +1361,7 @@ elif test "x$PATH_TO_PING" != "x"; then
 	then
 		with_ping6_command="$PATH_TO_PING -A inet6 -n -s 56 -c %d %s"
 		ac_cv_ping6_packets_first=yes
-		AC_MSG_RESULT([$with_ping_command])
+		AC_MSG_RESULT([$with_ping6_command])
 
 	elif $PATH_TO_PING -A inet6 -n -c 1 ::1 2>/dev/null | \
 		egrep -i "^round-trip|^rtt" >/dev/null
@@ -1557,6 +1589,17 @@ else
 	AC_MSG_WARN([Could not find qmail-qstat or equivalent])
 fi
 
+AC_PATH_PROG(PATH_TO_SMTPCTL,smtpctl)
+AC_ARG_WITH(smtpctl_command,
+            ACX_HELP_STRING([--with-smtpctl-command=PATH],
+                            [sets path to smtpctl]), PATH_TO_SMTPCTL=$withval)
+if test -n "$PATH_TO_SMTPCTL"
+then
+	AC_DEFINE_UNQUOTED(PATH_TO_SMTPCTL,"$PATH_TO_SMTPCTL",[path to smtpctl])
+else
+	AC_MSG_WARN([Could not find smtpctl or equivalent])
+fi
+
 dnl SWAP info required is amount allocated/available and amount free
 dnl The plugin works through all the swap devices and adds up the total swap
 dnl available.
@@ -1602,7 +1645,7 @@ then
 
 	if [$PATH_TO_SWAPINFO -k 2>/dev/null | egrep -i "^Device +1K-blocks +Used +Avail" >/dev/null]
 	then
-		ac_cv_swap_format=["%*s %f %*d %f"]
+		ac_cv_swap_format=["%*s %lf %*d %lf"]
 		ac_cv_swap_conv=1024
 		AC_MSG_RESULT([using FreeBSD format swapinfo])
 	fi

+ 4 - 1
lib/parse_ini.c

@@ -83,6 +83,7 @@ static char* default_file_in_path(void);
  */
 static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i){
 	size_t locator_len=0, stanza_len=0;
+	char *dflt = NULL;
 
 	/* if locator is NULL we'll use default values */
 	if(locator){
@@ -102,7 +103,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in
 	}
 	/* if there is no @file part */
 	if(stanza_len==locator_len){
-		i->file=default_file();
+		dflt=default_file();
+		if (dflt)
+			i->file=strdup(dflt);
 	} else {
 		i->file=strdup(&(locator[stanza_len+1]));
 	}

+ 10 - 0
lib/utils_base.c

@@ -164,18 +164,22 @@ _set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_st
 
 	temp_thresholds->warning = NULL;
 	temp_thresholds->critical = NULL;
+	temp_thresholds->warning_string = NULL;
+	temp_thresholds->critical_string = NULL;
 
 	if (warn_string) {
 		if (!(temp_thresholds->warning = parse_range_string(warn_string))) {
 			free(temp_thresholds);
 			return NP_RANGE_UNPARSEABLE;
 		}
+		temp_thresholds->warning_string = strdup(warn_string);
 	}
 	if (critical_string) {
 		if (!(temp_thresholds->critical = parse_range_string(critical_string))) {
 			free(temp_thresholds);
 			return NP_RANGE_UNPARSEABLE;
 		}
+		temp_thresholds->critical_string = strdup(critical_string);
 	}
 
 	*my_thresholds = temp_thresholds;
@@ -204,11 +208,17 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
 	} else {
 		if (my_threshold->warning) {
 			printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end);
+			if (my_threshold->warning_string) {
+				printf("Warning String: %s; ", my_threshold->warning_string);
+			}
 		} else {
 			printf("Warning not set; ");
 		}
 		if (my_threshold->critical) {
 			printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end);
+			if (my_threshold->critical_string) {
+				printf("Critical String: %s; ", my_threshold->critical_string);
+			}
 		} else {
 			printf("Critical not set");
 		}

+ 2 - 0
lib/utils_base.h

@@ -28,6 +28,8 @@ typedef struct range_struct {
 typedef struct thresholds_struct {
 	range	*warning;
 	range	*critical;
+	char    *warning_string;
+	char    *critical_string;
 	} thresholds;
 
 #define NP_STATE_FORMAT_VERSION 1

+ 1 - 1
lib/utils_disk.h

@@ -26,7 +26,7 @@ struct parameter_list
   struct parameter_list *name_next;
   uintmax_t total, available, available_to_root, used, inodes_free, inodes_total;
   double dfree_pct, dused_pct;
-  double dused_units, dfree_units, dtotal_units;
+  uintmax_t dused_units, dfree_units, dtotal_units;
   double dused_inodes_percent, dfree_inodes_percent;
 };
 

+ 1 - 1
m4/ax_with_python.m4

@@ -46,7 +46,7 @@ AC_DEFUN([AX_WITH_PYTHON],
     if test "$PYTHON" != "m4_ifval([$2],[$2],[python])"
     then
       AC_MSG_CHECKING($PYTHON version >= $1)
-      if test `$PYTHON -c ["import sys; print sys.version[:3] >= \"$1\" and \"OK\" or \"OLD\""]` = "OK"
+      if test `$PYTHON -c ["import sys; print(sys.version[:3] >= \"$1\" and \"OK\" or \"OLD\")"]` = "OK"
       then
         AC_MSG_RESULT(ok)
       else

+ 3 - 2
nagios-plugins.spec.in

@@ -162,11 +162,12 @@ fi
 
 %install
 rm -rf $RPM_BUILD_ROOT
-make AM_INSTALL_PROGRAM_FLAGS="" DESTDIR=${RPM_BUILD_ROOT} install install-root
+make AM_INSTALL_PROGRAM_FLAGS="" DESTDIR=${RPM_BUILD_ROOT} install
+make AM_INSTALL_PROGRAM_FLAGS="" DESTDIR=${RPM_BUILD_ROOT} install-packager
 %find_lang %{name}
 echo "%defattr(755,%{npusr},%{npgrp})" >> %{name}.lang
 comm -13 %{npdir}/ls-plugins-before %{npdir}/ls-plugins-after | egrep -v "\.o$|^\." | gawk -v libexecdir=%{_libexecdir} '{printf( "%s/%s\n", libexecdir, $0);}' >> %{name}.lang
-echo "%defattr(755,root,root)" >> %{name}.lang
+echo "%defattr(4555,root,%{npgrp})" >> %{name}.lang
 comm -13 %{npdir}/ls-plugins-root-before %{npdir}/ls-plugins-root-after | egrep -v "\.o$|^\." | gawk -v libexecdir=%{_libexecdir} '{printf( "%s/%s\n", libexecdir, $0);}' >> %{name}.lang
 echo "%defattr(755,%{npusr},%{npgrp})" >> %{name}.lang
 comm -13 %{npdir}/ls-plugins-scripts-before %{npdir}/ls-plugins-scripts-after | egrep -v "\.o$|^\." | gawk -v libexecdir=%{_libexecdir} '{printf( "%s/%s\n", libexecdir, $0);}' >> %{name}.lang

+ 47 - 0
plugins-python/Makefile.am

@@ -0,0 +1,47 @@
+## Process this file with automake to produce Makefile.in
+
+if RELEASE_PRESENT
+NP_VERSION = @NP_RELEASE@
+else
+NP-VERSION-FILE: .FORCE-NP-VERSION-FILE
+	@$(SHELL_PATH) $(top_srcdir)/NP-VERSION-GEN
+.FORCE-NP-VERSION-FILE:
+-include NP-VERSION-FILE
+endif
+
+SUFFIXES = .py .in
+
+VPATH=$(top_srcdir) $(top_srcdir)/plugins-python
+
+libexec_SCRIPTS = check_heartbleed.py  check_imap_login.py check_ncpa.py
+
+EXTRA_DIST=check_heartbleed.in  check_imap_login.in  check_ncpa.in
+
+EDIT = sed \
+  -e 's|[@]NP_VERSION[@]|$(NP_VERSION)|g' \
+  -e 's|[@]TRUSTED_PATH[@]|$(with_trusted_path)|g' \
+  -e 's|[@]PYTHON[@]|$(PYTHON)|g' \
+  -e 's|[@]libexecdir[@]|$(libexecdir)|g'
+
+#TESTS_ENVIRONMENT=perl -I $(top_builddir) -I $(top_srcdir)
+
+#TESTS = @SCRIPT_TEST@
+
+#test:
+#	perl -I $(top_builddir) -I $(top_srcdir) ../test.pl
+#	perl -I $(top_builddir) -I $(top_srcdir) ../test.pl t/utils.t	# utils.t is excluded from above, so manually ask to test
+
+#test-debug:
+#	NPTEST_DEBUG=1 HARNESS_VERBOSE=1 perl -I $(top_builddir) -I $(top_srcdir) ../test.pl
+#	NPTEST_DEBUG=1 HARNESS_VERBOSE=1 perl -I $(top_builddir) -I $(top_srcdir) ../test.pl t/utils.t	# utils.t is excluded from above, so manually ask to test
+
+CLEANFILES=$(libexec_SCRIPTS)
+
+.in.py:
+	@if [ ! "$(PYTHON)" = "missing" ]; then \
+	    $(EDIT) $< > $@; \
+	    chmod +x $@; \
+	fi
+
+clean-local:
+	rm -f NP-VERSION-FILE *.pyc

+ 331 - 0
plugins-python/check_heartbleed.in

@@ -0,0 +1,331 @@
+#!/usr/bin/python2
+
+# Check_Heartbleed.py v0.6
+# 18/4/2014
+
+# Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org)
+# The author disclaims copyright to this source code.
+
+# Modified for simplified checking by Yonathan Klijnsma
+
+# Modified to turn into a Nagios Plugin by Scott Wilkerson (swilkerson@nagios.com)
+# Modified to include TLS v1.2, v1.1, v1.0, and SSLv3.0, defaults to 1.1 (sreinhardt@nagios.com)
+# 	Corrected Hello and Heartbeat packets to match versions
+#	Added optional verbose output
+#	Reimplemented output message and added Rich's idea for looping all supported versions
+# Suggested and implemented in another plugin looping of all versions by default (rich.brown@blueberryhillsoftware.com)
+
+import sys
+import struct
+import socket
+import time
+import select
+import re
+from optparse import OptionParser
+
+options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
+options.add_option('-H', '--host', type='string', default='127.0.0.1', help='Host to connect to (default: 127.0.0.1)')
+options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
+options.add_option('-v', '--version', type='int', default=-1, help='TLS or SSL version to test [TLSv1.0(0), TLSv1.1(1), TLSv1.2(2), or SSLv3.0(3)] (default: all)')
+options.add_option('-u', '--udp', default=False, action='store_true', help='Use TCP or UDP protocols, no arguments needed. This does not work presently, keep to TCP. (default: TCP)')
+options.add_option('-t', '--timeout', type='int', default=10, help='Plugin timeout length (default: 10)')
+options.add_option('-V', '--verbose', default=False, action='store_true', help='Print verbose output, including hexdumps of packets.')
+
+def h2bin(x):
+    return x.replace(' ', '').replace('\n', '').decode('hex')
+
+# Returns correct versioning for handshake and hb packets
+def tls_ver ():
+    global opts
+    if opts.version == 0:    #TLSv1.0
+        return '''03 01'''
+    elif opts.version == 2:    #TLSv1.2
+        return '''03 03'''
+    elif opts.version == 3:    #SSLv3.0
+        return '''03 00'''
+    else:                    #TLSv1.1
+        return '''03 02'''
+
+# Builds hello packet with correct tls version for rest of connection
+def build_hello():
+
+    hello = h2bin('''
+    16 ''' + tls_ver() + ''' 00  dc 01 00 00 d8 ''' + tls_ver() + ''' 53
+    4e d0 57 9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf
+    bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 00
+    00 66 c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88
+    00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c
+    c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09
+    c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44
+    c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c
+    c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11
+    00 08 00 06 00 03 00 ff  01 00 00 49 00 0b 00 04
+    03 00 01 02 00 0a 00 34  00 32 00 0e 00 0d 00 19
+    00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08
+    00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13
+    00 01 00 02 00 03 00 0f  00 10 00 11 00 23 00 00
+    00 0f 00 01 01                                  
+    ''')
+
+##### Hello Packet Layout #####
+#	16													# initiate handshake
+#	+ tls_ver() +  										# version of tls to use
+#	00  dc 												# Length
+#	01 													# Handshake type (hello)
+#	00 00 d8 											# Length
+#	+ tls_ver() +  										# version of tls to use
+#	53 43 5b 90 										# timestamp (change?)
+#	9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf				# random bytes (seriously!)
+#   bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 		# random bytes (seriously!)
+#	00													# Length of session id (start new session)
+#   00 66 												# Length of ciphers supported list
+#	c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88			# 2 byte list of supported ciphers
+#   00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c	# 2 byte list of supported ciphers cont
+#   c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09	# 2 byte list of supported ciphers cont
+#   c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44	# 2 byte list of supported ciphers cont
+#   c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c	# 2 byte list of supported ciphers cont
+#   c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11	# 2 byte list of supported ciphers cont
+#   00 08 00 06 00 03 00 ff  							# 2 byte list of supported ciphers cont
+#	01 													# Length of compression methods
+#	00 													# Null compression (none)
+#	00 49												# Length of TLS extension list
+#	00 0b 00 04 03 00 01 02								# Elliptic curve point formats extension
+#	00 0a 00 34  00 32 00 0e 00 0d 00 19				# Elliptic curve
+#   00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08	# Elliptic curve cont
+#   00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13	# Elliptic curve cont
+#   00 01 00 02 00 03 00 0f  00 10 00 11				# Elliptic curve cont
+#	00 23 00 00											# TLS sessions ticket supported
+#   00 0f 00 01 01										# Heartbeat extension
+##### End Hello Packet #####
+
+    return hello
+
+# Builds and returns heartbleed packet that matches with tls version
+def build_hb():
+
+    hb = h2bin('''
+    18 ''' + tls_ver() + ''' 00 03
+    01 40 00
+    ''')
+
+##### Heartbleed Packet Layout #####
+#   18													# TLS Record Type (heartbeat) 
+#	+ tls_ver() + 										# TLS version
+#	00 03												# Length
+#   01 													# Heartbeat request
+#	40 00												# Length (16384 bytes)
+##### End Heartbleed Packet #####
+    
+    return hb
+
+# Builds and sends hb packet with zero size
+def build_empty_hb():
+
+    hb = h2bin('''
+    18 ''' + tls_ver() + ''' 00 03
+    01 00 00
+    ''')
+
+##### Heartbleed Packet Layout #####
+#   18													# TLS Record Type (heartbeat) 
+#	+ tls_ver() + 										# TLS version
+#	00 03												# Length
+#   01 													# Heartbeat request
+#	40 00												# Length (16384 bytes)
+##### End Heartbleed Packet #####
+    
+    return hb
+
+# Receives data from socket for specified length
+def recvall(s, length):
+    global opts
+    endtime = time.time() + opts.timeout
+    rdata = ''
+    remain = length
+
+    while remain > 0:
+        rtime = endtime - time.time() 
+        if rtime < 0:
+            return None
+        r, w, e = select.select([s], [], [], 5)
+        if s in r:
+            try:
+                data = s.recv(remain)
+            except socket.error:
+                # Should this be OK, as the server has sent a rst most likely and is therefore likely patched?
+                print 'UNKNOWN: Server ' + opts.host + ' closed connection after sending heartbeat. Likely the server has been patched.'
+                sys.exit(3)
+            # EOF?
+            if not data:
+                return None
+            rdata += data
+            remain -= len(data)
+    return rdata
+        
+# Receives messages and handles accordingly
+def recvmsg(s):
+    global opts
+    hdr = recvall(s, 5)
+    if hdr is None:
+        return None, None, None
+    typ, ver, ln = struct.unpack('>BHH', hdr)
+    pay = recvall(s, ln)
+    if pay is None:
+        return None, None, None
+    if opts.verbose == True:
+        print ' ... received message: type = %d, ver = %04x, length = %d, pay = %02x' % (typ, ver, len(pay), ord(pay[0]))
+    return typ, ver, pay
+
+# Sends empty hb packet
+def hit_hb(s, hb):
+    global opts
+
+    if opts.verbose == True:
+       print 'Sending malformed heartbeat packet...'
+
+    try:
+        s.send(hb)
+    except socket.error:
+        print 'UNKNOWN: Error sending heartbeat to ' + opts.host
+        sys.exit(3)
+
+    while True:
+        typ, ver, pay = recvmsg(s)
+        if typ == None:
+            returncode = 0
+            break
+
+        if typ == 24:
+            if pay > 3:
+                returncode = 2    # vulnerable
+                break
+            else:
+                returncode = 0
+                break
+
+        if typ == 21:    # TLS mismatch, hopefully we don't find this
+            returncode = 0
+            break
+
+    #Outside of while
+    if returncode == 0: # Not vulnerable message
+        if opts.version == 3: #respond with ssl instead of tls
+            message = 'SSLv3.0 is not vulnerable. '
+        else:
+            message = 'TLSv1.' + str(opts.version) + ' is not vulnerable. '
+    else: # vulnerable message
+        if opts.version == 3: #respond with ssl instead of tls
+            message = 'SSLv3.0 is vulnerable. '
+        else:
+            message = 'TLSv1.' + str(opts.version) + ' is vulnerable. '
+
+    return returncode, message
+
+# Prints nagios style output and exit codes
+def print_output(exitcode, outputmessage):
+
+    if exitcode == 2:
+        print 'CRITICAL: Server ' + opts.host + ' ' + outputmessage
+    else:
+        print 'OK: Server ' + opts.host + ' ' + outputmessage
+
+    sys.exit(exitcode)
+
+# Outputs packets as hex, used for verbose output
+def hexdump(s):
+
+    for b in xrange(0, len(s), 16):
+        lin = [c for c in s[b : b + 16]]
+        hxdat = ' '.join('%02X' % ord(c) for c in lin)
+        pdat = ''
+        for c in lin:
+            if 32 <= ord(c) <= 126:
+                pdat += c
+            else:
+                pdat += '.'
+        print '  %04x: %-48s %s' % (b, hxdat, pdat)
+    print
+
+# Initiates connection and handles initial hello\hb sending
+def connect(hb):
+    global opts
+ 
+    if opts.udp == True:
+        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    else:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    
+    s.settimeout(opts.timeout)
+
+    try: 
+        s.connect((opts.host, opts.port))
+    except socket.error:
+        print 'UNKNOWN: Connecton to server ' + opts.host + ' could not be established.'
+        sys.exit(3)
+
+    hello = build_hello()
+
+    if opts.verbose == True:
+        print 'Sending hello packet...'
+
+    try:
+        s.send(hello)
+    except socket.error:
+        print 'UNKNOWN: Error sending hello to ' + opts.host
+        sys.exit(3)
+
+    while True:
+        typ, ver, pay = recvmsg(s)
+        if typ == None:
+            print 'UNKNOWN: Server ' + opts.host + ' closed connection without sending Server Hello.'
+            sys.exit(3)
+        # Look for server hello done message.
+        if typ == 22 and ord(pay[0]) == 0x0E:
+            if opts.verbose == True:
+                hexdump(pay)
+            break
+        else:
+            if opts.verbose == True:
+                hexdump(pay)
+            continue
+
+    if opts.verbose == True:
+        print 'Sending malformed heartbeat packet...'
+
+    try:
+        s.send(hb)
+    except socket.error:
+        print 'UNKNOWN: Error sending heartbeat to ' + opts.host
+        sys.exit(3)
+
+    return s
+
+def main():
+    global opts
+    opts, args = options.parse_args()
+    exitcode = 0
+    outputmessage = ''
+
+    if opts.version == -1: # no version was specified, loop.
+
+        if opts.verbose == True:
+            print 'Checking all supported TLS and SSL versions.'
+
+        for opts.version in [0, 1, 2, 3]:
+            hb = build_hb()
+            s = connect(hb)
+            returncode, message = hit_hb(s, hb)
+
+            if returncode > exitcode:
+                exitcode = returncode
+            outputmessage += message
+            
+    else: # version was specified
+        hb = build_hb()
+        s = connect(hb)
+        exitcode, outputmessage = hit_hb(s, hb)
+
+    print_output(exitcode, outputmessage)
+
+if __name__ == '__main__':
+    main()

+ 61 - 0
plugins-python/check_imap_login.in

@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# vi:si:et:sw=4:sts=4:ts=4
+# -*- coding: UTF-8 -*-
+# -*- Mode: Python -*-
+#
+# Copyright (C) 2005 Bertera Pietro <pietro@bertera.it>
+
+# This file may be distributed and/or modified under the terms of
+# the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+# This file is distributed without any warranty; without even the implied
+# warranty of merchantability or fitness for a particular purpose.
+# See "LICENSE.GPL" in the source distribution for more information.
+
+import sys, os, imaplib, getopt
+
+def usage():
+    print "-u <user>"
+    print "-p <password>"
+    print "-s use SSL"
+    print "-H <host>"
+
+def main():
+	try:
+	    opts, args = getopt.getopt(sys.argv[1:], "u:p:sH:")	
+    except getopt.GetoptError:
+        usage()
+        return 3
+    
+    user = host = password = use_ssl = None
+    
+    for o, a in opts:
+        if o == "-u":
+            user = a
+        elif o == "-p":
+            password = a
+        elif o == "-s":
+            use_ssl = True
+        elif o == "-H":
+            host = a  
+    if user == None or password == None or host == None:
+        usage()
+        return 1
+    
+    if use_ssl:
+        M = imaplib.IMAP4_SSL(host=host)
+    else:
+    	M = imaplib.IMAP4(host)
+    
+    try:	
+        M.login(user, password)
+	except Exception, e:
+        print "CRITICAL: IMAP Login not Successful: %s" % e
+        sys.exit(2)
+    
+    M.logout()
+    print "OK IMAP Login Successful"
+    return 0
+
+if __name__ == "__main__":
+        sys.exit(main())

+ 300 - 0
plugins-python/check_ncpa.in

@@ -0,0 +1,300 @@
+#!@PYTHON@
+"""
+SYNOPSIS
+
+
+"""
+import sys
+import optparse
+import traceback
+import ssl
+
+# Python 2/3 Compatibility imports
+
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+try:
+    import urllib.request
+    import urllib.parse
+    import urllib.error
+except ImportError:
+    import urllib2
+    import urllib
+
+try:
+    urlencode = urllib.parse.urlencode
+except AttributeError:
+    urlencode = urllib.urlencode
+
+try:
+    urlopen = urllib.request.urlopen
+except AttributeError:
+    urlopen = urllib2.urlopen
+
+try:
+    urlquote = urllib.parse.quote
+except AttributeError:
+    urlquote = urllib.quote
+
+import shlex
+import re
+import signal
+
+__VERSION__ = '1.1.0'
+
+def pretty(d, indent=0, indenter=' ' * 4):
+    info_str = ''
+    for key, value in list(d.items()):
+        info_str += indenter * indent + str(key)
+        if isinstance(value, dict):
+            info_str += '/\n'
+            info_str += pretty(value, indent + 1, indenter)
+        else:
+            info_str += ': ' + str(value) + '\n'
+    return info_str
+
+
+def parse_args():
+    version = 'check_ncpa.py, Version %s' % __VERSION__
+
+    parser = optparse.OptionParser()
+    parser.add_option("-H", "--hostname", help="The hostname to be connected to.")
+    parser.add_option("-M", "--metric", default='',
+                      help="The metric to check, this is defined on client "
+                           "system. This would also be the plugin name in the "
+                           "plugins directory. Do not attach arguments to it, "
+                           "use the -a directive for that. DO NOT INCLUDE the api/ "
+                           "instruction.")
+    parser.add_option("-P", "--port", default=5693, type="int",
+                      help="Port to use to connect to the client.")
+    parser.add_option("-w", "--warning", default=None, type="str",
+                      help="Warning value to be passed for the check.")
+    parser.add_option("-c", "--critical", default=None, type="str",
+                      help="Critical value to be passed for the check.")
+    parser.add_option("-u", "--units", default=None,
+                      help="The unit prefix (k, Ki, M, Mi, G, Gi, T, Ti) for b and B unit "
+                           "types which calculates the value returned.")
+    parser.add_option("-n", "--unit", default=None,
+                      help="Overrides the unit with whatever unit you define. "
+                           "Does not perform calculations. This changes the unit of measurement only.")
+    parser.add_option("-a", "--arguments", default=None,
+                      help="Arguments for the plugin to be run. Not necessary "
+                           "unless you're running a custom plugin. Given in the same "
+                           "as you would call from the command line. Example: -a '-w 10 -c 20 -f /usr/local'")
+    parser.add_option("-t", "--token", default='',
+                      help="The token for connecting.")
+    parser.add_option("-T", "--timeout", default=60, type="int",
+                      help="Enforced timeout, will terminate plugins after "
+                           "this amount of seconds. [%default]")
+    parser.add_option("-d", "--delta", action='store_true',
+                      help="Signals that this check is a delta check and a "
+                           "local state will kept.")
+    parser.add_option("-l", "--list", action='store_true',
+                      help="List all values under a given node. Do not perform "
+                           "a check.")
+    parser.add_option("-v", "--verbose", action='store_true',
+                      help='Print more verbose error messages.')
+    parser.add_option("-D", "--debug", action='store_true',
+                      help='Print LOTS of error messages. Used mostly for debugging.')
+    parser.add_option("-V", "--version", action='store_true',
+                      help='Print version number of plugin.')
+    parser.add_option("-q", "--queryargs", default=None,
+                      help='Extra query arguments to pass in the NCPA URL.')
+    parser.add_option("-s", "--secure", action='store_true', default=False,
+                      help='Require successful certificate verification. Does not work on Python < 2.7.9.')
+    parser.add_option("-p", "--performance", action='store_true', default=False,
+                      help='Print performance data even when there is none. '
+                           'Will print data matching the return code of this script')
+    options, _ = parser.parse_args()
+
+    if options.version:
+        print(version)
+        sys.exit(0)
+
+    if options.arguments and options.metric and not 'plugin' in options.metric:
+        parser.print_help()
+        parser.error('You cannot specify arguments without running a custom plugin.')
+
+    if not options.hostname:
+        parser.print_help()
+        parser.error("Hostname is required for use.")
+
+    elif not options.metric and not options.list:
+        parser.print_help()
+        parser.error('No metric given, if you want to list all possible items '
+                     'use --list.')
+
+    options.metric = re.sub(r'^/?(api/)?', '', options.metric)
+
+    return options
+
+
+# ~ The following are all helper functions. I would normally split these out into
+# ~ a new module but this needs to be portable.
+
+
+def get_url_from_options(options):
+    host_part = get_host_part_from_options(options)
+    arguments = get_arguments_from_options(options)
+    return '%s?%s' % (host_part, arguments)
+
+
+def get_host_part_from_options(options):
+    """Gets the address that will be queries for the JSON.
+
+    """
+    hostname = options.hostname
+    port = options.port
+
+    if not options.metric is None:
+        metric = urlquote(options.metric)
+    else:
+        metric = ''
+
+    arguments = get_check_arguments_from_options(options)
+    if not metric and not arguments:
+        api_address = 'https://%s:%d/api' % (hostname, port)
+    else:
+        api_address = 'https://%s:%d/api/%s/%s' % (hostname, port, metric, arguments)
+
+    return api_address
+
+
+def get_check_arguments_from_options(options):
+    """Gets the escaped URL for plugin arguments to be added
+    to the end of the host URL. This is different from the get_arguments_from_options
+    in that this is meant for the syntax when the user is calling a check, whereas the below
+    is when GET arguments need to be added.
+
+    """
+    arguments = options.arguments
+    if arguments is None:
+        return ''
+    else:
+        lex = shlex.shlex(arguments)
+        lex.whitespace_split = True
+        arguments = '/'.join([urlquote(x, safe='') for x in lex])
+        return arguments
+
+
+def get_arguments_from_options(options, **kwargs):
+    """Returns the http query arguments. If there is a list variable specified,
+    it will return the arguments necessary to query for a list.
+
+    """
+
+    # Note: Changed back to units due to the units being what is passed via the
+    # API call which can confuse people if they don't match
+    arguments = { 'token': options.token,
+                  'units': options.units }
+    
+    if not options.list:
+        arguments['warning'] = options.warning
+        arguments['critical'] = options.critical
+        arguments['delta'] = options.delta
+        arguments['check'] = 1
+        arguments['unit'] = options.unit
+
+    if options.queryargs:
+        for argument in options.queryargs.split(','):
+            key, value = argument.split('=')
+            arguments[key] = value
+
+    #~ Encode the items in the dictionary that are not None
+    return urlencode(dict((k, v) for k, v in list(arguments.items()) if v is not None))
+
+
+def get_json(options):
+    """Get the page given by the options. This will call down the url and
+    encode its finding into a Python object (from JSON).
+
+    """
+    url = get_url_from_options(options)
+
+    if options.verbose:
+        print('Connecting to: ' + url)
+
+    try:
+        ctx = ssl.create_default_context()
+        if not options.secure:
+            ctx.check_hostname = False
+            ctx.verify_mode = ssl.CERT_NONE
+        ret = urlopen(url, context=ctx)
+    except AttributeError:
+        ret = urlopen(url)
+
+    ret = ''.join(ret)
+
+    if options.verbose:
+        print('File returned contained:\n' + ret)
+
+    arr = json.loads(ret)
+
+    if 'value' in arr:
+        return arr['value']
+
+    return arr
+
+
+def run_check(info_json):
+    """Run a check against the remote host.
+
+    """
+    return info_json['stdout'], info_json['returncode']
+
+
+def show_list(info_json):
+    """Show the list of available options.
+
+    """
+    return pretty(info_json), 0
+
+
+def timeout_handler(threshold):
+    def wrapped(signum, frames):
+        stdout = "UNKNOWN: Execution exceeded timeout threshold of %ds" % threshold
+        print stdout
+        sys.exit(3)
+    return wrapped
+
+
+def main():
+    options = parse_args()
+
+    # We need to ensure that we will only execute for a certain amount of
+    # seconds.
+    signal.signal(signal.SIGALRM, timeout_handler(options.timeout))
+    signal.alarm(options.timeout)
+
+    try:
+
+        if options.version:
+            stdout = 'The version of this plugin is %s' % __VERSION__
+            return stdout, 0
+
+        info_json = get_json(options)
+        if options.list:
+            return show_list(info_json)
+        else:
+            stdout, returncode = run_check(info_json)
+            if options.performance and stdout.find("|") == -1:
+                performance = " | 'status'={};1;2;".format(returncode)
+                return "{}{}".format(stdout, performance), returncode
+            else:
+                return stdout, returncode
+    except Exception, e:
+        if options.debug:
+            return 'The stack trace:' + traceback.format_exc(), 3
+        elif options.verbose:
+            return 'An error occurred:' + str(e), 3
+        else:
+            return 'UNKNOWN: Error occurred while running the plugin. Use the verbose flag for more details.', 3
+
+
+if __name__ == "__main__":
+    stdout, returncode = main()
+    print(stdout)
+    sys.exit(returncode)

+ 11 - 0
plugins-root/Makefile.am

@@ -52,9 +52,20 @@ INSTALL_SUID = \
 	chmod $(setuid_root_mode) $(DESTDIR)$(libexecdir)/$$p; \
 	done
 
+INSTALL_NOSUID = \
+	for f in $(noinst_PROGRAMS) ; do \
+	p=$$f; \
+	echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/$$p"; \
+	$(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/$$p; \
+	echo "NOTE: $(DESTDIR)$(libexecdir)/$$p expected to be chown/chmod by the package installer"; \
+	done
+
 install-root: $(noinst_PROGRAMS)
 	@$(INSTALL_SUID)
 
+install-packager: $(noinst_PROGRAMS)
+	@$(INSTALL_NOSUID)
+
 install-exec-local: $(noinst_PROGRAMS)
 	@TMPFILE=$(DESTDIR)$(libexecdir)/.setuid-$$$$; \
 	rm -f $$TMPFILE; \

Datei-Diff unterdrückt, da er zu groß ist
+ 1656 - 1072
plugins-root/check_icmp.c


+ 19 - 6
plugins-scripts/check_disk_smb.pl

@@ -22,7 +22,7 @@ require 5.004;
 use POSIX;
 use strict;
 use Getopt::Long;
-use vars qw($opt_P $opt_V $opt_h $opt_H $opt_k $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $verbose);
+use vars qw($opt_P $opt_V $opt_m $opt_h $opt_H $opt_k $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $opt_C $verbose);
 use vars qw($PROGNAME);
 use FindBin;
 use lib "$FindBin::Bin";
@@ -45,6 +45,7 @@ GetOptions
 	 "V"   => \$opt_V, "version"    => \$opt_V,
 	 "h"   => \$opt_h, "help"       => \$opt_h,
 	 "k"   => \$opt_k, "kerberos"   => \$opt_k,
+	 "m=s" => \$opt_m, "maxprotocol=s" => \$opt_m,
 	 "w=s" => \$opt_w, "warning=s"  => \$opt_w,
 	 "c=s" => \$opt_c, "critical=s" => \$opt_c,
 	 "p=s" => \$opt_p, "password=s" => \$opt_p,
@@ -52,7 +53,8 @@ GetOptions
 	 "s=s" => \$opt_s, "share=s"    => \$opt_s,
 	 "W=s" => \$opt_W, "workgroup=s" => \$opt_W,
 	 "H=s" => \$opt_H, "hostname=s" => \$opt_H,
-	 "a=s" => \$opt_a, "address=s" => \$opt_a);
+	 "a=s" => \$opt_a, "address=s" => \$opt_a,
+	 "C=s" => \$opt_C, "configfile=s" => \$opt_C);
 
 if ($opt_V) {
 	print_revision($PROGNAME,'@NP_VERSION@'); #'
@@ -82,6 +84,9 @@ defined($user) || usage("Invalid user: $opt_u\n");
 defined($opt_p) || ($opt_p = shift @ARGV) || ($opt_p = "");
 my $pass = $1 if ($opt_p =~ /(.*)/);
 
+defined($opt_m) || ($opt_m = shift @ARGV) || ($opt_m = "");
+my $maxprotocol = $1 if ($opt_m =~ /(.*)/);
+
 ($opt_w) || ($opt_w = shift @ARGV) || ($opt_w = 85);
 my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 ($warn) || usage("Invalid warning threshold: $opt_w\n");
@@ -90,6 +95,10 @@ my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
 ($crit) || usage("Invalid critical threshold: $opt_c\n");
 
+($opt_C) || ($opt_C = shift @ARGV) || ($opt_C = "");
+my $configfile = $opt_C if ($opt_C);
+usage("Unable to read config file $configfile\n") if ($configfile) && (! -r $configfile);
+
 # Execute the given command line and return anything it writes to STDOUT and/or
 # STDERR.  (This might be useful for other plugins, too, so it should possibly
 # be moved to utils.pm.)
@@ -187,10 +196,12 @@ my @cmd = (
 	$smbclient,
 	"//$host/$share",
 	"-U", "$user%$pass",
+	defined($maxprotocol) ? ("-m", $maxprotocol) : (),
 	defined($workgroup) ? ("-W", $workgroup) : (),
 	defined($address) ? ("-I", $address) : (),
 	defined($opt_P) ? ("-p", $opt_P) : (),
 	defined($opt_k) ? ("-k") : (),
+	defined($configfile) ? ("-s, $configfile") : (),
 	"-c", "du"
 );
 
@@ -289,8 +300,9 @@ print "$state\n" if ($verbose);
 exit $ERRORS{$state};
 
 sub print_usage () {
-	print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 
-      -w <warn> -c <crit> [-W <workgroup>] [-P <port>] [-a <IP>]\n";
+	print "Usage: $PROGNAME -H <host> -s <share> -u <user> 
+      -p <password> -w <warn> -c <crit> [-W <workgroup>] [-P <port>] 
+      [-a <IP>] [-C <configfile>]\n";
 }
 
 sub print_help () {
@@ -316,12 +328,13 @@ Perl Check SMB Disk plugin for Nagios
    Password to log in to server. (Defaults to an empty password)
 -w, --warning=INTEGER or INTEGER[kMG]
    Percent of used space at which a warning will be generated (Default: 85%)
-      
 -c, --critical=INTEGER or INTEGER[kMG]
    Percent of used space at which a critical will be generated (Defaults: 95%)
 -P, --port=INTEGER
    Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default)
-   
+-C, --configfile=STRING
+   Path to configfile which should be used by smbclient (Defaults to smb.conf of your smb installation)
+
    If thresholds are followed by either a k, M, or G then check to see if that
    much disk space is available (kilobytes, Megabytes, Gigabytes)
 

+ 11 - 1
plugins-scripts/check_log.sh

@@ -169,6 +169,16 @@ while test -n "$1"; do
     shift
 done
 
+if [ "$oldlog" = "" ]; then
+	echo "Log check error: You must supply an Old Log File name using '-O'!"
+	exit "$STATE_UNKNOWN"
+fi
+rc=`echo "$oldlog" | grep -q -- "^-"; echo $?`
+if [ $rc -eq 0 ]; then
+	echo "Log check error: You must supply an Old Log File name using '-O'!"
+	exit "$STATE_UNKNOWN"
+fi
+
 # If the source log file doesn't exist, exit
 
 if [ ! -e "$logfile" ]; then
@@ -212,7 +222,7 @@ if [[ $? -gt 1 ]];then
 fi
 
 # Get the last matching entry in the diff file
-lastentry=$(grep "$query" "$tempdiff" | tail -1)
+lastentry=$(egrep "$query" "$tempdiff" | tail -1)
 
 rm -f "$tempdiff"
 cat "$logfile" > "$oldlog"

+ 98 - 14
plugins-scripts/check_mailq.pl

@@ -28,9 +28,9 @@
 use POSIX;
 use strict;
 use Getopt::Long;
-use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s
-					$opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq @lines
-					%srcdomains %dstdomains);
+use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c $opt_t $opt_s $opt_d
+					$opt_M $mailq $status $state $msg $msg_q $msg_p $opt_W $opt_C $mailq $mailq_args
+					@lines %srcdomains %dstdomains);
 use FindBin;
 use lib "$FindBin::Bin";
 use lib '@libexecdir@';
@@ -49,6 +49,8 @@ $PROGNAME = "check_mailq";
 $mailq = 'sendmail';	# default
 $msg_q = 0 ;
 $msg_p = 0 ;
+# If appended, must start with a space
+$mailq_args = '' ;
 $state = $ERRORS{'UNKNOWN'};
 
 Getopt::Long::Configure('bundling');
@@ -58,6 +60,10 @@ if ($status){
 	exit $ERRORS{"UNKNOWN"};
 }
 
+if ($opt_d) {
+	$mailq_args = $mailq_args . ' -C ' . $opt_d;
+}
+
 if ($opt_s) {
 	if ($utils::PATH_TO_SUDO ne "") {
 		if (-x $utils::PATH_TO_SUDO) {
@@ -313,19 +319,19 @@ elsif ( $mailq eq "postfix" ) {
      ## open mailq
 	if ( defined $utils::PATH_TO_MAILQ ) {
 		if (-x $utils::PATH_TO_MAILQ) {
-			if (! open (MAILQ, "$utils::PATH_TO_MAILQ | ")) {
-				print "ERROR: $utils::PATH_TO_MAILQ returned an error\n";
+			if (! open (MAILQ, "$utils::PATH_TO_MAILQ$mailq_args | ")) {
+				print "ERROR: $utils::PATH_TO_MAILQ$mailq_args returned an error\n";
 				exit $ERRORS{'UNKNOWN'};
 			}
 		}
 		else {
 			if ( $sudo ne "" ) {
-				if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ | " ) ) {
-					print "ERROR: $utils::PATH_TO_MAILQ is not executable with sudo by (uid $>:gid($)))\n";
+				if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ$mailq_args | " ) ) {
+					print "ERROR: $utils::PATH_TO_MAILQ$mailq_args is not executable with sudo by (uid $>:gid($)))\n";
 					exit $ERRORS{'UNKNOWN'};
 				}
 			} else {
-				print "ERROR: $utils::PATH_TO_MAILQ is not executable by (uid $>:gid($))) and sudo is not set in utils.pm\n";
+				print "ERROR: $utils::PATH_TO_MAILQ$mailq_args is not executable by (uid $>:gid($))) and sudo is not set in utils.pm\n";
 				exit $ERRORS{'UNKNOWN'};
 			}
 		}
@@ -338,7 +344,7 @@ elsif ( $mailq eq "postfix" ) {
 	@lines = reverse <MAILQ>;
 
         if ( $? ) {
-		print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ",$/;
+		print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_MAILQ$mailq_args",$/;
 		exit $ERRORS{CRITICAL};
         }
 
@@ -351,7 +357,7 @@ elsif ( $mailq eq "postfix" ) {
 	}elsif ($lines[0]=~/Mail queue is empty/) {
 		$msg_q = 0;
         }else{
-                print "Couldn't match $utils::PATH_TO_MAILQ output\n";
+                print "Couldn't match $utils::PATH_TO_MAILQ$mailq_args output\n";
                 exit   $ERRORS{'UNKNOWN'};
         }
 
@@ -520,7 +526,47 @@ elsif ( $mailq eq "exim" ) {
 		$state = $ERRORS{'CRITICAL'};
 	}
 } # end of ($mailq eq "exim")
+elsif ( $mailq eq "opensmtpd" ) {
+	## open smtpctl
+	if ( defined $utils::PATH_TO_SMTPCTL && -x $utils::PATH_TO_SMTPCTL ) {
+		if (! open (MAILQ, "$sudo $utils::PATH_TO_SMTPCTL show queue | " ) ) {
+			print "ERROR: could not open $utils::PATH_TO_SMTPCTL \n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	}elsif( defined $utils::PATH_TO_SMTPCTL){
+		unless (-x $utils::PATH_TO_SMTPCTL) {
+			print "ERROR: $utils::PATH_TO_SMTPCTL is not executable by (uid $>:gid($)))\n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	} else {
+		print "ERROR: \$utils::PATH_TO_SMTPCTL is not defined\n";
+		exit $ERRORS{'UNKNOWN'};
+	}
+
+	while (<MAILQ>) {
+
+		# 34357f5b3f589feb|inet4|mta||f.someone@domaina.org|no-reply@domainb.com|no-reply@domainb.com|1498235412|1498581012|0|25|pending|17168|Network error on destination MXs
+		if (/^.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*|.*$/) {
+			$msg_q++ ;
+		}
+	}
+	close(MAILQ);
 
+	if ( $? ) {
+		print "CRITICAL: Error code ".($?>>8)." returned from $utils::PATH_TO_SMTPCTL",$/;
+		exit $ERRORS{CRITICAL};
+	}
+	if ($msg_q < $opt_w) {
+		$msg = "OK: $mailq mailq ($msg_q) is below threshold ($opt_w/$opt_c)";
+		$state = $ERRORS{'OK'};
+	}elsif ($msg_q >= $opt_w  && $msg_q < $opt_c) {
+		$msg = "WARNING: $mailq mailq is $msg_q (threshold w = $opt_w)";
+		$state = $ERRORS{'WARNING'};
+	}else {
+		$msg = "CRITICAL: $mailq mailq is $msg_q (threshold c = $opt_c)";
+		$state = $ERRORS{'CRITICAL'};
+	}
+} # end of ($mailq eq "opensmtpd")
 elsif ( $mailq eq "nullmailer" ) {
 	## open mailq
 	if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) {
@@ -558,6 +604,39 @@ elsif ( $mailq eq "nullmailer" ) {
 	}
 } # end of ($mailq eq "nullmailer")
 
+elsif ( $mailq eq "opensmtp" ) {
+	## open mailq
+	if ( defined $utils::PATH_TO_MAILQ && -x $utils::PATH_TO_MAILQ ) {
+		if (! open (MAILQ, "$sudo $utils::PATH_TO_MAILQ | " ) ) {
+			print "ERROR: could not open $utils::PATH_TO_MAILQ \n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	}elsif( defined $utils::PATH_TO_MAILQ){
+		unless (-x $utils::PATH_TO_MAILQ) {
+			print "ERROR: $utils::PATH_TO_MAILQ is not executable by (uid $>:gid($)))\n";
+			exit $ERRORS{'UNKNOWN'};
+		}
+	} else {
+		print "ERROR: \$utils::PATH_TO_MAILQ is not defined\n";
+		exit $ERRORS{'UNKNOWN'};
+	}
+
+	$msg_q++ while (<MAILQ>);
+
+	close(MAILQ) ;
+	if ($msg_q < $opt_w) {
+		$msg = "OK: $mailq mailq ($msg_q) is below threshold ($opt_w/$opt_c)";
+		$state = $ERRORS{'OK'};
+	}elsif ($msg_q >= $opt_w  && $msg_q < $opt_c) {
+		$msg = "WARNING: $mailq mailq is $msg_q (threshold w = $opt_w)";
+		$state = $ERRORS{'WARNING'};
+	}else {
+		$msg = "CRITICAL: $mailq mailq is $msg_q (threshold c = $opt_c)";
+		$state = $ERRORS{'CRITICAL'};
+	}
+} # end of ($mailq eq "opensmtp")
+
+
 # Perfdata support
 print "$msg|unsent=$msg_q;$opt_w;$opt_c;0\n";
 exit $state;
@@ -576,7 +655,8 @@ sub process_arguments(){
 		 "w=i" => \$opt_w, "warning=i"  => \$opt_w,   # warning if above this number
 		 "c=i" => \$opt_c, "critical=i" => \$opt_c,	  # critical if above this number
 		 "t=i" => \$opt_t, "timeout=i"  => \$opt_t,
-		 "s"   => \$opt_s, "sudo"       => \$opt_s
+		 "s"   => \$opt_s, "sudo"       => \$opt_s,
+		 "d:s" => \$opt_d, "configdir:s" => \$opt_d
 		 );
 
 	if ($opt_V) {
@@ -618,7 +698,7 @@ sub process_arguments(){
 	}
 
 	if (defined $opt_M) {
-		if ($opt_M =~ /^(sendmail|qmail|postfix|exim|nullmailer)$/) {
+		if ($opt_M =~ /^(sendmail|qmail|postfix|exim|nullmailer|opensmtpd)$/) {
 			$mailq = $opt_M ;
 		}elsif( $opt_M eq ''){
 			$mailq = 'sendmail';
@@ -648,6 +728,10 @@ sub process_arguments(){
 		{
 			$mailq = 'nullmailer';
 		}
+		elsif (defined $utils::PATH_TO_SMTPCTL && -x $utils::PATH_TO_SMTPCTL)
+		{
+			$mailq = 'opensmtpd';
+		}
 		else {
 			$mailq = 'sendmail';
 		}
@@ -657,7 +741,7 @@ sub process_arguments(){
 }
 
 sub print_usage () {
-	print "Usage: $PROGNAME -w <warn> -c <crit> [-W <warn>] [-C <crit>] [-M <MTA>] [-t <timeout>] [-s] [-v]\n";
+	print "Usage: $PROGNAME -w <warn> -c <crit> [-W <warn>] [-C <crit>] [-M <MTA>] [-t <timeout>] [-s] [-d <CONFIGDIR>] [-v]\n";
 }
 
 sub print_help () {
@@ -673,7 +757,7 @@ sub print_help () {
 	print "-W (--Warning)   = Min. number of messages for same domain in queue to generate warning\n";
 	print "-C (--Critical)  = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n";
 	print "-t (--timeout)   = Plugin timeout in seconds (default = $utils::TIMEOUT)\n";
-	print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer ] (default = autodetect)\n";
+	print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer | opensmtpd ] (default = autodetect)\n";
 	print "-h (--help)\n";
 	print "-V (--version)\n";
 	print "-v (--verbose)   = debugging output\n";

+ 15 - 8
plugins-scripts/check_sensors.sh

@@ -42,23 +42,30 @@ case "$1" in
 		exit "$STATE_OK"
 		;;
 	*)
+		ignorefault=0
+		if test "$1" = "-i" -o "$1" = "--ignore-fault"; then
+			ignorefault=1
+		fi
+
 		sensordata=$(sensors 2>&1)
 		status=$?
+
+		# Set a default
+		text="SENSOR UNKNOWN"
+		exit=$STATE_UNKNOWN
+
 		if [ $status -eq 127 ] ; then
 			text="SENSORS UNKNOWN - command not found (did you install lmsensors?)"
 			exit=$STATE_UNKNOWN
 		elif [ "$status" != 0 ] ; then
 			text="WARNING - sensors returned state $status"
 			exit=$STATE_WARNING
-		elif echo "${sensordata}" | egrep -q ALARM > /dev/null ; then
+		elif echo "${sensordata}" | egrep -q ALARM >/dev/null ; then
 			text="SENSOR CRITICAL - Sensor alarm detected!"
 			exit=$STATE_CRITICAL
-		elif echo "${sensordata}" | egrep -q FAULT  > /dev/null -a; then
-			if [ "$(test "$1")" != "-i" -a \
-				"$1" != "--ignore-fault" ] ; then
-				text="SENSOR UNKNOWN - Sensor reported fault"
-				exit=$STATE_UNKNOWN
-			fi
+		elif [ $ignorefault -eq 0 ] && echo "${sensordata}" | egrep -q FAULT  >/dev/null; then
+			text="SENSOR UNKNOWN - Sensor reported fault"
+			exit=$STATE_UNKNOWN
 		else
 			text="SENSORS OK"
 			exit=$STATE_OK
@@ -68,6 +75,6 @@ case "$1" in
 		if test "$1" = "-v" -o "$1" = "--verbose"; then
 			echo "${sensordata}"
 		fi
-		exit "$exit"
+		exit $exit
 		;;
 esac

+ 11 - 5
plugins-scripts/check_wave.pl

@@ -13,7 +13,8 @@ use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H);
 my (@test, $low1, $med1, $high1, $snr, $low2, $med2, $high2);
 my ($low, $med, $high, $lowavg, $medavg, $highavg, $tot, $ss);
 
-$PROGNAME = "check_wave";
+$PROGNAME = $0;
+chomp $PROGNAME;
 sub print_help ();
 sub print_usage ();
 
@@ -41,9 +42,9 @@ if ($opt_h) {
 }
 
 $opt_H = shift unless ($opt_H);
-print_usage() unless ($opt_H);
+unless ($opt_H) { print_usage(); exit -1; }
 my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/);
-print_usage() unless ($host);
+unless ($host) { print_usage(); exit -1; }
 
 ($opt_c) || ($opt_c = shift) || ($opt_c = 120);
 my $critical = $1 if ($opt_c =~ /([0-9]+)/);
@@ -51,7 +52,12 @@ my $critical = $1 if ($opt_c =~ /([0-9]+)/);
 ($opt_w) || ($opt_w = shift) || ($opt_w = 60);
 my $warning = $1 if ($opt_w =~ /([0-9]+)/);
 
-$low1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1`;
+$low1 = `snmpget $host public .1.3.6.1.4.1.74.2.21.1.2.1.8.1 2>/dev/null`;
+unless ($low1) {
+	print "UNKNOWN - Could not find the 'snmpget' command Please install\n";
+	print "the snmp commands (usually net-snmp) before using $PROGNAME\n";
+	exit $ERRORS{'UNKNOWN'};
+}
 @test = split(/ /,$low1);
 $low1 = $test[2];
 
@@ -97,7 +103,7 @@ if ($tot==0) {
 	$ss = ($medavg*50) + ($highavg*100);
 }
 
-printf("Signal Strength at: %3.0f%,  SNR at $snr%",$ss);
+printf("Signal Strength at: %3.0f%,  SNR at $snr%\n",$ss);
 
 if ($ss<$critical) {
 	exit(2);

+ 3 - 2
plugins/Makefile.am

@@ -29,7 +29,7 @@ MATHLIBS = @MATHLIBS@
 libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \
 	check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_overcr check_ping \
 	check_real check_smtp check_ssh check_tcp check_time check_ntp_time \
-	check_ups check_users negate \
+	check_ups check_users negate remove_perfdata \
 	urlize @EXTRAS@
 
 check_tcp_programs = check_ftp check_imap check_nntp check_pop \
@@ -78,7 +78,7 @@ check_fping_LDADD = $(NETLIBS)
 check_game_LDADD = $(BASEOBJS)
 check_http_LDADD = $(SSLOBJS)
 check_hpjd_LDADD = $(NETLIBS)
-check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS)
+check_ldap_LDADD = $(SSLOBJS) $(NETLIBS) $(LDAPLIBS) $(SSLLIBS)
 check_load_LDADD = $(BASEOBJS)
 check_mrtg_LDADD = $(BASEOBJS)
 check_mrtgtraf_LDADD = $(BASEOBJS)
@@ -113,6 +113,7 @@ check_by_ssh_LDADD = $(NETLIBS)
 check_ide_smart_LDADD = $(BASEOBJS)
 negate_LDADD = $(BASEOBJS)
 urlize_LDADD = $(BASEOBJS)
+remove_perfdata_LDADD = $(BASEOBJS)
 
 if !HAVE_UTMPX
 check_users_LDADD += popen.o

+ 12 - 3
plugins/check_apt.c

@@ -73,6 +73,7 @@ char* add_to_regexp(char *expr, const char *next);
 /* configuration variables */
 static int verbose = 0;      /* -v */
 static int do_update = 0;    /* whether to call apt-get update */
+static int only_critical = 0;    /* whether to warn about non-critical updates */
 static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */
 static char *upgrade_opts = NULL; /* options to override defaults for upgrade */
 static char *update_opts = NULL; /* options to override defaults for update */
@@ -110,7 +111,7 @@ int main (int argc, char **argv) {
 
 	if(sec_count > 0){
 		result = max_state(result, STATE_CRITICAL);
-	} else if(packages_available > 0){
+	} else if(packages_available > 0 && only_critical == 0){
 		result = max_state(result, STATE_WARNING);
 	} else if(result > STATE_UNKNOWN){
 		result = STATE_UNKNOWN;
@@ -148,12 +149,13 @@ int process_arguments (int argc, char **argv) {
 		{"include", required_argument, 0, 'i'},
 		{"exclude", required_argument, 0, 'e'},
 		{"critical", required_argument, 0, 'c'},
+		{"only-critical", no_argument, 0, 'o'},
 		{"input-file", required_argument, 0, INPUT_FILE_OPT},
 		{0, 0, 0, 0}
 	};
 
 	while(1) {
-		c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:", longopts, NULL);
+		c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:o", longopts, NULL);
 
 		if(c == -1 || c == EOF || c == 1) break;
 
@@ -203,6 +205,9 @@ int process_arguments (int argc, char **argv) {
 		case 'c':
 			do_critical=add_to_regexp(do_critical, optarg);
 			break;
+		case 'o':
+			only_critical=1;
+			break;
 		case INPUT_FILE_OPT:
 			input_filename = optarg;
 			break;
@@ -463,7 +468,11 @@ print_help (void)
   printf ("    %s\n", _("upgrades for Debian and Ubuntu:"));
   printf ("    \t\%s\n", SECURITY_RE);
   printf ("    %s\n", _("Note that the package must first match the include list before its"));
-  printf ("    %s\n\n", _("information is compared against the critical list."));
+  printf ("    %s\n", _("information is compared against the critical list."));
+  printf (" %s\n", "-o, --only-critical");
+  printf ("    %s\n", _("Only warn about upgrades matching the critical list.  The total number"));
+  printf ("    %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause"));
+  printf ("    %s\n\n", _("the plugin to return WARNING status."));
 
   printf ("%s\n\n", _("The following options require root privileges and should be used with care:"));
   printf (" %s\n", "-u, --update=OPTS");

+ 55 - 70
plugins/check_disk.c

@@ -28,7 +28,7 @@
 
 const char *progname = "check_disk";
 const char *program_name = "check_disk";  /* Required for coreutils libs */
-const char *copyright = "1999-2014";
+const char *copyright = "1999-2018";
 const char *email = "devel@nagios-plugins.org";
 
 
@@ -127,7 +127,6 @@ enum
 int process_arguments (int, char **);
 void print_path (const char *mypath);
 void set_all_thresholds (struct parameter_list *path);
-int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
 void print_help (void);
 void print_usage (void);
 double calculate_percent(uintmax_t, uintmax_t);
@@ -147,6 +146,7 @@ int erronly = FALSE;
 int display_mntp = FALSE;
 int exact_match = FALSE;
 int freespace_ignore_reserved = FALSE;
+int show_status = FALSE;
 char *warn_freespace_units = NULL;
 char *crit_freespace_units = NULL;
 char *warn_freespace_percent = NULL;
@@ -171,16 +171,15 @@ main (int argc, char **argv)
   int result = STATE_UNKNOWN;
   int disk_result = STATE_UNKNOWN;
   char *output;
-  char *details;
+  char status_lit[4];
   char *perf;
   char *preamble;
-  char *flag_header;
   double inode_space_pct;
   double warning_high_tide;
   double critical_high_tide;
   int temp_result;
 
-  struct mount_entry *me;
+  struct mount_entry *me, *last_me = NULL;
   struct fs_usage fsp, tmpfsp;
   struct parameter_list *temp_list, *path;
 
@@ -190,7 +189,6 @@ main (int argc, char **argv)
 
   preamble = strdup (" - free space:");
   output = strdup ("");
-  details = strdup ("");
   perf = strdup ("");
   stat_buf = malloc(sizeof *stat_buf);
 
@@ -206,11 +204,37 @@ main (int argc, char **argv)
   if (process_arguments (argc, argv) == ERROR)
     usage4 (_("Could not parse arguments"));
 
+  if (show_status)
+    sprintf(status_lit, "x:");
+  else
+    status_lit[0] = '\0';
+
   /* If a list of paths has not been selected, find entire
      mount list and create list of paths
    */
   if (path_selected == FALSE) {
     for (me = mount_list; me; me = me->me_next) {
+			if (strcmp(me->me_type, "autofs") == 0 && show_local_fs) {
+				if (last_me == NULL)
+					mount_list = me;
+				else
+					last_me->me_next = me->me_next;
+				free_mount_entry (me);
+				continue;
+			}
+			if (strcmp(me->me_type, "sysfs") == 0 || strcmp(me->me_type, "proc") == 0
+			|| strcmp(me->me_type, "debugfs") == 0 || strcmp(me->me_type, "tracefs") == 0
+			|| strcmp(me->me_type, "fusectl") == 0 || strcmp(me->me_type, "fuse.gvfsd-fuse") == 0
+			|| strcmp(me->me_type, "cgroup") == 0 || strstr(me->me_type, "tmpfs") != NULL)
+			{
+				if (last_me == NULL)
+					mount_list = me->me_next;
+				else
+					last_me->me_next = me->me_next;
+				free_mount_entry (me);
+				continue;
+			}
+
       if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
         path = np_add_parameter(&path_select_list, me->me_mountdir);
       }
@@ -291,7 +315,7 @@ main (int argc, char **argv)
       get_stats (path, &fsp);
 
       if (verbose >= 3) {
-        printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%llu mult=%llu\n",
+        printf ("For %s, used_pct=%g free_pct=%g used_units=%i free_units=%i total_units=%i used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%llu mult=%llu\n",
           me->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult);
       }
 
@@ -321,6 +345,9 @@ main (int argc, char **argv)
       if (verbose >=3) printf("Freeinodes_percent result=%d\n", temp_result);
       disk_result = max_state( disk_result, temp_result );
 
+      if (show_status)
+        status_lit[0] = state_text(disk_result)[0];
+
       result = max_state(result, disk_result);
 
       /* What a mess of units. The output shows free space, the perf data shows used space. Yikes!
@@ -357,14 +384,10 @@ main (int argc, char **argv)
       if (disk_result==STATE_OK && erronly && !verbose)
         continue;
 
-      if (disk_result && verbose) {
-	      xasprintf(&flag_header, " %s [", state_text (disk_result));
-      }
-      else {
-	      xasprintf(&flag_header, "");
-      }
-      xasprintf (&output, "%s %s %.0f %s (%.2f%%",
+      xasprintf (&output, "%s%s%s%s %i %s (%.2f%%",
                 output,
+                newlines ? "" : " ",
+                status_lit,
                 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
                 path->dfree_units,
                 units,
@@ -384,8 +407,6 @@ main (int argc, char **argv)
         }
       }
 
-      free(flag_header);
-
       /* TODO: Need to do a similar debug line
       xasprintf (&details, _("%s\n\
 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
@@ -398,9 +419,6 @@ main (int argc, char **argv)
 
   }
 
-  if (verbose >= 2)
-    xasprintf (&output, "%s%s", output, details);
-
   if (newlines) {
     printf ("DISK %s%s\n%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf);
   } else {
@@ -483,6 +501,7 @@ process_arguments (int argc, char **argv)
     {"errors-only", no_argument, 0, 'e'},
     {"exact-match", no_argument, 0, 'E'},
     {"all", no_argument, 0, 'A'},
+    {"show-status", no_argument, 0, 's'},
     {"verbose", no_argument, 0, 'v'},
     {"quiet", no_argument, 0, 'q'},
     {"clear", no_argument, 0, 'C'},
@@ -502,7 +521,7 @@ process_arguments (int argc, char **argv)
       strcpy (argv[c], "-t");
 
   while (1) {
-    c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEAn", longopts, &option);
+    c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEAns", longopts, &option);
 
     if (c == -1 || c == EOF)
       break;
@@ -703,6 +722,10 @@ process_arguments (int argc, char **argv)
       cflags = default_cflags;
       break;
 
+    case 's':
+      show_status = TRUE;
+			break;
+
     case 'A':
       optarg = strdup(".*");
     case 'R':
@@ -839,50 +862,6 @@ set_all_thresholds (struct parameter_list *path)
     set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
 }
 
-/* TODO: Remove?
-
-int
-validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
-{
-  if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
-    printf (_("INPUT ERROR: No thresholds specified"));
-    print_path (mypath);
-    return ERROR;
-  }
-  else if ((wp >= 0.0 || cp >= 0.0) &&
-           (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
-    printf (_("\
-INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
-            cp, wp);
-    print_path (mypath);
-    return ERROR;
-  }
-  else if ((iwp >= 0.0 || icp >= 0.0) &&
-           (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
-    printf (_("\
-INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
-            icp, iwp);
-    print_path (mypath);
-    return ERROR;
-  }
-  else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
-    printf (_("\
-INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
-            (unsigned long)c, (unsigned long)w);
-    print_path (mypath);
-    return ERROR;
-  }
-
-  return OK;
-}
-
-*/
-
-
-
-
-
-
 
 void
 print_help (void)
@@ -949,6 +928,8 @@ print_help (void)
   printf ("    %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)"));
   printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION");
   printf ("    %s\n", _("Regular expression to ignore selected path or partition (may be repeated)"));
+  printf (" %s\n", "-s, --show-status");
+  printf ("    %s\n", _("Show status for each path/partition"));
   printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
   printf (" %s\n", "-u, --units=STRING");
   printf ("    %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
@@ -980,16 +961,20 @@ print_usage (void)
 {
   printf ("%s\n", _("Usage:"));
   printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname);
-  printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
-  printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type] [-n]\n");
+  printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] {-A | [-R path] [-r path]}\n");
+  printf ("[-s] [-t timeout] [-u unit] [-v] [-X type] [-N type] [-n]\n");
 }
 
 void
 stat_path (struct parameter_list *p)
 {
   /* Stat entry to check that dir exists and is accessible */
-  if (verbose >= 3)
-    printf("calling stat on %s\n", p->name);
+  if (verbose >= 3) {
+    if (p->best_match)
+      printf("calling stat on %s (%s %s)\n", p->name, p->best_match->me_devname, p->best_match->me_type);
+    else
+      printf("calling stat on %s\n", p->name);
+  }
   if (stat (p->name, &stat_buf[0])) {
     if (verbose >= 3)
       printf("stat failed on %s\n", p->name);
@@ -1019,7 +1004,7 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
         get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
         get_path_stats(p_list, &tmpfsp); 
         if (verbose >= 3)
-          printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n",
+          printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%i free_units=%i total_units=%i fsu_blocksize=%llu mult=%llu\n",
                  p_list->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, p_list->dfree_units,
                  p_list->dtotal_units, mult);
 
@@ -1040,7 +1025,7 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
         first = 0;
       }
       if (verbose >= 3) 
-        printf("Group %s now has: used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n",
+        printf("Group %s now has: used_units=%1 free_units=%1 total_units=%1 fsu_blocksize=%llu mult=%llu\n",
                p->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p->best_match->me_mountdir, p->dused_units,
                p->dfree_units, p->dtotal_units, mult);
     }

Datei-Diff unterdrückt, da er zu groß ist
+ 1119 - 1084
plugins/check_http.c


+ 65 - 12
plugins/check_ldap.c

@@ -76,6 +76,9 @@ int starttls = FALSE;
 int ssl_on_connect = FALSE;
 int verbose = 0;
 
+int check_cert = FALSE;
+int days_till_exp_warn, days_till_exp_crit;
+
 /* for ldap tls */
 
 char *SERVICE = "LDAP";
@@ -183,6 +186,9 @@ main (int argc, char *argv[])
 			printf (_("Could not init TLS at port %i!\n"), ld_port);
 			return STATE_CRITICAL;
 		}
+
+		if (check_cert == TRUE)
+			return ldap_check_cert(ld);
 #else
 		printf (_("TLS not supported by the libraries!\n"));
 		return STATE_CRITICAL;
@@ -207,6 +213,9 @@ main (int argc, char *argv[])
 			printf (_("Could not init startTLS at port %i!\n"), ld_port);
 			return STATE_CRITICAL;
 		}
+
+		if (check_cert == TRUE)
+			return ldap_check_cert(ld);
 #else
 		printf (_("startTLS not supported by the library, needs LDAPv3!\n"));
 		return STATE_CRITICAL;
@@ -296,6 +305,7 @@ int
 process_arguments (int argc, char **argv)
 {
 	int c;
+	char *temp;
 
 	int option = 0;
 	/* initialize the long option struct */
@@ -315,6 +325,7 @@ process_arguments (int argc, char **argv)
 #endif
 		{"starttls", no_argument, 0, 'T'},
 		{"ssl", no_argument, 0, 'S'},
+		{"age", required_argument, 0, 'A'},
 		{"use-ipv4", no_argument, 0, '4'},
 		{"use-ipv6", no_argument, 0, '6'},
 		{"port", required_argument, 0, 'p'},
@@ -335,7 +346,7 @@ process_arguments (int argc, char **argv)
 	}
 
 	while (1) {
-		c = getopt_long (argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:U:C:W:", longopts, &option);
+		c = getopt_long (argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:U:C:W:A:", longopts, &option);
 
 		if (c == -1 || c == EOF)
 			break;
@@ -403,6 +414,33 @@ process_arguments (int argc, char **argv)
 			else
 				usage_va(_("%s cannot be combined with %s"), "-T/--starttls", "-S/--ssl");
 			break;
+		case 'A': /* Check SSL cert validity */
+#ifndef HAVE_SSL
+			usage4 (_("Invalid option - SSL is not available"));
+#else
+			if (starttls || ssl_on_connect || strstr(argv[0],"check_ldaps")) {
+				if ((temp=strchr(optarg,','))!=NULL) {
+					*temp = '\0';
+					if (!is_intnonneg (temp))
+						usage2 (_("Invalid certificate expiration period"), optarg);
+					days_till_exp_warn = atoi(optarg);
+					*temp = ',';
+					temp++;
+					if (!is_intnonneg (temp))
+						usage2 (_("Invalid certificate expiration period"), temp);
+						days_till_exp_crit = atoi (temp);
+				} else {
+					days_till_exp_crit = 0;
+					if (!is_intnonneg (optarg))
+						usage2 (_("Invalid certificate expiration period"), optarg);
+					days_till_exp_warn = atoi (optarg);
+				}
+				check_cert = TRUE;
+			} else {
+				usage_va(_("%s requires either %s or %s"), "-A/--age", "-S/--ssl", "-T/--starttls");
+			}
+			break;
+#endif
 		case 'S':
 			if (! starttls) {
 				ssl_on_connect = TRUE;
@@ -477,32 +515,34 @@ print_help (void)
 
 	printf (UT_IPv46);
 
-	printf (" %s\n", "-a [--attr]");
+	printf (" %s\n", "-a, --attr=ATTRIBUTE");
   printf ("    %s\n", _("ldap attribute to search (default: \"(objectclass=*)\""));
-  printf (" %s\n", "-b [--base]");
+  printf (" %s\n", "-b, --base=BASE");
   printf ("    %s\n", _("ldap base (eg. ou=my unit, o=my org, c=at"));
-  printf (" %s\n", "-D [--bind]");
+  printf (" %s\n", "-D, --bind=DN");
   printf ("    %s\n", _("ldap bind DN (if required)"));
-  printf (" %s\n", "-P [--pass]");
+  printf (" %s\n", "-P, --pass=PASSWORD");
   printf ("    %s\n", _("ldap password (if required)"));
-  printf (" %s\n", "-T [--starttls]");
+  printf (" %s\n", "-T, --starttls");
   printf ("    %s\n", _("use starttls mechanism introduced in protocol version 3"));
-  printf (" %s\n", "-S [--ssl]");
+  printf (" %s\n", "-S, --ssl");
   printf ("    %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT);
+  printf (" %s\n", "-A, --age=INTEGER[,INTEGER]");
+  printf ("    %s\n", _("Minimum number of days a certificate has to be valid"));
 
 #ifdef HAVE_LDAP_SET_OPTION
-	printf (" %s\n", "-2 [--ver2]");
+	printf (" %s\n", "-2, --ver2");
   printf ("    %s\n", _("use ldap protocol version 2"));
-  printf (" %s\n", "-3 [--ver3]");
+  printf (" %s\n", "-3, --ver3");
   printf ("    %s\n", _("use ldap protocol version 3"));
   printf ("    (%s %d)\n", _("default protocol version:"), DEFAULT_PROTOCOL);
 #endif
 
 	printf (UT_WARN_CRIT);
 
-  printf (" %s\n", "-W [--warn-entries]");
+  printf (" %s\n", "-W, --warn-entries=INTEGER");
   printf ("    %s\n", _("Number of found entries to result in warning status"));
-  printf (" %s\n", "-C [--crit-entries]");
+  printf (" %s\n", "-C, --crit-entries=INTEGER");
   printf ("    %s\n", _("Number of found entries to result in critical status"));
 
 	printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
@@ -526,7 +566,7 @@ print_usage (void)
 {
   printf ("%s\n", _("Usage:"));
   printf (" %s (-H <host>|-U <uri>) -b <base_dn> [-p <port>] [-a <attr>] [-D <binddn>]\n", progname);
-  printf ("       [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout]%s\n",
+  printf ("       [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout] [-A <age>]%s\n",
 #ifdef HAVE_LDAP_SET_OPTION
 			"\n       [-2|-3] [-4|-6]"
 #else
@@ -534,3 +574,16 @@ print_usage (void)
 #endif
 			);
 }
+
+int ldap_check_cert (LDAP *ld)
+{
+	SSL *ssl;
+	int rc;
+
+	rc = ldap_get_option(ld, LDAP_OPT_X_TLS_SSL_CTX, &ssl);
+	if (rc == LDAP_OPT_ERROR || ssl == NULL) {
+		printf ("%s\n",_("CRITICAL - Cannot retrieve ssl session from connection."));
+		return STATE_CRITICAL;
+	}
+	return np_net_ssl_check_cert_real(ssl, days_till_exp_warn, days_till_exp_crit);
+}

+ 1 - 0
plugins/check_nagios.c

@@ -64,6 +64,7 @@ main (int argc, char **argv)
 	int procuid = 0;
 	int procpid = 0;
 	int procppid = 0;
+	int procjid = 0;
 	int procvsz = 0;
 	int procrss = 0;
 	char proc_cgroup_hierarchy[MAX_INPUT_BUFFER];

+ 7 - 0
plugins/check_ntp_time.c

@@ -80,6 +80,7 @@ typedef struct {
 /* this structure holds data about results from querying offset from a peer */
 typedef struct {
 	time_t waiting;         /* ts set when we started waiting for a response */
+	int connected;          /* don't try to "write()" if "connect()" fails */
 	int num_responses;      /* number of successfully recieved responses */
 	uint8_t stratum;        /* copied verbatim from the ntp_message */
 	double rtdelay;         /* converted from the ntp_message */
@@ -355,6 +356,7 @@ double offset_request(const char *host, int *status){
 			ufds[i].fd=socklist[i];
 			ufds[i].events=POLLIN;
 			ufds[i].revents=0;
+			servers[i].connected=1;
 		}
 		ai_tmp = ai_tmp->ai_next;
 	}
@@ -370,6 +372,8 @@ double offset_request(const char *host, int *status){
 		now_time=time(NULL);
 
 		for(i=0; i<num_hosts; i++){
+			if(servers[i].connected == 0)
+				continue;
 			if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){
 				if(verbose && servers[i].waiting != 0) printf("re-");
 				if(verbose) printf("sending request to peer %d\n", i);
@@ -413,6 +417,9 @@ double offset_request(const char *host, int *status){
 			}
 		}
 		/* lather, rinse, repeat. */
+		/* break if we have one response but other ntp servers doesn't response */
+		/* greater than timeout_interval/2 */
+		if (servers_completed && now_time-start_ts > timeout_interval/2) break;
 	}
 
 	if (one_read == 0) {

+ 19 - 1
plugins/check_ping.c

@@ -54,6 +54,7 @@ void print_usage (void);
 void print_help (void);
 
 int display_html = FALSE;
+int show_resolution = FALSE;
 int wpl = UNKNOWN_PACKET_LOSS;
 int cpl = UNKNOWN_PACKET_LOSS;
 float wrta = UNKNOWN_TRIP_TIME;
@@ -67,6 +68,8 @@ int verbose = 0;
 float rta = UNKNOWN_TRIP_TIME;
 int pl = UNKNOWN_PACKET_LOSS;
 
+char ping_name[256];
+char ping_ip_addr[64];
 char *warn_text;
 
 
@@ -159,6 +162,12 @@ main (int argc, char **argv)
 		else
 			printf (_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"),
 							state_text (this_result), warn_text, pl, rta);
+		if (show_resolution) {
+			if (strcmp(ping_name, ping_ip_addr) == 0)
+				printf(" - %s", ping_name);
+			else
+				printf(" - %s (%s)", ping_name, ping_ip_addr);
+		}
 		if (display_html == TRUE)
 			printf ("</A>");
 
@@ -196,6 +205,7 @@ process_arguments (int argc, char **argv)
 	static struct option longopts[] = {
 		STD_LONG_OPTS,
 		{"packets", required_argument, 0, 'p'},
+		{"show-resolution", no_argument, 0, 's'},
 		{"nohtml", no_argument, 0, 'n'},
 		{"link", no_argument, 0, 'L'},
 		{"use-ipv4", no_argument, 0, '4'},
@@ -214,7 +224,7 @@ process_arguments (int argc, char **argv)
 	}
 
 	while (1) {
-		c = getopt_long (argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
+		c = getopt_long (argc, argv, "VvhsnL46t:c:w:H:p:", longopts, &option);
 
 		if (c == -1 || c == EOF)
 			break;
@@ -271,6 +281,9 @@ process_arguments (int argc, char **argv)
 			else
 				usage2 (_("<max_packets> (%s) must be a non-negative number\n"), optarg);
 			break;
+		case 's':
+			show_resolution = TRUE;
+			break;
 		case 'n':	/* no HTML */
 			display_html = FALSE;
 			break;
@@ -448,6 +461,9 @@ run_ping (const char *cmd, const char *addr)
 
 		result = max_state (result, error_scan (buf, addr));
 
+		if(sscanf(buf, "PING %255s (%63[^)]", &ping_name, &ping_ip_addr))
+			continue;
+
 		/* get the percent loss statistics */
 		match = 0;
 		if((sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
@@ -585,6 +601,8 @@ print_help (void)
   printf (" %s\n", "-p, --packets=INTEGER");
   printf ("    %s ", _("number of ICMP ECHO packets to send"));
   printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
+	printf (" %s\n", "-s, --show-resolution");
+	printf ("    %s\n", _("show name resolution in the plugin output (DNS & IP)"));
   printf (" %s\n", "-L, --link");
   printf ("    %s\n", _("show HTML in the plugin output (obsoleted by urlize)"));
 

+ 65 - 7
plugins/check_procs.c

@@ -71,6 +71,8 @@ int options = 0; /* bitmask of filter criteria to test against */
 #define ELAPSED 512
 #define EREG_ARGS 1024
 #define CGROUP_HIERARCHY 2048
+#define EXCLUDE_PROGS 4096
+#define JID 8192
 
 #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
 							ppid of procs are compared to pid of this proc*/
@@ -94,6 +96,9 @@ int rss;
 float pcpu;
 char *statopts;
 char *prog;
+char *exclude_progs;
+char ** exclude_progs_arr = NULL;
+char exclude_progs_counter = 0; 
 char *cgroup_hierarchy;
 char *args;
 char *input_filename = NULL;
@@ -103,6 +108,7 @@ char *fails;
 char tmp[MAX_INPUT_BUFFER];
 int kthread_filter = 0;
 int usepid = 0; /* whether to test for pid or /proc/pid/exe */
+int jid;
 
 FILE *ps_input = NULL;
 
@@ -133,6 +139,7 @@ main (int argc, char **argv)
 	int procuid = 0;
 	pid_t procpid = 0;
 	pid_t procppid = 0;
+	int procjid = 0;
 	pid_t kthread_ppid = 0;
 	int procvsz = 0;
 	int procrss = 0;
@@ -236,9 +243,9 @@ main (int argc, char **argv)
 			procseconds = convert_to_seconds(procetime);
 
 			if (verbose >= 3) {
-				printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s",
++				printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d jid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
 					procs, procuid, procvsz, procrss,
-					procpid, procppid, procpcpu, procstat,
+					procpid, procppid, procjid, procpcpu, procstat,
 					procetime, procprog, procargs);
 				if (strstr(PS_COMMAND, "cgroup") != NULL) {
 					printf(" proc_cgroup_hierarchy=%s\n", proc_cgroup_hierarchy);
@@ -262,6 +269,26 @@ main (int argc, char **argv)
 				continue;
 			}
 
+			/* Ignore excluded processes by name */
+			if(options & EXCLUDE_PROGS) {
+			  int found = 0;
+			  int i = 0;
+			 
+			  
+			  for(i=0; i < (exclude_progs_counter); i++) {
+			    if(!strcmp(procprog, exclude_progs_arr[i])) {
+			      found = 1;
+			    }
+			  }
+			  if(found == 0) {
+			    resultsum |= EXCLUDE_PROGS;
+			  }else
+			  {
+                            if(verbose >= 3)
+			      printf("excluding - by ignorelist\n");
+                          }
+			}
+
 			/* filter kernel threads (childs of KTHREAD_PARENT)*/
 			/* TODO adapt for other OSes than GNU/Linux
 					sorry for not doing that, but I've no other OSes to test :-( */
@@ -287,6 +314,8 @@ main (int argc, char **argv)
 				resultsum |= PROG;
 			if ((options & PPID) && (procppid == ppid))
 				resultsum |= PPID;
+			if ((options & JID) && (procjid == jid))
+				resultsum |= JID;
 			if ((options & USER) && (procuid == uid))
 				resultsum |= USER;
 			if ((options & VSZ)  && (procvsz >= vsz))
@@ -315,9 +344,9 @@ main (int argc, char **argv)
 
 			procs++;
 			if (verbose >= 2) {
-				printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s",
++				printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d jid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
 					procuid, procvsz, procrss,
-					procpid, procppid, procpcpu, procstat, 
+					procpid, procppid, procjid, procpcpu, procstat,
 					procetime, procprog, procargs);
 				if (strstr(PS_COMMAND, "cgroup") != NULL) {
 					printf(" cgroup_hierarchy=%s\n", cgroup_hierarchy);
@@ -438,6 +467,8 @@ process_arguments (int argc, char **argv)
 		{"no-kthreads", required_argument, 0, 'k'},
 		{"traditional-filter", no_argument, 0, 'T'},
 		{"cgroup-hierarchy", required_argument, 0, 'g'},
+		{"exclude-process", required_argument, 0, 'X'},
+		{"jid", required_argument, 0, 'j'},
 		{0, 0, 0, 0}
 	};
 
@@ -446,7 +477,7 @@ process_arguments (int argc, char **argv)
 			strcpy (argv[c], "-t");
 
 	while (1) {
-		c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:Tg:",
+		c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:Tg:X:j:",
 			longopts, &option);
 
 		if (c == -1 || c == EOF)
@@ -477,6 +508,12 @@ process_arguments (int argc, char **argv)
 				break;
 			}
 			usage4 (_("Parent Process ID must be an integer!"));
+		case 'j':                                   /* jail id */
+			if (sscanf (optarg, "%d%[^0-9]", &jid, tmp) == 1) {
+				xasprintf (&fmt, "%s%sJID = %d", (fmt ? fmt : "") , (options ? ", " : ""), jid);
+				options |= JID;
+				break;
+			}
 		case 's':									/* status */
 			if (statopts)
 				break;
@@ -516,6 +553,23 @@ process_arguments (int argc, char **argv)
 			          prog);
 			options |= PROG;
 			break;
+		case 'X':
+		        if(exclude_progs)
+			  break;
+			else
+			  exclude_progs = optarg;
+			xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
+				   exclude_progs);
+			char *p = strtok(exclude_progs, ",");
+
+			while(p){
+			  exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter);
+			  exclude_progs_arr[exclude_progs_counter-1] = p;
+			  p = strtok(NULL, ",");
+			}
+
+			options |= EXCLUDE_PROGS;
+			break;
 		case 'g':									/* cgroup hierarchy */
 			if (cgroup_hierarchy)
 				break;
@@ -766,6 +820,8 @@ print_help (void)
   printf ("   %s\n", _("RSZDT, plus others based on the output of your 'ps' command)."));
   printf (" %s\n", "-p, --ppid=PPID");
   printf ("   %s\n", _("Only scan for children of the parent process ID indicated."));
+  printf (" %s\n", "-j, --jid=JID");
+  printf ("   %s\n", _("Only scan for process running in jail which ID is JID."));
   printf (" %s\n", "-z, --vsz=VSZ");
   printf ("   %s\n", _("Only scan for processes with VSZ higher than indicated."));
   printf (" %s\n", "-r, --rss=RSS");
@@ -780,6 +836,8 @@ print_help (void)
   printf ("   %s\n", _("Only scan for processes with args that contain the regex STRING."));
   printf (" %s\n", "-C, --command=COMMAND");
   printf ("   %s\n", _("Only scan for exact matches of COMMAND (without path)."));
+  printf (" %s\n", "-C, --exclude-process");
+  printf ("   %s\n", _("Exclude processes which match this comma seperated list"));
   printf (" %s\n", "-k, --no-kthreads");
   printf ("   %s\n", _("Only scan for non kernel threads (works on Linux only)."));
   printf (" %s\n", "-g, --cgroup-hierarchy");
@@ -818,7 +876,7 @@ void
 print_usage (void)
 {
   printf ("%s\n", _("Usage:"));
-	printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
+	printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid] [-j jid]\n", progname);
   printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
-  printf (" [-C command] [-k] [-t timeout] [-v]\n");
+  printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");
 }

+ 68 - 2
plugins/check_radius.c

@@ -36,6 +36,17 @@ const char *email = "devel@nagios-plugins.org";
 #include "utils.h"
 #include "netutils.h"
 
+#include <ifaddrs.h>
+
+#ifdef __FreeBSD__
+#include <net/if_dl.h>
+#else
+#include <linux/if_packet.h>
+#define AF_LINK AF_PACKET
+#define LLADDR(l) ((l)->sll_addr)
+#define sockaddr_dl sockaddr_ll
+#endif
+
 #if defined(HAVE_LIBFREERADIUS_CLIENT)
 #include <freeradius-client.h>
 #elif defined(HAVE_LIBRADIUSCLIENT_NG)
@@ -47,6 +58,7 @@ const char *email = "devel@nagios-plugins.org";
 int process_arguments (int, char **);
 void print_help (void);
 void print_usage (void);
+char *get_ether_addr(uint32_t client_id);
 
 #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG)
 #define my_rc_conf_str(a) rc_conf_str(rch,a)
@@ -85,6 +97,7 @@ char *username = NULL;
 char *password = NULL;
 char *nasid = NULL;
 char *nasipaddress = NULL;
+char *castid = NULL;
 char *expect = NULL;
 char *config_file = NULL;
 unsigned short port = PW_AUTH_UDP_PORT;
@@ -154,6 +167,7 @@ main (int argc, char **argv)
 	SEND_DATA data;
 	int result = STATE_UNKNOWN;
 	uint32_t client_id, service;
+	char *ether;
 	char *str;
 
 	setlocale (LC_ALL, "");
@@ -197,6 +211,14 @@ main (int argc, char **argv)
 	if (my_rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL)
 		die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
 
+	if (castid != NULL) {
+		if (!(my_rc_avpair_add (&data.send_pairs, PW_CALLING_STATION_ID, castid, 0)))
+			die (STATE_UNKNOWN, _("Invalid Calling-Station-Id\n"));
+	} else if ((ether = get_ether_addr(client_id)) != NULL) {
+		if (!(my_rc_avpair_add (&data.send_pairs, PW_CALLING_STATION_ID, ether, 0)))
+			die (STATE_UNKNOWN, _("Invalid Calling-Station-Id\n"));
+	}
+
 	my_rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval,
 	             retries);
 
@@ -237,6 +259,7 @@ process_arguments (int argc, char **argv)
 		{"password", required_argument, 0, 'p'},
 		{"nas-id", required_argument, 0, 'n'},
 		{"nas-ip-address", required_argument, 0, 'N'},
+		{"calling-station-id", required_argument, 0, 'c'},
 		{"filename", required_argument, 0, 'F'},
 		{"expect", required_argument, 0, 'e'},
 		{"retries", required_argument, 0, 'r'},
@@ -248,8 +271,8 @@ process_arguments (int argc, char **argv)
 	};
 
 	while (1) {
-		c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts,
-									 &option);
+		c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:N:c:t:r:e:", longopts,
+									   &option);
 
 		if (c == -1 || c == EOF || c == 1)
 			break;
@@ -296,6 +319,9 @@ process_arguments (int argc, char **argv)
 		case 'N':									/* nas ip address */
 			nasipaddress = optarg;
 			break;
+		case 'c':									/* calling station id */
+			castid = optarg;
+			break;
 		case 'F':									/* configuration file */
 			config_file = optarg;
 			break;
@@ -358,6 +384,8 @@ print_help (void)
   printf ("    %s\n", _("NAS identifier"));
   printf (" %s\n", "-N, --nas-ip-address=STRING");
   printf ("    %s\n", _("NAS IP Address"));
+  printf (" %s\n", "-c, --calling-station-id=STRING");
+  printf ("    %s\n", _("Calling Station identifier"));
   printf (" %s\n", "-F, --filename=STRING");
   printf ("    %s\n", _("Configuration file"));
   printf (" %s\n", "-e, --expect=STRING");
@@ -403,3 +431,41 @@ int my_rc_read_config(char * a)
 	return rc_read_config(a);
 #endif
 }
+
+char *get_ether_addr(uint32_t client_id)
+{
+	static char ether_addr[18];
+	struct ifaddrs *ifap, *ifa, *ifb;
+	struct sockaddr_in *sain;
+	unsigned char *lladdr;
+
+	getifaddrs(&ifap);
+
+	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
+		if (ifa->ifa_addr->sa_family == AF_INET) {
+			sain = (struct sockaddr_in *)ifa->ifa_addr;
+			if (client_id == ntohl(sain->sin_addr.s_addr))
+				break;
+		}
+	if (ifa == NULL) {
+		freeifaddrs(ifap);
+		return NULL;
+	}
+
+	ifb = ifa;
+	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
+		if (ifa->ifa_addr->sa_family == AF_LINK
+		    && strcmp(ifa->ifa_name, ifb->ifa_name) == 0)
+			break;
+	if (ifa == NULL) {
+		freeifaddrs(ifap);
+		return NULL;
+	}
+
+	lladdr = (unsigned char *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr);
+	sprintf(ether_addr, "%02X-%02X-%02X-%02X-%02X-%02X",
+	    lladdr[0], lladdr[1], lladdr[2], lladdr[3], lladdr[4], lladdr[5]);
+
+	freeifaddrs(ifap);
+	return ether_addr;
+}

+ 78 - 30
plugins/check_snmp.c

@@ -288,6 +288,7 @@ main (int argc, char **argv)
 		set_thresholds(&thlds[i],
 		               w ? strpbrk(w, NP_THRESHOLDS_CHARS) : NULL,
 		               c ? strpbrk(c, NP_THRESHOLDS_CHARS) : NULL);
+
 		if (w) {
 			th_warn=strchr(th_warn, ',');
 			if (th_warn) th_warn++;
@@ -332,7 +333,7 @@ main (int argc, char **argv)
 
 	/* This is just for display purposes, so it can remain a string */
 	xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s %s %s %s:%s",
-		snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[context]", "[authpriv]",
+		snmpcmd, command_interval, retries, strlen(miblist) ? miblist : "''", proto, "[context]", "[authpriv]",
 		server_address, port);
 
 	for (i = 0; i < numoids; i++) {
@@ -486,6 +487,7 @@ main (int argc, char **argv)
 		/* Process this block for numeric comparisons */
 		/* Make some special values,like Timeticks numeric only if a threshold is defined */
 		if (thlds[i]->warning || thlds[i]->critical || calculate_rate || is_ticks || offset != 0.0) {
+
 			ptr = strpbrk (show, "-0123456789");
 			if (ptr == NULL)
 				die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show);
@@ -574,50 +576,96 @@ main (int argc, char **argv)
 		ptr = NULL;
 		strtod(show, &ptr);
 		if (ptr > show) {
-			if (perf_labels && nlabels >= (size_t)1 && (size_t)i < nlabels && labels[i] != NULL)
-				temp_string=labels[i];
-			else
-				temp_string=oidname;
-			if (strpbrk (temp_string, " ='\"") == NULL) {
-				strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
+
+			/* use either specified label or oid as label */
+			if (perf_labels 
+				&& (nlabels >= (size_t)1) 
+				&& ((size_t)i < nlabels) 
+				&& labels[i] != NULL) {
+
+					temp_string=labels[i];
+			}
+			else {
+				temp_string = oidname;
+			}
+
+			/* check the label for space, equal, singlequote or doublequote */
+			if (strpbrk(temp_string, " ='\"") == NULL) {
+
+				/* if it doesn't have any - we can just use it as the label */
+				strncat(perfstr, temp_string, sizeof(perfstr) - strlen(perfstr) - 1);
+
 			} else {
-				if (strpbrk (temp_string, "'") == NULL) {
+
+				/* if it does have one of those characters, we need
+				   to find a way to adequately quote it */
+				if (strpbrk(temp_string, "'") == NULL) {
 					quote_string="'";
 				} else {
 					quote_string="\"";
 				}
-				strncat(perfstr, quote_string, sizeof(perfstr)-strlen(perfstr)-1);
-				strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
-				strncat(perfstr, quote_string, sizeof(perfstr)-strlen(perfstr)-1);
+
+				strncat(perfstr, quote_string, sizeof(perfstr) - strlen(perfstr) - 1);
+				strncat(perfstr, temp_string, sizeof(perfstr) - strlen(perfstr) - 1);
+				strncat(perfstr, quote_string, sizeof(perfstr) - strlen(perfstr) - 1);
 			}
-			strncat(perfstr, "=", sizeof(perfstr)-strlen(perfstr)-1);
-			len = sizeof(perfstr)-strlen(perfstr)-1;
-			strncat(perfstr, show, len>ptr-show ? ptr-show : len);
 
-			if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL) {
-				xasprintf (&temp_string, "%s", unitv[i]);
-				strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
-				}
+			/* append the equal */
+			strncat(perfstr, "=", sizeof(perfstr) - strlen(perfstr) - 1);
+			len = sizeof(perfstr) - strlen(perfstr) - 1;
+
+			/* and then the data itself from the response */
+			strncat(perfstr, show, (len > ptr - show) ? ptr - show : len);
 
-			if (type)
-				strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
+			/* now append the unit of measurement */
+			if ((nunits > (size_t)0) 
+				&& ((size_t)i < nunits) 
+				&& (unitv[i] != NULL)) {
+
+					xasprintf(&temp_string, "%s", unitv[i]);
+					strncat(perfstr, temp_string, sizeof(perfstr) - strlen(perfstr) - 1);
+			}
 
+			/* and the type, if any */
+			if (type) {
+				strncat(perfstr, type, sizeof(perfstr) - strlen(perfstr) - 1);
+			}
+
+			/* add warn/crit to perfdata */
 			if (thlds[i]->warning || thlds[i]->critical) {
-				strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
-				if (thlds[i]->warning) {
-					xasprintf (&temp_string, "%.0f", thlds[i]->warning->end);
-					strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
+
+				strncat(perfstr, ";", sizeof(perfstr) - strlen(perfstr) - 1);
+
+				/* print the warning string if it exists */
+				if (thlds[i]->warning_string) {
+
+					xasprintf(&temp_string, "%s", thlds[i]->warning_string);
+					strncat(perfstr, temp_string, sizeof(perfstr) - strlen(perfstr) - 1);
 				}
 				strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
-				if (thlds[i]->critical) {
-					xasprintf (&temp_string, "%.0f", thlds[i]->critical->end);
-					strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
+
+				/* print the critical string if it exists */
+				if (thlds[i]->critical_string) {
+
+					xasprintf(&temp_string, "%s", thlds[i]->critical_string);
+					strncat(perfstr, temp_string, sizeof(perfstr) - strlen(perfstr) - 1);
 				}
-				strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
+				strncat(perfstr, ";", sizeof(perfstr) - strlen(perfstr) - 1);
+			}
+
+			/* remove trailing semi-colons for guideline adherence */
+			len = strlen(perfstr) - 1;
+			if (perfstr[len] == ';') {
+				perfstr[len] = '\0';
 			}
-			strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1);
+
+			/* we do not add any min/max value */
+
+			strncat(perfstr, " ", sizeof(perfstr) - strlen(perfstr) - 1);
 		}
-	}
+
+	} /* for (line=0, i=0; line < chld_out.lines; line++, i++) */
+	
 	total_oids=i;
 
 	/* Save state data, as all data collected now */

+ 6 - 0
plugins/common.h

@@ -146,6 +146,9 @@
 #    include <rsa.h>
 #    include <crypto.h>
 #    include <x509.h>
+#    if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#      include <x509v3.h>
+#    endif
 #    include <pem.h>
 #    include <ssl.h>
 #    include <err.h>
@@ -154,6 +157,9 @@
 #      include <openssl/rsa.h>
 #      include <openssl/crypto.h>
 #      include <openssl/x509.h>
+#      if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#        include <openssl/x509v3.h>
+#      endif
 #      include <openssl/pem.h>
 #      include <openssl/ssl.h>
 #      include <openssl/err.h>

+ 30 - 0
plugins/netutils.c

@@ -392,3 +392,33 @@ resolve_host_or_addr (const char *address, int family)
 		return TRUE;
 	}
 }
+
+/* Turn a network address into a string */
+void
+parse_address_string(int address_family, struct sockaddr_storage *addr, char *address, int size)
+{
+	switch (address_family) {
+		case AF_INET:
+			inet_ntop(address_family, &((struct sockaddr_in *)addr)->sin_addr, address, size);
+		break;
+
+		case AF_INET6:
+			inet_ntop(address_family, &((struct sockaddr_in6 *)addr)->sin6_addr, address, size);
+		break;
+	}
+}
+
+/* Define the address length */
+char
+address_length(int address_family)
+{
+	switch (address_family) {
+		case AF_INET:
+			return INET_ADDRSTRLEN;
+		break;
+
+		case AF_INET6:
+			return INET6_ADDRSTRLEN;
+		break;
+	}
+}

+ 1 - 0
plugins/netutils.h

@@ -108,6 +108,7 @@ void np_net_ssl_cleanup();
 int np_net_ssl_write(const void *buf, int num);
 int np_net_ssl_read(void *buf, int num);
 int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit);
+int np_net_ssl_check_cert_real(SSL *ssl, int days_till_exp_warn, int days_till_exp_crit);
 #endif /* HAVE_SSL */
 
 #endif /* NAGIOS_NETUGILS_H_INCLUDED_ */

+ 257 - 0
plugins/remove_perfdata.c

@@ -0,0 +1,257 @@
+/*****************************************************************************
+* 
+* Nagios remove perfdata plugin
+* 
+* License: GPL
+* Copyright (c) 2002-2017 Nagios Plugins Development Team
+* 
+* Description:
+* 
+* This file contains the remove_perfdata plugin
+* 
+* Removes perfdata from a specified plugin's output. Optionally,
+* you can choose to remove any long output as well
+* 
+* 
+* 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 <http://www.gnu.org/licenses/>.
+* 
+* 
+*****************************************************************************/
+
+const char *progname = "remove_perfdata";
+const char *copyright = "2002-2017";
+const char *email = "devel@nagios-plugins.org";
+
+/* timeout should be handled in the plugin being called */
+#define DEFAULT_TIMEOUT 300
+
+#include "common.h"
+#include "utils.h"
+#include "utils_cmd.h"
+
+#include <ctype.h>
+
+static const char **process_arguments(int, char **);
+void validate_arguments(char **);
+void print_help(void);
+void print_usage(void);
+int remove_perfdata = 1;
+int remove_long_output = 0;
+
+
+int
+main(int argc, char **argv)
+{
+    int result = STATE_UNKNOWN;
+    int c = 0;
+    int i = 0;
+    int j = 0;
+    char *buf;
+    char *sub;
+    char **command_line;
+    output chld_out;
+    output chld_err;
+
+    setlocale(LC_ALL, "");
+    bindtextdomain(PACKAGE, LOCALEDIR);
+    textdomain(PACKAGE);
+
+    command_line = (char **) process_arguments(argc, argv);
+
+    /* Set signal handling and alarm */
+    if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) {
+        die(STATE_UNKNOWN, _("Cannot catch SIGALRM"));
+    }
+
+    (void) alarm((unsigned) DEFAULT_TIMEOUT);
+
+    /* catch when the command is quoted */
+    if (command_line[1] == NULL) {
+        result = cmd_run(command_line[0], &chld_out, &chld_err, 0);
+    } else {
+        result = cmd_run_array(command_line, &chld_out, &chld_err, 0);
+    }
+
+    if (chld_err.lines > 0) {
+        printf("%s:\n", _("Error output from command"));
+        for (i = 0; i < chld_err.lines; i++) {
+            printf("%s\n", chld_err.line[i]);
+        }
+        exit(STATE_WARNING);
+    }
+
+    /* Return UNKNOWN or worse if no output is returned */
+    if (chld_out.lines == 0) {
+        die(max_state_alt(result, STATE_UNKNOWN), _("No data returned from command\n"));
+    }
+
+    for (i = 0; i < chld_out.lines; i++) {
+
+        /* if we're on the first line, remove the perfdata */
+        if (remove_perfdata && i == 0) {
+
+            int in_quotes = 0;
+
+            for (j = 0; j < (int) strlen(chld_out.line[i]); j++) {
+
+                c = chld_out.line[i][j];
+
+                if (c == '"') {
+                    if (in_quotes) {
+                        in_quotes = 0;
+                    }
+                    else {
+                        in_quotes = 1;
+                    }
+                }
+
+                /* when we reach an unqouted |, stop printing */
+                if (!in_quotes && c == '|')
+                    break;
+
+                printf("%c", c);
+            }
+
+            /* and print a newline if we skipped past it */
+            if (c != '\n') {
+                printf("\n");
+            }
+        }
+
+        /* if we don't want long output, don't print it */
+        else if (remove_long_output && i > 0) {
+            break;
+        }
+
+        /* for everything else, theres mastercard - or printing the full line to the screen */
+        else {
+            printf("%s\n", chld_out.line[i]);
+        }
+    }
+
+    exit(result);
+}
+
+
+/* process command-line arguments */
+static const char **
+process_arguments(int argc, char **argv)
+{
+    int c = 0;
+    int option = 0;
+    static struct option longopts[] = {
+        {"help", no_argument, 0, 'h'},
+        {"version", no_argument, 0, 'V'},
+        {"remove-long-output", no_argument, 0, 'l'},
+        {"dont-remove-perfdata", required_argument, 0, 'd'},
+        {0, 0, 0, 0}
+    };
+
+    while (1) {
+        c = getopt_long(argc, argv, "+hVld", longopts, &option);
+
+        if (c == -1 || c == EOF)
+            break;
+
+        switch (c) {
+
+        /* help */
+        case '?':
+            usage5();
+            break;
+
+        /* help */
+        case 'h':
+            print_help();
+            exit(EXIT_SUCCESS);
+            break;
+
+        /* version */
+        case 'V':
+            print_revision(progname, NP_VERSION);
+            exit(EXIT_SUCCESS);
+
+        /* remove long output */
+        case 'l':
+            remove_long_output = 1;
+            break;
+
+        /* don't remove perfdata */
+        case 'd':
+            remove_perfdata = 0;
+            break;
+        }
+    }
+
+    validate_arguments(&argv[optind]);
+
+    return (const char **) &argv[optind];
+}
+
+
+void
+validate_arguments(char **command_line)
+{
+    if (command_line[0] == NULL)
+        usage4(_("Could not parse arguments"));
+
+    if (   strncmp(command_line[0], "/", 1) != 0 
+        && strncmp(command_line[0], "./", 2) != 0)
+        usage4(_("Require path to command"));
+}
+
+
+void
+print_help(void)
+{
+    print_revision(progname, NP_VERSION);
+
+    printf(COPYRIGHT, copyright, email);
+
+    printf("%s\n", _("Removes perfdata from plugin output."));
+    printf("%s\n", _("Additional switches can be used to remove long output as well."));
+
+    printf("\n\n");
+    print_usage();
+
+    printf(UT_HELP_VRSN);
+
+    printf(" -l, --remove-long-output\n");
+    printf("    %s\n", _("Remove long output from specified plugin's output."));
+    printf(" -d, --dont-remove-perfdata\n");
+    printf("    %s\n", _("Don't remove perfdata from the specified plugin's output.\n"));
+
+    printf("\n");
+
+    printf("%s\n", _("Examples:"));
+    printf("\n");
+    printf("%s\n", "remove_perfdata /usr/local/nagios/libexec/check_ping -H host");
+    printf("    %s\n", _("Run check_ping and remove performance data. (Must use full path to plugin.)"));
+    printf("\n");
+    printf("%s\n", _("Notes:"));
+    printf("    %s\n", _("This plugin is a wrapper to take the output of another plugin and alter it."));
+    printf("    %s\n", _("The full path of the plugin must be provided."));
+    printf("\n");
+
+    printf(UT_SUPPORT);
+}
+
+
+
+void
+print_usage(void)
+{
+    printf("%s\n", _("Usage:"));
+    printf("%s [-hV] [-l] [-d] <definition of wrapped plugin>\n", progname);
+}

+ 23 - 2
plugins/sslutils.c

@@ -35,6 +35,8 @@ static SSL_CTX *c=NULL;
 static SSL *s=NULL;
 static int initialized=0;
 
+int check_hostname = 0;
+
 int np_net_ssl_init(int sd) {
 	return np_net_ssl_init_with_hostname(sd, NULL);
 }
@@ -157,6 +159,16 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
 #endif
 		SSL_set_fd(s, sd);
 		if (SSL_connect(s) == 1) {
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+			if (check_hostname && host_name && *host_name) {
+				X509 *certificate=SSL_get_peer_certificate(s);
+				int rc = X509_check_host(certificate, host_name, 0, 0, NULL);
+				if (rc != 1) {
+					printf("%s\n", _("CRITICAL - Hostname mismatch."));
+					return STATE_CRITICAL;
+				}
+			}
+#endif
 			return OK;
 		} else {
 			printf("%s\n", _("CRITICAL - Cannot make SSL connection."));
@@ -194,6 +206,15 @@ int np_net_ssl_read(void *buf, int num) {
 }
 
 int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
+#  ifdef USE_OPENSSL
+	return np_net_ssl_check_cert_real(s, days_till_exp_warn, days_till_exp_crit);
+#  else /* ifndef USE_OPENSSL */
+	printf ("%s\n", _("WARNING - Plugin does not support checking certificates."));
+	return STATE_WARNING;
+#  endif /* USE_OPENSSL */
+}
+
+int np_net_ssl_check_cert_real(SSL *ssl, int days_till_exp_warn, int days_till_exp_crit){
 #  ifdef USE_OPENSSL
 	X509 *certificate=NULL;
 	X509_NAME *subj=NULL;
@@ -214,7 +235,7 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
 	// Prefix whatever we're about to print with SSL
 	printf("SSL ");
 
-	certificate=SSL_get_peer_certificate(s);
+	certificate=SSL_get_peer_certificate(ssl);
 	if (!certificate) {
 		printf("%s\n",_("CRITICAL - Cannot retrieve server certificate."));
 		return STATE_CRITICAL;
@@ -304,7 +325,7 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
 		else
 			status = STATE_CRITICAL;
 	} else {
-		printf(_("OK - Certificate '%s' will expire on %s. "), cn, timestamp);
+		printf(_("OK - Certificate '%s' will expire in %u days on %s.\n"), cn, days_left, timestamp);
 		status = STATE_OK;
 	}
 	X509_free(certificate);

+ 17 - 1
plugins/t/check_apt.t

@@ -23,7 +23,7 @@ sub make_result_regexp {
 }
 
 if (-x "./check_apt") {
-	plan tests => 28;
+	plan tests => 36;
 } else {
 	plan skip_all => "No check_apt compiled";
 }
@@ -40,10 +40,18 @@ $result = NPTest->testCmd( sprintf($testfile_command, "", "debian2") );
 is( $result->return_code, 1, "Debian apt output, warning" );
 like( $result->output, make_result_regexp(13, 0), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian2") );
+is( $result->return_code, 0, "Debian apt output, no critical" );
+like( $result->output, make_result_regexp(13, 0), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") );
 is( $result->return_code, 2, "Debian apt output, some critical" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian3") );
+is( $result->return_code, 2, "Debian apt output, some critical" );
+like( $result->output, make_result_regexp(19, 4), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-c '^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)'", "debian3") );
 is( $result->return_code, 2, "Debian apt output - should have same result when default security regexp specified via -c" );
 like( $result->output, make_result_regexp(19, 4), "Output correct" );
@@ -52,6 +60,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") );
 is( $result->return_code, 1, "Debian apt output, filter for libc6" );
 like( $result->output, make_result_regexp(3, 0), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") );
+is( $result->return_code, 1, "Debian apt output, filter for libc6, not critical" );
+like( $result->output, make_result_regexp(3, 0), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6 -i xen", "debian3") );
 is( $result->return_code, 2, "Debian apt output, filter for libc6 and xen" );
 like( $result->output, make_result_regexp(9, 4), "Output correct" );
@@ -64,6 +76,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6", "debian3") );
 is( $result->return_code, 2, "Debian apt output, filter out libc6" );
 like( $result->output, make_result_regexp(16, 4), "Output correct" );
 
+$result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -o", "debian3") );
+is( $result->return_code, 2, "Debian apt output, filter out libc6, critical" );
+like( $result->output, make_result_regexp(16, 4), "Output correct" );
+
 $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -e xen", "debian3") );
 is( $result->return_code, 1, "Debian apt output, filter out libc6 and xen" );
 like( $result->output, make_result_regexp(10, 0), "Output correct" );

+ 25 - 16
plugins/utils.c

@@ -204,31 +204,40 @@ int
 parse_timeout_string (char *timeout_str)
 {
 	char *seperated_str;
-        char *timeout_val = "";
+    char *timeout_val = "";
 	char *timeout_sta = NULL;
-        if ( strstr(timeout_str, ":" ) == NULL) {
+
+	if (strstr(timeout_str, ":") == NULL) {
 		timeout_val = timeout_str;
-        } else if ( strncmp(timeout_str, ":", 1 ) == 0) {
+	} 
+	else if (strncmp(timeout_str, ":", 1) == 0) {
 		seperated_str = strtok(timeout_str, ":");
-                if ( seperated_str != NULL ) {
-                	timeout_sta = seperated_str;
+
+		if (seperated_str != NULL) {
+			timeout_sta = seperated_str;
 		}
-        } else {
+	}
+	else {
 		seperated_str = strtok(timeout_str, ":");
-                timeout_val = seperated_str;
-                seperated_str = strtok(NULL, ":");
-                if (seperated_str != NULL) {
-                        timeout_sta = seperated_str;
-                }
-        }
-        if ( timeout_sta != NULL ) {
+		timeout_val = seperated_str;
+		seperated_str = strtok(NULL, ":");
+
+		if (seperated_str != NULL) {
+			timeout_sta = seperated_str;
+		}
+	}
+
+	if (timeout_sta != NULL) {
 		set_timeout_state(timeout_sta);
 	}
-	if (( timeout_val == NULL ) || ( timeout_val[0] == '\0' )) {
+
+	if ((timeout_val == NULL) || (timeout_val[0] == '\0')) {
 		return timeout_interval;
-	} else if (is_intpos(timeout_val)) {
+	} 
+	else if (is_intpos(timeout_val)) {
 		return atoi(timeout_val);
-	} else {
+	}
+	else {
 		usage4 (_("Timeout value must be a positive integer"));
 		exit (STATE_UNKNOWN);
 	}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.