summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorRincewindsHat <12514511+RincewindsHat@users.noreply.github.com>2023-09-18 20:59:46 (GMT)
committerRincewindsHat <12514511+RincewindsHat@users.noreply.github.com>2023-09-18 20:59:46 (GMT)
commit0e70e81133c25274fe2dd2309556b41357dd759b (patch)
tree9a680b36788ee1ad4e7ecc5ccfeb4494db9fdc72 /plugins
parentce355c80cf6054bfa5e1dcf81f9e2183ef963ee1 (diff)
parent2ddc75e69db5a3dd379c896d8420c9af20ec1cee (diff)
downloadmonitoring-plugins-0e70e81133c25274fe2dd2309556b41357dd759b.tar.gz
Merge branch 'master' into mysql_detect_mysqldumprefs/pull/1718/head
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am6
-rw-r--r--plugins/check_apt.c72
-rw-r--r--plugins/check_by_ssh.c32
-rw-r--r--plugins/check_curl.c591
-rw-r--r--plugins/check_dbi.c14
-rw-r--r--plugins/check_disk.c243
-rw-r--r--plugins/check_dns.c2
-rw-r--r--plugins/check_fping.c40
-rw-r--r--plugins/check_game.c2
-rw-r--r--plugins/check_hpjd.c18
-rw-r--r--plugins/check_http.c374
-rw-r--r--plugins/check_ldap.c7
-rw-r--r--plugins/check_load.c124
-rw-r--r--plugins/check_mysql.c7
-rw-r--r--plugins/check_nt.c2
-rw-r--r--plugins/check_ntp.c18
-rw-r--r--plugins/check_ntp_peer.c12
-rw-r--r--plugins/check_ntp_time.c2
-rw-r--r--plugins/check_nwstat.c2
-rw-r--r--plugins/check_pgsql.c79
-rw-r--r--plugins/check_ping.c69
-rw-r--r--plugins/check_procs.c103
-rw-r--r--plugins/check_radius.c8
-rw-r--r--plugins/check_real.c4
-rw-r--r--plugins/check_smtp.c104
-rw-r--r--plugins/check_snmp.c216
-rw-r--r--plugins/check_swap.c93
-rw-r--r--plugins/check_tcp.c2
-rw-r--r--plugins/check_ups.c21
-rw-r--r--plugins/check_users.c37
-rw-r--r--plugins/picohttpparser/picohttpparser.c34
-rw-r--r--plugins/picohttpparser/picohttpparser.h4
-rw-r--r--plugins/popen.c2
-rw-r--r--plugins/runcmd.c4
-rw-r--r--plugins/sslutils.c34
-rw-r--r--plugins/t/check_by_ssh.t18
-rw-r--r--plugins/t/check_curl.t46
-rw-r--r--plugins/t/check_disk.t39
-rw-r--r--plugins/t/check_http.t16
-rw-r--r--plugins/t/check_load.t15
-rw-r--r--plugins/t/check_mysql.t6
-rw-r--r--plugins/t/check_mysql_query.t2
-rw-r--r--plugins/t/check_nagios.t2
-rw-r--r--plugins/t/check_smtp.t40
-rw-r--r--plugins/t/check_snmp.t68
-rw-r--r--plugins/t/negate.t2
-rw-r--r--plugins/tests/certs/.gitignore2
-rw-r--r--plugins/tests/certs/client-cert.pem22
-rw-r--r--plugins/tests/certs/client-key.pem28
-rw-r--r--plugins/tests/certs/clientca-cert.pem25
-rw-r--r--plugins/tests/certs/clientca-key.pem28
-rw-r--r--plugins/tests/certs/clientchain-cert.pem45
-rw-r--r--plugins/tests/certs/clientchain-key.pem28
-rw-r--r--plugins/tests/certs/clientintermediate-cert.pem23
-rw-r--r--plugins/tests/certs/clientintermediate-key.pem28
-rw-r--r--plugins/tests/certs/expired-cert.pem32
-rw-r--r--plugins/tests/certs/expired-key.pem52
-rw-r--r--plugins/tests/certs/ext.cnf2
-rwxr-xr-xplugins/tests/certs/generate-certs.sh63
-rw-r--r--plugins/tests/certs/server-cert.pem44
-rw-r--r--plugins/tests/certs/server-key.pem52
-rwxr-xr-xplugins/tests/check_curl.t31
-rwxr-xr-xplugins/tests/check_http.t341
-rwxr-xr-xplugins/tests/check_procs.t32
-rwxr-xr-xplugins/tests/check_snmp.t41
-rw-r--r--plugins/tests/check_snmp_agent.pl8
-rw-r--r--plugins/tests/var/ps-axwo.debian219
-rw-r--r--plugins/tests/var/ps_axwo.debian84
-rw-r--r--plugins/utils.c30
-rw-r--r--plugins/utils.h2
70 files changed, 2667 insertions, 1231 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 3fde54d..49086b7 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -51,10 +51,10 @@ noinst_LIBRARIES = libnpcommon.a
51libnpcommon_a_SOURCES = utils.c netutils.c sslutils.c runcmd.c \ 51libnpcommon_a_SOURCES = utils.c netutils.c sslutils.c runcmd.c \
52 popen.c utils.h netutils.h popen.h common.h runcmd.c runcmd.h 52 popen.c utils.h netutils.h popen.h common.h runcmd.c runcmd.h
53 53
54BASEOBJS = libnpcommon.a ../lib/libmonitoringplug.a ../gl/libgnu.a 54BASEOBJS = libnpcommon.a ../lib/libmonitoringplug.a ../gl/libgnu.a $(LIB_CRYPTO)
55NETOBJS = $(BASEOBJS) $(EXTRA_NETOBLS) 55NETOBJS = $(BASEOBJS) $(EXTRA_NETOBLS)
56NETLIBS = $(NETOBJS) $(SOCKETLIBS) 56NETLIBS = $(NETOBJS) $(SOCKETLIBS)
57SSLOBJS = $(BASEOBJS) $(NETLIBS) $(SSLLIBS) 57SSLOBJS = $(BASEOBJS) $(NETLIBS) $(SSLLIBS) $(LIB_CRYPTO)
58 58
59TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir) 59TESTS_ENVIRONMENT = perl -I $(top_builddir) -I $(top_srcdir)
60 60
@@ -112,7 +112,7 @@ check_tcp_LDADD = $(SSLOBJS)
112check_time_LDADD = $(NETLIBS) 112check_time_LDADD = $(NETLIBS)
113check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS) 113check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS)
114check_ups_LDADD = $(NETLIBS) 114check_ups_LDADD = $(NETLIBS)
115check_users_LDADD = $(BASEOBJS) $(WTSAPI32LIBS) 115check_users_LDADD = $(BASEOBJS) $(WTSAPI32LIBS) $(SYSTEMDLIBS)
116check_by_ssh_LDADD = $(NETLIBS) 116check_by_ssh_LDADD = $(NETLIBS)
117check_ide_smart_LDADD = $(BASEOBJS) 117check_ide_smart_LDADD = $(BASEOBJS)
118negate_LDADD = $(BASEOBJS) 118negate_LDADD = $(BASEOBJS)
diff --git a/plugins/check_apt.c b/plugins/check_apt.c
index d7be575..fa982ae 100644
--- a/plugins/check_apt.c
+++ b/plugins/check_apt.c
@@ -1,32 +1,32 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_apt plugin 3* Monitoring check_apt plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2006-2008 Monitoring Plugins Development Team 6* Copyright (c) 2006-2008 Monitoring Plugins Development Team
7* 7*
8* Original author: Sean Finney 8* Original author: Sean Finney
9* 9*
10* Description: 10* Description:
11* 11*
12* This file contains the check_apt plugin 12* This file contains the check_apt plugin
13* 13*
14* Check for available updates in apt package management systems 14* Check for available updates in apt package management systems
15* 15*
16* 16*
17* This program is free software: you can redistribute it and/or modify 17* This program is free software: you can redistribute it and/or modify
18* it under the terms of the GNU General Public License as published by 18* it under the terms of the GNU General Public License as published by
19* the Free Software Foundation, either version 3 of the License, or 19* the Free Software Foundation, either version 3 of the License, or
20* (at your option) any later version. 20* (at your option) any later version.
21* 21*
22* This program is distributed in the hope that it will be useful, 22* This program is distributed in the hope that it will be useful,
23* but WITHOUT ANY WARRANTY; without even the implied warranty of 23* but WITHOUT ANY WARRANTY; without even the implied warranty of
24* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25* GNU General Public License for more details. 25* GNU General Public License for more details.
26* 26*
27* You should have received a copy of the GNU General Public License 27* You should have received a copy of the GNU General Public License
28* along with this program. If not, see <http://www.gnu.org/licenses/>. 28* along with this program. If not, see <http://www.gnu.org/licenses/>.
29* 29*
30*****************************************************************************/ 30*****************************************************************************/
31 31
32const char *progname = "check_apt"; 32const char *progname = "check_apt";
@@ -76,9 +76,9 @@ int cmpstringp(const void *p1, const void *p2);
76 76
77/* configuration variables */ 77/* configuration variables */
78static int verbose = 0; /* -v */ 78static int verbose = 0; /* -v */
79static int list = 0; /* list packages available for upgrade */ 79static bool list = false; /* list packages available for upgrade */
80static int do_update = 0; /* whether to call apt-get update */ 80static bool do_update = false; /* whether to call apt-get update */
81static int only_critical = 0; /* whether to warn about non-critical updates */ 81static bool only_critical = false; /* whether to warn about non-critical updates */
82static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */ 82static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */
83static char *upgrade_opts = NULL; /* options to override defaults for upgrade */ 83static char *upgrade_opts = NULL; /* options to override defaults for upgrade */
84static char *update_opts = NULL; /* options to override defaults for update */ 84static char *update_opts = NULL; /* options to override defaults for update */
@@ -119,7 +119,7 @@ int main (int argc, char **argv) {
119 119
120 if(sec_count > 0){ 120 if(sec_count > 0){
121 result = max_state(result, STATE_CRITICAL); 121 result = max_state(result, STATE_CRITICAL);
122 } else if(packages_available >= packages_warning && only_critical == 0){ 122 } else if(packages_available >= packages_warning && only_critical == false){
123 result = max_state(result, STATE_WARNING); 123 result = max_state(result, STATE_WARNING);
124 } else if(result > STATE_UNKNOWN){ 124 } else if(result > STATE_UNKNOWN){
125 result = STATE_UNKNOWN; 125 result = STATE_UNKNOWN;
@@ -144,7 +144,7 @@ int main (int argc, char **argv) {
144 144
145 for(i = 0; i < sec_count; i++) 145 for(i = 0; i < sec_count; i++)
146 printf("%s (security)\n", secpackages_list[i]); 146 printf("%s (security)\n", secpackages_list[i]);
147 if (only_critical == 0) { 147 if (only_critical == false) {
148 for(i = 0; i < packages_available - sec_count; i++) 148 for(i = 0; i < packages_available - sec_count; i++)
149 printf("%s\n", packages_list[i]); 149 printf("%s\n", packages_list[i]);
150 } 150 }
@@ -166,7 +166,7 @@ int process_arguments (int argc, char **argv) {
166 {"upgrade", optional_argument, 0, 'U'}, 166 {"upgrade", optional_argument, 0, 'U'},
167 {"no-upgrade", no_argument, 0, 'n'}, 167 {"no-upgrade", no_argument, 0, 'n'},
168 {"dist-upgrade", optional_argument, 0, 'd'}, 168 {"dist-upgrade", optional_argument, 0, 'd'},
169 {"list", no_argument, 0, 'l'}, 169 {"list", no_argument, false, 'l'},
170 {"include", required_argument, 0, 'i'}, 170 {"include", required_argument, 0, 'i'},
171 {"exclude", required_argument, 0, 'e'}, 171 {"exclude", required_argument, 0, 'e'},
172 {"critical", required_argument, 0, 'c'}, 172 {"critical", required_argument, 0, 'c'},
@@ -212,14 +212,14 @@ int process_arguments (int argc, char **argv) {
212 upgrade=NO_UPGRADE; 212 upgrade=NO_UPGRADE;
213 break; 213 break;
214 case 'u': 214 case 'u':
215 do_update=1; 215 do_update=true;
216 if(optarg!=NULL){ 216 if(optarg!=NULL){
217 update_opts=strdup(optarg); 217 update_opts=strdup(optarg);
218 if(update_opts==NULL) die(STATE_UNKNOWN, "strdup failed"); 218 if(update_opts==NULL) die(STATE_UNKNOWN, "strdup failed");
219 } 219 }
220 break; 220 break;
221 case 'l': 221 case 'l':
222 list=1; 222 list=true;
223 break; 223 break;
224 case 'i': 224 case 'i':
225 do_include=add_to_regexp(do_include, optarg); 225 do_include=add_to_regexp(do_include, optarg);
@@ -231,7 +231,7 @@ int process_arguments (int argc, char **argv) {
231 do_critical=add_to_regexp(do_critical, optarg); 231 do_critical=add_to_regexp(do_critical, optarg);
232 break; 232 break;
233 case 'o': 233 case 'o':
234 only_critical=1; 234 only_critical=true;
235 break; 235 break;
236 case INPUT_FILE_OPT: 236 case INPUT_FILE_OPT:
237 input_filename = optarg; 237 input_filename = optarg;
@@ -269,7 +269,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkg
269 die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); 269 die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf);
270 } 270 }
271 } 271 }
272 272
273 if(do_exclude!=NULL){ 273 if(do_exclude!=NULL){
274 regres=regcomp(&ereg, do_exclude, REG_EXTENDED); 274 regres=regcomp(&ereg, do_exclude, REG_EXTENDED);
275 if(regres!=0) { 275 if(regres!=0) {
@@ -278,7 +278,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkg
278 progname, rerrbuf); 278 progname, rerrbuf);
279 } 279 }
280 } 280 }
281 281
282 const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; 282 const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE;
283 regres=regcomp(&sreg, crit_ptr, REG_EXTENDED); 283 regres=regcomp(&sreg, crit_ptr, REG_EXTENDED);
284 if(regres!=0) { 284 if(regres!=0) {
@@ -295,7 +295,7 @@ int run_upgrade(int *pkgcount, int *secpkgcount, char ***pkglist, char ***secpkg
295 /* run the upgrade */ 295 /* run the upgrade */
296 result = np_runcmd(cmdline, &chld_out, &chld_err, 0); 296 result = np_runcmd(cmdline, &chld_out, &chld_err, 0);
297 } 297 }
298 298
299 /* apt-get upgrade only changes exit status if there is an 299 /* apt-get upgrade only changes exit status if there is an
300 * internal error when run in dry-run mode. therefore we will 300 * internal error when run in dry-run mode. therefore we will
301 * treat such an error as UNKNOWN */ 301 * treat such an error as UNKNOWN */
@@ -371,7 +371,7 @@ int run_update(void){
371 struct output chld_out, chld_err; 371 struct output chld_out, chld_err;
372 char *cmdline; 372 char *cmdline;
373 373
374 /* run the upgrade */ 374 /* run the update */
375 cmdline = construct_cmdline(NO_UPGRADE, update_opts); 375 cmdline = construct_cmdline(NO_UPGRADE, update_opts);
376 result = np_runcmd(cmdline, &chld_out, &chld_err, 0); 376 result = np_runcmd(cmdline, &chld_out, &chld_err, 0);
377 /* apt-get update changes exit status if it can't fetch packages. 377 /* apt-get update changes exit status if it can't fetch packages.
@@ -501,16 +501,6 @@ print_help (void)
501 501
502 printf(UT_PLUG_TIMEOUT, timeout_interval); 502 printf(UT_PLUG_TIMEOUT, timeout_interval);
503 503
504 printf (" %s\n", "-U, --upgrade=OPTS");
505 printf (" %s\n", _("[Default] Perform an upgrade. If an optional OPTS argument is provided,"));
506 printf (" %s\n", _("apt-get will be run with these command line options instead of the"));
507 printf (" %s", _("default "));
508 printf ("(%s).\n", UPGRADE_DEFAULT_OPTS);
509 printf (" %s\n", _("Note that you may be required to have root privileges if you do not use"));
510 printf (" %s\n", _("the default options."));
511 printf (" %s\n", "-d, --dist-upgrade=OPTS");
512 printf (" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS"));
513 printf (" %s\n", _("can be provided to override the default options."));
514 printf (" %s\n", "-n, --no-upgrade"); 504 printf (" %s\n", "-n, --no-upgrade");
515 printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least).")); 505 printf (" %s\n", _("Do not run the upgrade. Probably not useful (without -u at least)."));
516 printf (" %s\n", "-l, --list"); 506 printf (" %s\n", "-l, --list");
@@ -530,7 +520,7 @@ print_help (void)
530 printf (" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified")); 520 printf (" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified"));
531 printf (" %s\n", _("multiple times like above. Default is a regexp matching security")); 521 printf (" %s\n", _("multiple times like above. Default is a regexp matching security"));
532 printf (" %s\n", _("upgrades for Debian and Ubuntu:")); 522 printf (" %s\n", _("upgrades for Debian and Ubuntu:"));
533 printf (" \t\%s\n", SECURITY_RE); 523 printf (" \t%s\n", SECURITY_RE);
534 printf (" %s\n", _("Note that the package must first match the include list before its")); 524 printf (" %s\n", _("Note that the package must first match the include list before its"));
535 printf (" %s\n", _("information is compared against the critical list.")); 525 printf (" %s\n", _("information is compared against the critical list."));
536 printf (" %s\n", "-o, --only-critical"); 526 printf (" %s\n", "-o, --only-critical");
@@ -538,7 +528,7 @@ print_help (void)
538 printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause")); 528 printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause"));
539 printf (" %s\n", _("the plugin to return WARNING status.")); 529 printf (" %s\n", _("the plugin to return WARNING status."));
540 printf (" %s\n", "-w, --packages-warning"); 530 printf (" %s\n", "-w, --packages-warning");
541 printf (" %s\n", _("Minumum number of packages available for upgrade to return WARNING status.")); 531 printf (" %s\n", _("Minimum number of packages available for upgrade to return WARNING status."));
542 printf (" %s\n\n", _("Default is 1 package.")); 532 printf (" %s\n\n", _("Default is 1 package."));
543 533
544 printf ("%s\n\n", _("The following options require root privileges and should be used with care:")); 534 printf ("%s\n\n", _("The following options require root privileges and should be used with care:"));
@@ -547,6 +537,16 @@ print_help (void)
547 printf (" %s\n", _("the default options. Note: you may also need to adjust the global")); 537 printf (" %s\n", _("the default options. Note: you may also need to adjust the global"));
548 printf (" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get")); 538 printf (" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get"));
549 printf (" %s\n", _("upgrade is expected to take longer than the default timeout.")); 539 printf (" %s\n", _("upgrade is expected to take longer than the default timeout."));
540 printf (" %s\n", "-U, --upgrade=OPTS");
541 printf (" %s\n", _("Perform an upgrade. If an optional OPTS argument is provided,"));
542 printf (" %s\n", _("apt-get will be run with these command line options instead of the"));
543 printf (" %s", _("default "));
544 printf ("(%s).\n", UPGRADE_DEFAULT_OPTS);
545 printf (" %s\n", _("Note that you may be required to have root privileges if you do not use"));
546 printf (" %s\n", _("the default options, which will only run a simulation and NOT perform the upgrade"));
547 printf (" %s\n", "-d, --dist-upgrade=OPTS");
548 printf (" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS"));
549 printf (" %s\n", _("can be provided to override the default options."));
550 550
551 printf(UT_SUPPORT); 551 printf(UT_SUPPORT);
552} 552}
diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c
index 485bf3b..1ad547e 100644
--- a/plugins/check_by_ssh.c
+++ b/plugins/check_by_ssh.c
@@ -49,6 +49,8 @@ unsigned int commands = 0;
49unsigned int services = 0; 49unsigned int services = 0;
50int skip_stdout = 0; 50int skip_stdout = 0;
51int skip_stderr = 0; 51int skip_stderr = 0;
52int warn_on_stderr = 0;
53bool unknown_timeout = FALSE;
52char *remotecmd = NULL; 54char *remotecmd = NULL;
53char **commargv = NULL; 55char **commargv = NULL;
54int commargc = 0; 56int commargc = 0;
@@ -100,6 +102,13 @@ main (int argc, char **argv)
100 102
101 result = cmd_run_array (commargv, &chld_out, &chld_err, 0); 103 result = cmd_run_array (commargv, &chld_out, &chld_err, 0);
102 104
105 /* SSH returns 255 if connection attempt fails; include the first line of error output */
106 if (result == 255 && unknown_timeout) {
107 printf (_("SSH connection failed: %s\n"),
108 chld_err.lines > 0 ? chld_err.line[0] : "(no error output)");
109 return STATE_UNKNOWN;
110 }
111
103 if (verbose) { 112 if (verbose) {
104 for(i = 0; i < chld_out.lines; i++) 113 for(i = 0; i < chld_out.lines; i++)
105 printf("stdout: %s\n", chld_out.line[i]); 114 printf("stdout: %s\n", chld_out.line[i]);
@@ -116,7 +125,10 @@ main (int argc, char **argv)
116 if(chld_err.lines > skip_stderr) { 125 if(chld_err.lines > skip_stderr) {
117 printf (_("Remote command execution failed: %s\n"), 126 printf (_("Remote command execution failed: %s\n"),
118 chld_err.line[skip_stderr]); 127 chld_err.line[skip_stderr]);
119 return max_state_alt(result, STATE_UNKNOWN); 128 if ( warn_on_stderr )
129 return max_state_alt(result, STATE_WARNING);
130 else
131 return max_state_alt(result, STATE_UNKNOWN);
120 } 132 }
121 133
122 /* this is simple if we're not supposed to be passive. 134 /* this is simple if we're not supposed to be passive.
@@ -176,6 +188,7 @@ process_arguments (int argc, char **argv)
176 {"verbose", no_argument, 0, 'v'}, 188 {"verbose", no_argument, 0, 'v'},
177 {"fork", no_argument, 0, 'f'}, 189 {"fork", no_argument, 0, 'f'},
178 {"timeout", required_argument, 0, 't'}, 190 {"timeout", required_argument, 0, 't'},
191 {"unknown-timeout", no_argument, 0, 'U'},
179 {"host", required_argument, 0, 'H'}, /* backward compatibility */ 192 {"host", required_argument, 0, 'H'}, /* backward compatibility */
180 {"hostname", required_argument, 0, 'H'}, 193 {"hostname", required_argument, 0, 'H'},
181 {"port", required_argument,0,'p'}, 194 {"port", required_argument,0,'p'},
@@ -189,6 +202,7 @@ process_arguments (int argc, char **argv)
189 {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */ 202 {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */
190 {"skip-stdout", optional_argument, 0, 'S'}, 203 {"skip-stdout", optional_argument, 0, 'S'},
191 {"skip-stderr", optional_argument, 0, 'E'}, 204 {"skip-stderr", optional_argument, 0, 'E'},
205 {"warn-on-stderr", no_argument, 0, 'W'},
192 {"proto1", no_argument, 0, '1'}, 206 {"proto1", no_argument, 0, '1'},
193 {"proto2", no_argument, 0, '2'}, 207 {"proto2", no_argument, 0, '2'},
194 {"use-ipv4", no_argument, 0, '4'}, 208 {"use-ipv4", no_argument, 0, '4'},
@@ -207,7 +221,7 @@ process_arguments (int argc, char **argv)
207 strcpy (argv[c], "-t"); 221 strcpy (argv[c], "-t");
208 222
209 while (1) { 223 while (1) {
210 c = getopt_long (argc, argv, "Vvh1246fqt:H:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, 224 c = getopt_long (argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts,
211 &option); 225 &option);
212 226
213 if (c == -1 || c == EOF) 227 if (c == -1 || c == EOF)
@@ -229,6 +243,9 @@ process_arguments (int argc, char **argv)
229 else 243 else
230 timeout_interval = atoi (optarg); 244 timeout_interval = atoi (optarg);
231 break; 245 break;
246 case 'U':
247 unknown_timeout = TRUE;
248 break;
232 case 'H': /* host */ 249 case 'H': /* host */
233 hostname = optarg; 250 hostname = optarg;
234 break; 251 break;
@@ -307,6 +324,9 @@ process_arguments (int argc, char **argv)
307 else 324 else
308 skip_stderr = atoi (optarg); 325 skip_stderr = atoi (optarg);
309 break; 326 break;
327 case 'W': /* exit with warning if there is an output on stderr */
328 warn_on_stderr = 1;
329 break;
310 case 'o': /* Extra options for the ssh command */ 330 case 'o': /* Extra options for the ssh command */
311 comm_append("-o"); 331 comm_append("-o");
312 comm_append(optarg); 332 comm_append(optarg);
@@ -413,6 +433,8 @@ print_help (void)
413 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]")); 433 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]"));
414 printf (" %s\n", "-E, --skip-stderr[=n]"); 434 printf (" %s\n", "-E, --skip-stderr[=n]");
415 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]")); 435 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]"));
436 printf (" %s\n", "-W, --warn-on-stderr]");
437 printf (" %s\n", _("Exit with an warning, if there is an output on STDERR"));
416 printf (" %s\n", "-f"); 438 printf (" %s\n", "-f");
417 printf (" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed")); 439 printf (" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed"));
418 printf (" %s\n","-C, --command='COMMAND STRING'"); 440 printf (" %s\n","-C, --command='COMMAND STRING'");
@@ -435,6 +457,8 @@ print_help (void)
435 printf (" %s\n", _("Tell ssh to suppress warning and diagnostic messages [optional]")); 457 printf (" %s\n", _("Tell ssh to suppress warning and diagnostic messages [optional]"));
436 printf (UT_WARN_CRIT); 458 printf (UT_WARN_CRIT);
437 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 459 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
460 printf (" %s\n","-U, --unknown-timeout");
461 printf (" %s\n", _("Make connection problems return UNKNOWN instead of CRITICAL"));
438 printf (UT_VERBOSE); 462 printf (UT_VERBOSE);
439 printf("\n"); 463 printf("\n");
440 printf (" %s\n", _("The most common mode of use is to refer to a local identity file with")); 464 printf (" %s\n", _("The most common mode of use is to refer to a local identity file with"));
@@ -464,8 +488,8 @@ void
464print_usage (void) 488print_usage (void)
465{ 489{
466 printf ("%s\n", _("Usage:")); 490 printf ("%s\n", _("Usage:"));
467 printf (" %s -H <host> -C <command> [-fqv] [-1|-2] [-4|-6]\n" 491 printf (" %s -H <host> -C <command> [-fqvU] [-1|-2] [-4|-6]\n"
468 " [-S [lines]] [-E [lines]] [-t timeout] [-i identity]\n" 492 " [-S [lines]] [-E [lines]] [-W] [-t timeout] [-i identity]\n"
469 " [-l user] [-n name] [-s servicelist] [-O outputfile]\n" 493 " [-l user] [-n name] [-s servicelist] [-O outputfile]\n"
470 " [-p port] [-o ssh-option] [-F configfile]\n", 494 " [-p port] [-o ssh-option] [-F configfile]\n",
471 progname); 495 progname);
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 5990b95..d0871c4 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -37,6 +37,7 @@ const char *progname = "check_curl";
37const char *copyright = "2006-2019"; 37const char *copyright = "2006-2019";
38const char *email = "devel@monitoring-plugins.org"; 38const char *email = "devel@monitoring-plugins.org";
39 39
40#include <stdbool.h>
40#include <ctype.h> 41#include <ctype.h>
41 42
42#include "common.h" 43#include "common.h"
@@ -54,6 +55,7 @@ const char *email = "devel@monitoring-plugins.org";
54#include "uriparser/Uri.h" 55#include "uriparser/Uri.h"
55 56
56#include <arpa/inet.h> 57#include <arpa/inet.h>
58#include <netinet/in.h>
57 59
58#if defined(HAVE_SSL) && defined(USE_OPENSSL) 60#if defined(HAVE_SSL) && defined(USE_OPENSSL)
59#include <openssl/opensslv.h> 61#include <openssl/opensslv.h>
@@ -66,13 +68,13 @@ const char *email = "devel@monitoring-plugins.org";
66#define DEFAULT_BUFFER_SIZE 2048 68#define DEFAULT_BUFFER_SIZE 2048
67#define DEFAULT_SERVER_URL "/" 69#define DEFAULT_SERVER_URL "/"
68#define HTTP_EXPECT "HTTP/" 70#define HTTP_EXPECT "HTTP/"
69#define DEFAULT_MAX_REDIRS 15
70#define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN 71#define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN
71enum { 72enum {
72 MAX_IPV4_HOSTLENGTH = 255, 73 MAX_IPV4_HOSTLENGTH = 255,
73 HTTP_PORT = 80, 74 HTTP_PORT = 80,
74 HTTPS_PORT = 443, 75 HTTPS_PORT = 443,
75 MAX_PORT = 65535 76 MAX_PORT = 65535,
77 DEFAULT_MAX_REDIRS = 15
76}; 78};
77 79
78enum { 80enum {
@@ -131,14 +133,14 @@ regmatch_t pmatch[REGS];
131char regexp[MAX_RE_SIZE]; 133char regexp[MAX_RE_SIZE];
132int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; 134int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE;
133int errcode; 135int errcode;
134int invert_regex = 0; 136bool invert_regex = false;
135 137
136char *server_address = NULL; 138char *server_address = NULL;
137char *host_name = NULL; 139char *host_name = NULL;
138char *server_url = 0; 140char *server_url = 0;
139char server_ip[DEFAULT_BUFFER_SIZE]; 141char server_ip[DEFAULT_BUFFER_SIZE];
140struct curl_slist *server_ips = NULL; 142struct curl_slist *server_ips = NULL;
141int specify_port = FALSE; 143bool specify_port = false;
142unsigned short server_port = HTTP_PORT; 144unsigned short server_port = HTTP_PORT;
143unsigned short virtual_port = 0; 145unsigned short virtual_port = 0;
144int host_name_length; 146int host_name_length;
@@ -150,8 +152,8 @@ int days_till_exp_warn, days_till_exp_crit;
150thresholds *thlds; 152thresholds *thlds;
151char user_agent[DEFAULT_BUFFER_SIZE]; 153char user_agent[DEFAULT_BUFFER_SIZE];
152int verbose = 0; 154int verbose = 0;
153int show_extended_perfdata = FALSE; 155bool show_extended_perfdata = false;
154int show_body = FALSE; 156bool show_body = false;
155int min_page_len = 0; 157int min_page_len = 0;
156int max_page_len = 0; 158int max_page_len = 0;
157int redir_depth = 0; 159int redir_depth = 0;
@@ -160,10 +162,16 @@ char *http_method = NULL;
160char *http_post_data = NULL; 162char *http_post_data = NULL;
161char *http_content_type = NULL; 163char *http_content_type = NULL;
162CURL *curl; 164CURL *curl;
165bool curl_global_initialized = false;
166bool curl_easy_initialized = false;
163struct curl_slist *header_list = NULL; 167struct curl_slist *header_list = NULL;
168bool body_buf_initialized = false;
164curlhelp_write_curlbuf body_buf; 169curlhelp_write_curlbuf body_buf;
170bool header_buf_initialized = false;
165curlhelp_write_curlbuf header_buf; 171curlhelp_write_curlbuf header_buf;
172bool status_line_initialized = false;
166curlhelp_statusline status_line; 173curlhelp_statusline status_line;
174bool put_buf_initialized = false;
167curlhelp_read_curlbuf put_buf; 175curlhelp_read_curlbuf put_buf;
168char http_header[DEFAULT_BUFFER_SIZE]; 176char http_header[DEFAULT_BUFFER_SIZE];
169long code; 177long code;
@@ -173,7 +181,7 @@ double time_connect;
173double time_appconnect; 181double time_appconnect;
174double time_headers; 182double time_headers;
175double time_firstbyte; 183double time_firstbyte;
176char errbuf[CURL_ERROR_SIZE+1]; 184char errbuf[MAX_INPUT_BUFFER];
177CURLcode res; 185CURLcode res;
178char url[DEFAULT_BUFFER_SIZE]; 186char url[DEFAULT_BUFFER_SIZE];
179char msg[DEFAULT_BUFFER_SIZE]; 187char msg[DEFAULT_BUFFER_SIZE];
@@ -186,13 +194,14 @@ char user_auth[MAX_INPUT_BUFFER] = "";
186char proxy_auth[MAX_INPUT_BUFFER] = ""; 194char proxy_auth[MAX_INPUT_BUFFER] = "";
187char **http_opt_headers; 195char **http_opt_headers;
188int http_opt_headers_count = 0; 196int http_opt_headers_count = 0;
189int display_html = FALSE; 197bool display_html = false;
190int onredirect = STATE_OK; 198int onredirect = STATE_OK;
191int followmethod = FOLLOW_HTTP_CURL; 199int followmethod = FOLLOW_HTTP_CURL;
192int followsticky = STICKY_NONE; 200int followsticky = STICKY_NONE;
193int use_ssl = FALSE; 201bool use_ssl = false;
194int use_sni = TRUE; 202bool use_sni = true;
195int check_cert = FALSE; 203bool check_cert = false;
204bool continue_after_check_cert = false;
196typedef union { 205typedef union {
197 struct curl_slist* to_info; 206 struct curl_slist* to_info;
198 struct curl_certinfo* to_certinfo; 207 struct curl_certinfo* to_certinfo;
@@ -202,19 +211,20 @@ int ssl_version = CURL_SSLVERSION_DEFAULT;
202char *client_cert = NULL; 211char *client_cert = NULL;
203char *client_privkey = NULL; 212char *client_privkey = NULL;
204char *ca_cert = NULL; 213char *ca_cert = NULL;
205int verify_peer_and_host = FALSE; 214bool verify_peer_and_host = false;
206int is_openssl_callback = FALSE; 215bool is_openssl_callback = false;
207#if defined(HAVE_SSL) && defined(USE_OPENSSL) 216#if defined(HAVE_SSL) && defined(USE_OPENSSL)
208X509 *cert = NULL; 217X509 *cert = NULL;
209#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ 218#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */
210int no_body = FALSE; 219bool no_body = false;
211int maximum_age = -1; 220int maximum_age = -1;
212int address_family = AF_UNSPEC; 221int address_family = AF_UNSPEC;
213curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; 222curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN;
214int curl_http_version = CURL_HTTP_VERSION_NONE; 223int curl_http_version = CURL_HTTP_VERSION_NONE;
215int automatic_decompression = FALSE; 224bool automatic_decompression = false;
225char *cookie_jar_file = NULL;
216 226
217int process_arguments (int, char**); 227bool process_arguments (int, char**);
218void handle_curl_option_return_code (CURLcode res, const char* option); 228void handle_curl_option_return_code (CURLcode res, const char* option);
219int check_http (void); 229int check_http (void);
220void redir (curlhelp_write_curlbuf*); 230void redir (curlhelp_write_curlbuf*);
@@ -234,7 +244,7 @@ void curlhelp_freewritebuffer (curlhelp_write_curlbuf*);
234int curlhelp_initreadbuffer (curlhelp_read_curlbuf *, const char *, size_t); 244int curlhelp_initreadbuffer (curlhelp_read_curlbuf *, const char *, size_t);
235int curlhelp_buffer_read_callback (void *, size_t , size_t , void *); 245int curlhelp_buffer_read_callback (void *, size_t , size_t , void *);
236void curlhelp_freereadbuffer (curlhelp_read_curlbuf *); 246void curlhelp_freereadbuffer (curlhelp_read_curlbuf *);
237curlhelp_ssl_library curlhelp_get_ssl_library (CURL*); 247curlhelp_ssl_library curlhelp_get_ssl_library ();
238const char* curlhelp_get_ssl_library_string (curlhelp_ssl_library); 248const char* curlhelp_get_ssl_library_string (curlhelp_ssl_library);
239int net_noopenssl_check_certificate (cert_ptr_union*, int, int); 249int net_noopenssl_check_certificate (cert_ptr_union*, int, int);
240 250
@@ -268,10 +278,10 @@ main (int argc, char **argv)
268 progname, NP_VERSION, VERSION, curl_version()); 278 progname, NP_VERSION, VERSION, curl_version());
269 279
270 /* parse arguments */ 280 /* parse arguments */
271 if (process_arguments (argc, argv) == ERROR) 281 if (process_arguments (argc, argv) == false)
272 usage4 (_("Could not parse arguments")); 282 usage4 (_("Could not parse arguments"));
273 283
274 if (display_html == TRUE) 284 if (display_html)
275 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", 285 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">",
276 use_ssl ? "https" : "http", 286 use_ssl ? "https" : "http",
277 host_name ? host_name : server_address, 287 host_name ? host_name : server_address,
@@ -287,6 +297,7 @@ main (int argc, char **argv)
287 297
288int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) 298int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
289{ 299{
300 (void) preverify_ok;
290 /* TODO: we get all certificates of the chain, so which ones 301 /* TODO: we get all certificates of the chain, so which ones
291 * should we test? 302 * should we test?
292 * TODO: is the last certificate always the server certificate? 303 * TODO: is the last certificate always the server certificate?
@@ -311,6 +322,8 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
311 322
312CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) 323CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm)
313{ 324{
325 (void) curl; // ignore unused parameter
326 (void) parm; // ignore unused parameter
314 SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback); 327 SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback);
315 328
316 return CURLE_OK; 329 return CURLE_OK;
@@ -365,8 +378,12 @@ void
365handle_curl_option_return_code (CURLcode res, const char* option) 378handle_curl_option_return_code (CURLcode res, const char* option)
366{ 379{
367 if (res != CURLE_OK) { 380 if (res != CURLE_OK) {
368 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Error while setting cURL option '%s': cURL returned %d - %s"), 381 snprintf (msg,
369 option, res, curl_easy_strerror(res)); 382 DEFAULT_BUFFER_SIZE,
383 _("Error while setting cURL option '%s': cURL returned %d - %s"),
384 option,
385 res,
386 curl_easy_strerror(res));
370 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 387 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
371 } 388 }
372} 389}
@@ -375,8 +392,11 @@ int
375lookup_host (const char *host, char *buf, size_t buflen) 392lookup_host (const char *host, char *buf, size_t buflen)
376{ 393{
377 struct addrinfo hints, *res, *result; 394 struct addrinfo hints, *res, *result;
395 char addrstr[100];
396 size_t addrstr_len;
378 int errcode; 397 int errcode;
379 void *ptr; 398 void *ptr;
399 size_t buflen_remaining = buflen - 1;
380 400
381 memset (&hints, 0, sizeof (hints)); 401 memset (&hints, 0, sizeof (hints));
382 hints.ai_family = address_family; 402 hints.ai_family = address_family;
@@ -386,31 +406,62 @@ lookup_host (const char *host, char *buf, size_t buflen)
386 errcode = getaddrinfo (host, NULL, &hints, &result); 406 errcode = getaddrinfo (host, NULL, &hints, &result);
387 if (errcode != 0) 407 if (errcode != 0)
388 return errcode; 408 return errcode;
389 409
410 strcpy(buf, "");
390 res = result; 411 res = result;
391 412
392 while (res) { 413 while (res) {
393 inet_ntop (res->ai_family, res->ai_addr->sa_data, buf, buflen); 414 switch (res->ai_family) {
394 switch (res->ai_family) { 415 case AF_INET:
395 case AF_INET: 416 ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
396 ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; 417 break;
397 break; 418 case AF_INET6:
398 case AF_INET6: 419 ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
399 ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; 420 break;
400 break;
401 } 421 }
402 inet_ntop (res->ai_family, ptr, buf, buflen); 422
403 if (verbose >= 1) 423 inet_ntop (res->ai_family, ptr, addrstr, 100);
424 if (verbose >= 1) {
404 printf ("* getaddrinfo IPv%d address: %s\n", 425 printf ("* getaddrinfo IPv%d address: %s\n",
405 res->ai_family == PF_INET6 ? 6 : 4, buf); 426 res->ai_family == PF_INET6 ? 6 : 4, addrstr);
427 }
428
429 // Append all IPs to buf as a comma-separated string
430 addrstr_len = strlen(addrstr);
431 if (buflen_remaining > addrstr_len + 1) {
432 if (buf[0] != '\0') {
433 strncat(buf, ",", buflen_remaining);
434 buflen_remaining -= 1;
435 }
436 strncat(buf, addrstr, buflen_remaining);
437 buflen_remaining -= addrstr_len;
438 }
439
406 res = res->ai_next; 440 res = res->ai_next;
407 } 441 }
408 442
409 freeaddrinfo(result); 443 freeaddrinfo(result);
410 444
411 return 0; 445 return 0;
412} 446}
413 447
448static void
449cleanup (void)
450{
451 if (status_line_initialized) curlhelp_free_statusline(&status_line);
452 status_line_initialized = false;
453 if (curl_easy_initialized) curl_easy_cleanup (curl);
454 curl_easy_initialized = false;
455 if (curl_global_initialized) curl_global_cleanup ();
456 curl_global_initialized = false;
457 if (body_buf_initialized) curlhelp_freewritebuffer (&body_buf);
458 body_buf_initialized = false;
459 if (header_buf_initialized) curlhelp_freewritebuffer (&header_buf);
460 header_buf_initialized = false;
461 if (put_buf_initialized) curlhelp_freereadbuffer (&put_buf);
462 put_buf_initialized = false;
463}
464
414int 465int
415check_http (void) 466check_http (void)
416{ 467{
@@ -419,18 +470,24 @@ check_http (void)
419 int i; 470 int i;
420 char *force_host_header = NULL; 471 char *force_host_header = NULL;
421 struct curl_slist *host = NULL; 472 struct curl_slist *host = NULL;
422 char addrstr[100]; 473 char addrstr[DEFAULT_BUFFER_SIZE/2];
423 char dnscache[DEFAULT_BUFFER_SIZE]; 474 char dnscache[DEFAULT_BUFFER_SIZE];
424 475
425 /* initialize curl */ 476 /* initialize curl */
426 if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK) 477 if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK)
427 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); 478 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n");
479 curl_global_initialized = true;
428 480
429 if ((curl = curl_easy_init()) == NULL) 481 if ((curl = curl_easy_init()) == NULL) {
430 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n"); 482 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n");
483 }
484 curl_easy_initialized = true;
431 485
486 /* register cleanup function to shut down libcurl properly */
487 atexit (cleanup);
488
432 if (verbose >= 1) 489 if (verbose >= 1)
433 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, TRUE), "CURLOPT_VERBOSE"); 490 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, 1), "CURLOPT_VERBOSE");
434 491
435 /* print everything on stdout like check_http would do */ 492 /* print everything on stdout like check_http would do */
436 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR"); 493 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR");
@@ -445,12 +502,14 @@ check_http (void)
445 /* initialize buffer for body of the answer */ 502 /* initialize buffer for body of the answer */
446 if (curlhelp_initwritebuffer(&body_buf) < 0) 503 if (curlhelp_initwritebuffer(&body_buf) < 0)
447 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); 504 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n");
505 body_buf_initialized = true;
448 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_WRITEFUNCTION"); 506 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_WRITEFUNCTION");
449 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA"); 507 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA");
450 508
451 /* initialize buffer for header of the answer */ 509 /* initialize buffer for header of the answer */
452 if (curlhelp_initwritebuffer( &header_buf ) < 0) 510 if (curlhelp_initwritebuffer( &header_buf ) < 0)
453 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" ); 511 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" );
512 header_buf_initialized = true;
454 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_HEADERFUNCTION"); 513 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_HEADERFUNCTION");
455 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER"); 514 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER");
456 515
@@ -463,10 +522,14 @@ check_http (void)
463 522
464 // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy 523 // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy
465 if(use_ssl && host_name != NULL) { 524 if(use_ssl && host_name != NULL) {
466 if ( (res=lookup_host (server_address, addrstr, 100)) != 0) { 525 if ( (res=lookup_host (server_address, addrstr, DEFAULT_BUFFER_SIZE/2)) != 0) {
467 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), 526 snprintf (msg,
468 server_address, res, gai_strerror (res)); 527 DEFAULT_BUFFER_SIZE,
469 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 528 _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"),
529 server_address,
530 res,
531 gai_strerror (res));
532 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
470 } 533 }
471 snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, addrstr); 534 snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, addrstr);
472 host = curl_slist_append(NULL, dnscache); 535 host = curl_slist_append(NULL, dnscache);
@@ -475,10 +538,22 @@ check_http (void)
475 printf ("* curl CURLOPT_RESOLVE: %s\n", dnscache); 538 printf ("* curl CURLOPT_RESOLVE: %s\n", dnscache);
476 } 539 }
477 540
541 // If server_address is an IPv6 address it must be surround by square brackets
542 struct in6_addr tmp_in_addr;
543 if (inet_pton(AF_INET6, server_address, &tmp_in_addr) == 1) {
544 char *new_server_address = malloc(strlen(server_address) + 3);
545 if (new_server_address == NULL) {
546 die(STATE_UNKNOWN, "HTTP UNKNOWN - Unable to allocate memory\n");
547 }
548 snprintf(new_server_address, strlen(server_address)+3, "[%s]", server_address);
549 free(server_address);
550 server_address = new_server_address;
551 }
552
478 /* compose URL: use the address we want to connect to, set Host: header later */ 553 /* compose URL: use the address we want to connect to, set Host: header later */
479 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", 554 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s",
480 use_ssl ? "https" : "http", 555 use_ssl ? "https" : "http",
481 use_ssl & host_name != NULL ? host_name : server_address, 556 ( use_ssl & ( host_name != NULL ) ) ? host_name : server_address,
482 server_port, 557 server_port,
483 server_url 558 server_url
484 ); 559 );
@@ -499,7 +574,7 @@ check_http (void)
499 574
500 /* disable body for HEAD request */ 575 /* disable body for HEAD request */
501 if (http_method && !strcmp (http_method, "HEAD" )) { 576 if (http_method && !strcmp (http_method, "HEAD" )) {
502 no_body = TRUE; 577 no_body = true;
503 } 578 }
504 579
505 /* set HTTP protocol version */ 580 /* set HTTP protocol version */
@@ -554,7 +629,7 @@ check_http (void)
554 629
555#ifdef LIBCURL_FEATURE_SSL 630#ifdef LIBCURL_FEATURE_SSL
556 631
557 /* set SSL version, warn about unsecure or unsupported versions */ 632 /* set SSL version, warn about insecure or unsupported versions */
558 if (use_ssl) { 633 if (use_ssl) {
559 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSLVERSION, ssl_version), "CURLOPT_SSLVERSION"); 634 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSLVERSION, ssl_version), "CURLOPT_SSLVERSION");
560 } 635 }
@@ -582,7 +657,7 @@ check_http (void)
582 } 657 }
583 658
584 /* detect SSL library used by libcurl */ 659 /* detect SSL library used by libcurl */
585 ssl_library = curlhelp_get_ssl_library (curl); 660 ssl_library = curlhelp_get_ssl_library ();
586 661
587 /* try hard to get a stack of certificates to verify against */ 662 /* try hard to get a stack of certificates to verify against */
588 if (check_cert) { 663 if (check_cert) {
@@ -596,7 +671,7 @@ check_http (void)
596#ifdef USE_OPENSSL 671#ifdef USE_OPENSSL
597 /* libcurl and monitoring plugins built with OpenSSL, good */ 672 /* libcurl and monitoring plugins built with OpenSSL, good */
598 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); 673 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION");
599 is_openssl_callback = TRUE; 674 is_openssl_callback = true;
600#else /* USE_OPENSSL */ 675#else /* USE_OPENSSL */
601#endif /* USE_OPENSSL */ 676#endif /* USE_OPENSSL */
602 /* libcurl is built with OpenSSL, monitoring plugins, so falling 677 /* libcurl is built with OpenSSL, monitoring plugins, so falling
@@ -675,9 +750,11 @@ check_http (void)
675 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS"); 750 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS");
676 751
677 /* for now allow only http and https (we are a http(s) check plugin in the end) */ 752 /* for now allow only http and https (we are a http(s) check plugin in the end) */
678#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) 753#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 85, 0)
754 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"), "CURLOPT_REDIR_PROTOCOLS_STR");
755#elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4)
679 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS"); 756 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS");
680#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) */ 757#endif
681 758
682 /* TODO: handle the following aspects of redirection, make them 759 /* TODO: handle the following aspects of redirection, make them
683 * command line options too later: 760 * command line options too later:
@@ -721,11 +798,19 @@ check_http (void)
721 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_POSTFIELDS, http_post_data), "CURLOPT_POSTFIELDS"); 798 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_POSTFIELDS, http_post_data), "CURLOPT_POSTFIELDS");
722 } else if (!strcmp(http_method, "PUT")) { 799 } else if (!strcmp(http_method, "PUT")) {
723 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), "CURLOPT_READFUNCTION"); 800 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), "CURLOPT_READFUNCTION");
724 curlhelp_initreadbuffer (&put_buf, http_post_data, strlen (http_post_data)); 801 if (curlhelp_initreadbuffer (&put_buf, http_post_data, strlen (http_post_data)) < 0)
802 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating read buffer for PUT\n");
803 put_buf_initialized = true;
725 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA"); 804 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA");
726 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE"); 805 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE");
727 } 806 }
728 } 807 }
808
809 /* cookie handling */
810 if (cookie_jar_file != NULL) {
811 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEJAR, cookie_jar_file), "CURLOPT_COOKIEJAR");
812 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEFILE, cookie_jar_file), "CURLOPT_COOKIEFILE");
813 }
729 814
730 /* do the request */ 815 /* do the request */
731 res = curl_easy_perform(curl); 816 res = curl_easy_perform(curl);
@@ -736,25 +821,34 @@ check_http (void)
736 /* free header and server IP resolve lists, we don't need it anymore */ 821 /* free header and server IP resolve lists, we don't need it anymore */
737 curl_slist_free_all (header_list); header_list = NULL; 822 curl_slist_free_all (header_list); header_list = NULL;
738 curl_slist_free_all (server_ips); server_ips = NULL; 823 curl_slist_free_all (server_ips); server_ips = NULL;
824 if (host) {
825 curl_slist_free_all (host); host = NULL;
826 }
739 827
740 /* Curl errors, result in critical Nagios state */ 828 /* Curl errors, result in critical Nagios state */
741 if (res != CURLE_OK) { 829 if (res != CURLE_OK) {
742 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"), 830 snprintf (msg,
743 server_port, res, errbuf[0] ? errbuf : curl_easy_strerror(res)); 831 DEFAULT_BUFFER_SIZE,
744 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 832 _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"),
833 server_port,
834 res,
835 errbuf[0] ? errbuf : curl_easy_strerror(res));
836 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
745 } 837 }
746 838
747 /* certificate checks */ 839 /* certificate checks */
748#ifdef LIBCURL_FEATURE_SSL 840#ifdef LIBCURL_FEATURE_SSL
749 if (use_ssl == TRUE) { 841 if (use_ssl) {
750 if (check_cert == TRUE) { 842 if (check_cert) {
751 if (is_openssl_callback) { 843 if (is_openssl_callback) {
752#ifdef USE_OPENSSL 844#ifdef USE_OPENSSL
753 /* check certificate with OpenSSL functions, curl has been built against OpenSSL 845 /* check certificate with OpenSSL functions, curl has been built against OpenSSL
754 * and we actually have OpenSSL in the monitoring tools 846 * and we actually have OpenSSL in the monitoring tools
755 */ 847 */
756 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 848 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
757 return result; 849 if (!continue_after_check_cert) {
850 return result;
851 }
758#else /* USE_OPENSSL */ 852#else /* USE_OPENSSL */
759 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); 853 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n");
760#endif /* USE_OPENSSL */ 854#endif /* USE_OPENSSL */
@@ -782,30 +876,41 @@ check_http (void)
782 } 876 }
783GOT_FIRST_CERT: 877GOT_FIRST_CERT:
784 if (!raw_cert) { 878 if (!raw_cert) {
785 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates from CERTINFO information - certificate data was empty")); 879 snprintf (msg,
786 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 880 DEFAULT_BUFFER_SIZE,
881 _("Cannot retrieve certificates from CERTINFO information - certificate data was empty"));
882 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
787 } 883 }
788 BIO* cert_BIO = BIO_new (BIO_s_mem()); 884 BIO* cert_BIO = BIO_new (BIO_s_mem());
789 BIO_write (cert_BIO, raw_cert, strlen(raw_cert)); 885 BIO_write (cert_BIO, raw_cert, strlen(raw_cert));
790 cert = PEM_read_bio_X509 (cert_BIO, NULL, NULL, NULL); 886 cert = PEM_read_bio_X509 (cert_BIO, NULL, NULL, NULL);
791 if (!cert) { 887 if (!cert) {
792 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot read certificate from CERTINFO information - BIO error")); 888 snprintf (msg,
793 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 889 DEFAULT_BUFFER_SIZE,
890 _("Cannot read certificate from CERTINFO information - BIO error"));
891 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
794 } 892 }
795 BIO_free (cert_BIO); 893 BIO_free (cert_BIO);
796 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 894 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
797 return result; 895 if (!continue_after_check_cert) {
896 return result;
897 }
798#else /* USE_OPENSSL */ 898#else /* USE_OPENSSL */
799 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, 899 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal,
800 * so we use the libcurl CURLINFO data 900 * so we use the libcurl CURLINFO data
801 */ 901 */
802 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); 902 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit);
803 return result; 903 if (!continue_after_check_cert) {
904 return result;
905 }
804#endif /* USE_OPENSSL */ 906#endif /* USE_OPENSSL */
805 } else { 907 } else {
806 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"), 908 snprintf (msg,
807 res, curl_easy_strerror(res)); 909 DEFAULT_BUFFER_SIZE,
808 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 910 _("Cannot retrieve certificates - cURL returned %d - %s"),
911 res,
912 curl_easy_strerror(res));
913 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
809 } 914 }
810 } 915 }
811 } 916 }
@@ -826,7 +931,7 @@ GOT_FIRST_CERT:
826 perfd_time(total_time), 931 perfd_time(total_time),
827 perfd_size(page_len), 932 perfd_size(page_len),
828 perfd_time_connect(time_connect), 933 perfd_time_connect(time_connect),
829 use_ssl == TRUE ? perfd_time_ssl (time_appconnect-time_connect) : "", 934 use_ssl ? perfd_time_ssl (time_appconnect-time_connect) : "",
830 perfd_time_headers(time_headers - time_appconnect), 935 perfd_time_headers(time_headers - time_appconnect),
831 perfd_time_firstbyte(time_firstbyte - time_headers), 936 perfd_time_firstbyte(time_firstbyte - time_headers),
832 perfd_time_transfer(total_time-time_firstbyte) 937 perfd_time_transfer(total_time-time_firstbyte)
@@ -844,11 +949,15 @@ GOT_FIRST_CERT:
844 949
845 /* get status line of answer, check sanity of HTTP code */ 950 /* get status line of answer, check sanity of HTTP code */
846 if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) { 951 if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) {
847 snprintf (msg, DEFAULT_BUFFER_SIZE, "Unparsable status line in %.3g seconds response time|%s\n", 952 snprintf (msg,
848 total_time, perfstring); 953 DEFAULT_BUFFER_SIZE,
954 "Unparsable status line in %.3g seconds response time|%s\n",
955 total_time,
956 perfstring);
849 /* we cannot know the major/minor version here for sure as we cannot parse the first line */ 957 /* we cannot know the major/minor version here for sure as we cannot parse the first line */
850 die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg); 958 die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg);
851 } 959 }
960 status_line_initialized = true;
852 961
853 /* get result code from cURL */ 962 /* get result code from cURL */
854 handle_curl_option_return_code (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE"); 963 handle_curl_option_return_code (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE");
@@ -864,9 +973,16 @@ GOT_FIRST_CERT:
864 /* make sure the status line matches the response we are looking for */ 973 /* make sure the status line matches the response we are looking for */
865 if (!expected_statuscode(status_line.first_line, server_expect)) { 974 if (!expected_statuscode(status_line.first_line, server_expect)) {
866 if (server_port == HTTP_PORT) 975 if (server_port == HTTP_PORT)
867 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line); 976 snprintf(msg,
977 DEFAULT_BUFFER_SIZE,
978 _("Invalid HTTP response received from host: %s\n"),
979 status_line.first_line);
868 else 980 else
869 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, status_line.first_line); 981 snprintf(msg,
982 DEFAULT_BUFFER_SIZE,
983 _("Invalid HTTP response received from host on port %d: %s\n"),
984 server_port,
985 status_line.first_line);
870 die (STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg, 986 die (STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg,
871 show_body ? "\n" : "", 987 show_body ? "\n" : "",
872 show_body ? body_buf.buf : ""); 988 show_body ? body_buf.buf : "");
@@ -902,7 +1018,7 @@ GOT_FIRST_CERT:
902 } 1018 }
903 } else { 1019 } else {
904 /* this is a specific code in the command line to 1020 /* this is a specific code in the command line to
905 * be returned when a redirection is encoutered 1021 * be returned when a redirection is encountered
906 */ 1022 */
907 } 1023 }
908 result = max_state_alt (onredirect, result); 1024 result = max_state_alt (onredirect, result);
@@ -939,64 +1055,119 @@ GOT_FIRST_CERT:
939 1055
940 if (strlen (header_expect)) { 1056 if (strlen (header_expect)) {
941 if (!strstr (header_buf.buf, header_expect)) { 1057 if (!strstr (header_buf.buf, header_expect)) {
1058
942 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search)); 1059 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search));
1060
943 if(output_header_search[sizeof(output_header_search)-1]!='\0') { 1061 if(output_header_search[sizeof(output_header_search)-1]!='\0') {
944 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4); 1062 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4);
945 } 1063 }
946 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); 1064
947 result = STATE_CRITICAL; 1065 char tmp[DEFAULT_BUFFER_SIZE];
1066
1067 snprintf (tmp,
1068 DEFAULT_BUFFER_SIZE,
1069 _("%sheader '%s' not found on '%s://%s:%d%s', "),
1070 msg,
1071 output_header_search,
1072 use_ssl ? "https" : "http",
1073 host_name ? host_name : server_address,
1074 server_port,
1075 server_url);
1076
1077 strcpy(msg, tmp);
1078
1079 result = STATE_CRITICAL;
948 } 1080 }
949 } 1081 }
950 1082
951 if (strlen (string_expect)) { 1083 if (strlen (string_expect)) {
952 if (!strstr (body_buf.buf, string_expect)) { 1084 if (!strstr (body_buf.buf, string_expect)) {
1085
953 strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); 1086 strncpy(&output_string_search[0],string_expect,sizeof(output_string_search));
1087
954 if(output_string_search[sizeof(output_string_search)-1]!='\0') { 1088 if(output_string_search[sizeof(output_string_search)-1]!='\0') {
955 bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); 1089 bcopy("...",&output_string_search[sizeof(output_string_search)-4],4);
956 } 1090 }
957 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); 1091
958 result = STATE_CRITICAL; 1092 char tmp[DEFAULT_BUFFER_SIZE];
1093
1094 snprintf (tmp,
1095 DEFAULT_BUFFER_SIZE,
1096 _("%sstring '%s' not found on '%s://%s:%d%s', "),
1097 msg,
1098 output_string_search,
1099 use_ssl ? "https" : "http",
1100 host_name ? host_name : server_address,
1101 server_port,
1102 server_url);
1103
1104 strcpy(msg, tmp);
1105
1106 result = STATE_CRITICAL;
959 } 1107 }
960 } 1108 }
961 1109
962 if (strlen (regexp)) { 1110 if (strlen (regexp)) {
963 errcode = regexec (&preg, body_buf.buf, REGS, pmatch, 0); 1111 errcode = regexec (&preg, body_buf.buf, REGS, pmatch, 0);
964 if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { 1112 if ((errcode == 0 && !invert_regex) || (errcode == REG_NOMATCH && invert_regex)) {
965 /* OK - No-op to avoid changing the logic around it */ 1113 /* OK - No-op to avoid changing the logic around it */
966 result = max_state_alt(STATE_OK, result); 1114 result = max_state_alt(STATE_OK, result);
967 } 1115 }
968 else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { 1116 else if ((errcode == REG_NOMATCH && !invert_regex) || (errcode == 0 && invert_regex)) {
969 if (invert_regex == 0) 1117 if (!invert_regex) {
970 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg); 1118 char tmp[DEFAULT_BUFFER_SIZE];
971 else 1119
972 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg); 1120 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg);
973 result = STATE_CRITICAL; 1121 strcpy(msg, tmp);
974 } 1122
975 else { 1123 } else {
976 regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 1124 char tmp[DEFAULT_BUFFER_SIZE];
977 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sExecute Error: %s, "), msg, errbuf); 1125
978 result = STATE_UNKNOWN; 1126 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg);
979 } 1127 strcpy(msg, tmp);
1128
1129 }
1130 result = STATE_CRITICAL;
1131 } else {
1132 regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
1133
1134 char tmp[DEFAULT_BUFFER_SIZE];
1135
1136 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sExecute Error: %s, "), msg, errbuf);
1137 strcpy(msg, tmp);
1138 result = STATE_UNKNOWN;
1139 }
980 } 1140 }
981 1141
982 /* make sure the page is of an appropriate size */ 1142 /* make sure the page is of an appropriate size */
983 if ((max_page_len > 0) && (page_len > max_page_len)) { 1143 if ((max_page_len > 0) && (page_len > max_page_len)) {
984 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spage size %d too large, "), msg, page_len); 1144 char tmp[DEFAULT_BUFFER_SIZE];
985 result = max_state_alt(STATE_WARNING, result); 1145
986 } else if ((min_page_len > 0) && (page_len < min_page_len)) { 1146 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spage size %d too large, "), msg, page_len);
987 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spage size %d too small, "), msg, page_len); 1147
988 result = max_state_alt(STATE_WARNING, result); 1148 strcpy(msg, tmp);
989 } 1149
1150 result = max_state_alt(STATE_WARNING, result);
1151
1152 } else if ((min_page_len > 0) && (page_len < min_page_len)) {
1153 char tmp[DEFAULT_BUFFER_SIZE];
1154
1155 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spage size %d too small, "), msg, page_len);
1156 strcpy(msg, tmp);
1157 result = max_state_alt(STATE_WARNING, result);
1158 }
990 1159
991 /* -w, -c: check warning and critical level */ 1160 /* -w, -c: check warning and critical level */
992 result = max_state_alt(get_status(total_time, thlds), result); 1161 result = max_state_alt(get_status(total_time, thlds), result);
993 1162
994 /* Cut-off trailing characters */ 1163 /* Cut-off trailing characters */
995 if(msg[strlen(msg)-2] == ',') 1164 if (strlen(msg) >= 2) {
996 msg[strlen(msg)-2] = '\0'; 1165 if(msg[strlen(msg)-2] == ',')
997 else 1166 msg[strlen(msg)-2] = '\0';
998 msg[strlen(msg)-3] = '\0'; 1167 else
999 1168 msg[strlen(msg)-3] = '\0';
1169 }
1170
1000 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ 1171 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */
1001 die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", 1172 die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s",
1002 state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), 1173 state_text(result), string_statuscode (status_line.http_major, status_line.http_minor),
@@ -1008,16 +1179,6 @@ GOT_FIRST_CERT:
1008 (show_body ? body_buf.buf : ""), 1179 (show_body ? body_buf.buf : ""),
1009 (show_body ? "\n" : "") ); 1180 (show_body ? "\n" : "") );
1010 1181
1011 /* proper cleanup after die? */
1012 curlhelp_free_statusline(&status_line);
1013 curl_easy_cleanup (curl);
1014 curl_global_cleanup ();
1015 curlhelp_freewritebuffer (&body_buf);
1016 curlhelp_freewritebuffer (&header_buf);
1017 if (!strcmp (http_method, "PUT")) {
1018 curlhelp_freereadbuffer (&put_buf);
1019 }
1020
1021 return result; 1182 return result;
1022} 1183}
1023 1184
@@ -1054,7 +1215,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1054 char *new_url; 1215 char *new_url;
1055 1216
1056 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 1217 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
1057 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 1218 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
1058 headers, &nof_headers, 0); 1219 headers, &nof_headers, 0);
1059 1220
1060 location = get_header_value (headers, nof_headers, "location"); 1221 location = get_header_value (headers, nof_headers, "location");
@@ -1113,7 +1274,10 @@ redir (curlhelp_write_curlbuf* header_buf)
1113 } 1274 }
1114 } 1275 }
1115 1276
1116 use_ssl = !uri_strcmp (uri.scheme, "https"); 1277 if (!uri_strcmp (uri.scheme, "https"))
1278 use_ssl = true;
1279 else
1280 use_ssl = false;
1117 1281
1118 /* we do a sloppy test here only, because uriparser would have failed 1282 /* we do a sloppy test here only, because uriparser would have failed
1119 * above, if the port would be invalid, we just check for MAX_PORT 1283 * above, if the port would be invalid, we just check for MAX_PORT
@@ -1188,6 +1352,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1188 * attached to the URL in Location 1352 * attached to the URL in Location
1189 */ 1353 */
1190 1354
1355 cleanup ();
1191 check_http (); 1356 check_http ();
1192} 1357}
1193 1358
@@ -1200,7 +1365,7 @@ test_file (char *path)
1200 usage2 (_("file does not exist or is not readable"), path); 1365 usage2 (_("file does not exist or is not readable"), path);
1201} 1366}
1202 1367
1203int 1368bool
1204process_arguments (int argc, char **argv) 1369process_arguments (int argc, char **argv)
1205{ 1370{
1206 char *p; 1371 char *p;
@@ -1210,9 +1375,12 @@ process_arguments (int argc, char **argv)
1210 enum { 1375 enum {
1211 INVERT_REGEX = CHAR_MAX + 1, 1376 INVERT_REGEX = CHAR_MAX + 1,
1212 SNI_OPTION, 1377 SNI_OPTION,
1378 MAX_REDIRS_OPTION,
1379 CONTINUE_AFTER_CHECK_CERT,
1213 CA_CERT_OPTION, 1380 CA_CERT_OPTION,
1214 HTTP_VERSION_OPTION, 1381 HTTP_VERSION_OPTION,
1215 AUTOMATIC_DECOMPRESSION 1382 AUTOMATIC_DECOMPRESSION,
1383 COOKIE_JAR
1216 }; 1384 };
1217 1385
1218 int option = 0; 1386 int option = 0;
@@ -1243,6 +1411,7 @@ process_arguments (int argc, char **argv)
1243 {"private-key", required_argument, 0, 'K'}, 1411 {"private-key", required_argument, 0, 'K'},
1244 {"ca-cert", required_argument, 0, CA_CERT_OPTION}, 1412 {"ca-cert", required_argument, 0, CA_CERT_OPTION},
1245 {"verify-cert", no_argument, 0, 'D'}, 1413 {"verify-cert", no_argument, 0, 'D'},
1414 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
1246 {"useragent", required_argument, 0, 'A'}, 1415 {"useragent", required_argument, 0, 'A'},
1247 {"header", required_argument, 0, 'k'}, 1416 {"header", required_argument, 0, 'k'},
1248 {"no-body", no_argument, 0, 'N'}, 1417 {"no-body", no_argument, 0, 'N'},
@@ -1254,13 +1423,15 @@ process_arguments (int argc, char **argv)
1254 {"use-ipv6", no_argument, 0, '6'}, 1423 {"use-ipv6", no_argument, 0, '6'},
1255 {"extended-perfdata", no_argument, 0, 'E'}, 1424 {"extended-perfdata", no_argument, 0, 'E'},
1256 {"show-body", no_argument, 0, 'B'}, 1425 {"show-body", no_argument, 0, 'B'},
1426 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
1257 {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, 1427 {"http-version", required_argument, 0, HTTP_VERSION_OPTION},
1258 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, 1428 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION},
1429 {"cookie-jar", required_argument, 0, COOKIE_JAR},
1259 {0, 0, 0, 0} 1430 {0, 0, 0, 0}
1260 }; 1431 };
1261 1432
1262 if (argc < 2) 1433 if (argc < 2)
1263 return ERROR; 1434 return false;
1264 1435
1265 /* support check_http compatible arguments */ 1436 /* support check_http compatible arguments */
1266 for (c = 1; c < argc; c++) { 1437 for (c = 1; c < argc; c++) {
@@ -1340,7 +1511,7 @@ process_arguments (int argc, char **argv)
1340 if( strtol(optarg, NULL, 10) > MAX_PORT) 1511 if( strtol(optarg, NULL, 10) > MAX_PORT)
1341 usage2 (_("Invalid port number, supplied port number is too big"), optarg); 1512 usage2 (_("Invalid port number, supplied port number is too big"), optarg);
1342 server_port = (unsigned short)strtol(optarg, NULL, 10); 1513 server_port = (unsigned short)strtol(optarg, NULL, 10);
1343 specify_port = TRUE; 1514 specify_port = true;
1344 } 1515 }
1345 break; 1516 break;
1346 case 'a': /* authorization info */ 1517 case 'a': /* authorization info */
@@ -1374,10 +1545,10 @@ process_arguments (int argc, char **argv)
1374 http_opt_headers[http_opt_headers_count - 1] = optarg; 1545 http_opt_headers[http_opt_headers_count - 1] = optarg;
1375 break; 1546 break;
1376 case 'L': /* show html link */ 1547 case 'L': /* show html link */
1377 display_html = TRUE; 1548 display_html = true;
1378 break; 1549 break;
1379 case 'n': /* do not show html link */ 1550 case 'n': /* do not show html link */
1380 display_html = FALSE; 1551 display_html = false;
1381 break; 1552 break;
1382 case 'C': /* Check SSL cert validity */ 1553 case 'C': /* Check SSL cert validity */
1383#ifdef LIBCURL_FEATURE_SSL 1554#ifdef LIBCURL_FEATURE_SSL
@@ -1398,9 +1569,14 @@ process_arguments (int argc, char **argv)
1398 usage2 (_("Invalid certificate expiration period"), optarg); 1569 usage2 (_("Invalid certificate expiration period"), optarg);
1399 days_till_exp_warn = atoi (optarg); 1570 days_till_exp_warn = atoi (optarg);
1400 } 1571 }
1401 check_cert = TRUE; 1572 check_cert = true;
1402 goto enable_ssl; 1573 goto enable_ssl;
1403#endif 1574#endif
1575 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
1576#ifdef HAVE_SSL
1577 continue_after_check_cert = true;
1578 break;
1579#endif
1404 case 'J': /* use client certificate */ 1580 case 'J': /* use client certificate */
1405#ifdef LIBCURL_FEATURE_SSL 1581#ifdef LIBCURL_FEATURE_SSL
1406 test_file(optarg); 1582 test_file(optarg);
@@ -1421,13 +1597,13 @@ process_arguments (int argc, char **argv)
1421#endif 1597#endif
1422#ifdef LIBCURL_FEATURE_SSL 1598#ifdef LIBCURL_FEATURE_SSL
1423 case 'D': /* verify peer certificate & host */ 1599 case 'D': /* verify peer certificate & host */
1424 verify_peer_and_host = TRUE; 1600 verify_peer_and_host = true;
1425 goto enable_ssl; 1601 break;
1426#endif 1602#endif
1427 case 'S': /* use SSL */ 1603 case 'S': /* use SSL */
1428#ifdef LIBCURL_FEATURE_SSL 1604#ifdef LIBCURL_FEATURE_SSL
1429 enable_ssl: 1605 enable_ssl:
1430 use_ssl = TRUE; 1606 use_ssl = true;
1431 /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default. 1607 /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default.
1432 * Only set if it's non-zero. This helps when we include multiple 1608 * Only set if it's non-zero. This helps when we include multiple
1433 * parameters, like -S and -C combinations */ 1609 * parameters, like -S and -C combinations */
@@ -1501,17 +1677,24 @@ process_arguments (int argc, char **argv)
1501#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ 1677#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */
1502 if (verbose >= 2) 1678 if (verbose >= 2)
1503 printf(_("* Set SSL/TLS version to %d\n"), ssl_version); 1679 printf(_("* Set SSL/TLS version to %d\n"), ssl_version);
1504 if (specify_port == FALSE) 1680 if (!specify_port)
1505 server_port = HTTPS_PORT; 1681 server_port = HTTPS_PORT;
1506 break; 1682 break;
1507#else /* LIBCURL_FEATURE_SSL */ 1683#else /* LIBCURL_FEATURE_SSL */
1508 /* -C -J and -K fall through to here without SSL */ 1684 /* -C -J and -K fall through to here without SSL */
1509 usage4 (_("Invalid option - SSL is not available")); 1685 usage4 (_("Invalid option - SSL is not available"));
1510 break; 1686 break;
1511 case SNI_OPTION: /* --sni is parsed, but ignored, the default is TRUE with libcurl */ 1687 case SNI_OPTION: /* --sni is parsed, but ignored, the default is true with libcurl */
1512 use_sni = TRUE; 1688 use_sni = true;
1513 break; 1689 break;
1514#endif /* LIBCURL_FEATURE_SSL */ 1690#endif /* LIBCURL_FEATURE_SSL */
1691 case MAX_REDIRS_OPTION:
1692 if (!is_intnonneg (optarg))
1693 usage2 (_("Invalid max_redirs count"), optarg);
1694 else {
1695 max_depth = atoi (optarg);
1696 }
1697 break;
1515 case 'f': /* onredirect */ 1698 case 'f': /* onredirect */
1516 if (!strcmp (optarg, "ok")) 1699 if (!strcmp (optarg, "ok"))
1517 onredirect = STATE_OK; 1700 onredirect = STATE_OK;
@@ -1556,6 +1739,7 @@ process_arguments (int argc, char **argv)
1556 break; 1739 break;
1557 case 'R': /* regex */ 1740 case 'R': /* regex */
1558 cflags |= REG_ICASE; 1741 cflags |= REG_ICASE;
1742 // fall through
1559 case 'r': /* regex */ 1743 case 'r': /* regex */
1560 strncpy (regexp, optarg, MAX_RE_SIZE - 1); 1744 strncpy (regexp, optarg, MAX_RE_SIZE - 1);
1561 regexp[MAX_RE_SIZE - 1] = 0; 1745 regexp[MAX_RE_SIZE - 1] = 0;
@@ -1563,11 +1747,11 @@ process_arguments (int argc, char **argv)
1563 if (errcode != 0) { 1747 if (errcode != 0) {
1564 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 1748 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
1565 printf (_("Could Not Compile Regular Expression: %s"), errbuf); 1749 printf (_("Could Not Compile Regular Expression: %s"), errbuf);
1566 return ERROR; 1750 return false;
1567 } 1751 }
1568 break; 1752 break;
1569 case INVERT_REGEX: 1753 case INVERT_REGEX:
1570 invert_regex = 1; 1754 invert_regex = true;
1571 break; 1755 break;
1572 case '4': 1756 case '4':
1573 address_family = AF_INET; 1757 address_family = AF_INET;
@@ -1602,7 +1786,7 @@ process_arguments (int argc, char **argv)
1602 break; 1786 break;
1603 } 1787 }
1604 case 'N': /* no-body */ 1788 case 'N': /* no-body */
1605 no_body = TRUE; 1789 no_body = true;
1606 break; 1790 break;
1607 case 'M': /* max-age */ 1791 case 'M': /* max-age */
1608 { 1792 {
@@ -1625,10 +1809,10 @@ process_arguments (int argc, char **argv)
1625 } 1809 }
1626 break; 1810 break;
1627 case 'E': /* show extended perfdata */ 1811 case 'E': /* show extended perfdata */
1628 show_extended_perfdata = TRUE; 1812 show_extended_perfdata = true;
1629 break; 1813 break;
1630 case 'B': /* print body content after status line */ 1814 case 'B': /* print body content after status line */
1631 show_body = TRUE; 1815 show_body = true;
1632 break; 1816 break;
1633 case HTTP_VERSION_OPTION: 1817 case HTTP_VERSION_OPTION:
1634 curl_http_version = CURL_HTTP_VERSION_NONE; 1818 curl_http_version = CURL_HTTP_VERSION_NONE;
@@ -1643,12 +1827,15 @@ process_arguments (int argc, char **argv)
1643 curl_http_version = CURL_HTTP_VERSION_NONE; 1827 curl_http_version = CURL_HTTP_VERSION_NONE;
1644#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */ 1828#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */
1645 } else { 1829 } else {
1646 fprintf (stderr, "unkown http-version parameter: %s\n", optarg); 1830 fprintf (stderr, "unknown http-version parameter: %s\n", optarg);
1647 exit (STATE_WARNING); 1831 exit (STATE_WARNING);
1648 } 1832 }
1649 break; 1833 break;
1650 case AUTOMATIC_DECOMPRESSION: 1834 case AUTOMATIC_DECOMPRESSION:
1651 automatic_decompression = TRUE; 1835 automatic_decompression = true;
1836 break;
1837 case COOKIE_JAR:
1838 cookie_jar_file = optarg;
1652 break; 1839 break;
1653 case '?': 1840 case '?':
1654 /* print short usage statement if args not parsable */ 1841 /* print short usage statement if args not parsable */
@@ -1689,52 +1876,52 @@ process_arguments (int argc, char **argv)
1689 virtual_port = server_port; 1876 virtual_port = server_port;
1690 else { 1877 else {
1691 if ((use_ssl && server_port == HTTPS_PORT) || (!use_ssl && server_port == HTTP_PORT)) 1878 if ((use_ssl && server_port == HTTPS_PORT) || (!use_ssl && server_port == HTTP_PORT))
1692 if(specify_port == FALSE) 1879 if(!specify_port)
1693 server_port = virtual_port; 1880 server_port = virtual_port;
1694 } 1881 }
1695 1882
1696 return TRUE; 1883 return true;
1697} 1884}
1698 1885
1699char *perfd_time (double elapsed_time) 1886char *perfd_time (double elapsed_time)
1700{ 1887{
1701 return fperfdata ("time", elapsed_time, "s", 1888 return fperfdata ("time", elapsed_time, "s",
1702 thlds->warning?TRUE:FALSE, thlds->warning?thlds->warning->end:0, 1889 thlds->warning?true:false, thlds->warning?thlds->warning->end:0,
1703 thlds->critical?TRUE:FALSE, thlds->critical?thlds->critical->end:0, 1890 thlds->critical?true:false, thlds->critical?thlds->critical->end:0,
1704 TRUE, 0, TRUE, socket_timeout); 1891 true, 0, true, socket_timeout);
1705} 1892}
1706 1893
1707char *perfd_time_connect (double elapsed_time_connect) 1894char *perfd_time_connect (double elapsed_time_connect)
1708{ 1895{
1709 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1896 return fperfdata ("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1710} 1897}
1711 1898
1712char *perfd_time_ssl (double elapsed_time_ssl) 1899char *perfd_time_ssl (double elapsed_time_ssl)
1713{ 1900{
1714 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1901 return fperfdata ("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1715} 1902}
1716 1903
1717char *perfd_time_headers (double elapsed_time_headers) 1904char *perfd_time_headers (double elapsed_time_headers)
1718{ 1905{
1719 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1906 return fperfdata ("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1720} 1907}
1721 1908
1722char *perfd_time_firstbyte (double elapsed_time_firstbyte) 1909char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1723{ 1910{
1724 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1911 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1725} 1912}
1726 1913
1727char *perfd_time_transfer (double elapsed_time_transfer) 1914char *perfd_time_transfer (double elapsed_time_transfer)
1728{ 1915{
1729 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1916 return fperfdata ("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1730} 1917}
1731 1918
1732char *perfd_size (int page_len) 1919char *perfd_size (int page_len)
1733{ 1920{
1734 return perfdata ("size", page_len, "B", 1921 return perfdata ("size", page_len, "B",
1735 (min_page_len>0?TRUE:FALSE), min_page_len, 1922 (min_page_len>0?true:false), min_page_len,
1736 (min_page_len>0?TRUE:FALSE), 0, 1923 (min_page_len>0?true:false), 0,
1737 TRUE, 0, FALSE, 0); 1924 true, 0, false, 0);
1738} 1925}
1739 1926
1740void 1927void
@@ -1791,7 +1978,11 @@ print_help (void)
1791#endif 1978#endif
1792 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1979 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1793 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1980 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1794 printf (" %s\n", _("(when this option is used the URL is not checked.)")); 1981 printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use"));
1982 printf (" %s\n", _(" --continue-after-certificate to override this behavior)"));
1983 printf (" %s\n", "--continue-after-certificate");
1984 printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check."));
1985 printf (" %s\n", _("Does nothing unless -C is used."));
1795 printf (" %s\n", "-J, --client-cert=FILE"); 1986 printf (" %s\n", "-J, --client-cert=FILE");
1796 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); 1987 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1797 printf (" %s\n", _("to be used in establishing the SSL session")); 1988 printf (" %s\n", _("to be used in establishing the SSL session"));
@@ -1854,6 +2045,9 @@ print_help (void)
1854 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); 2045 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same."));
1855 printf (" %s\n", _("follow uses the old redirection algorithm of check_http.")); 2046 printf (" %s\n", _("follow uses the old redirection algorithm of check_http."));
1856 printf (" %s\n", _("curl uses CURL_FOLLOWLOCATION built into libcurl.")); 2047 printf (" %s\n", _("curl uses CURL_FOLLOWLOCATION built into libcurl."));
2048 printf (" %s\n", "--max-redirs=INTEGER");
2049 printf (" %s", _("Maximal number of redirects (default: "));
2050 printf ("%d)\n", DEFAULT_MAX_REDIRS);
1857 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 2051 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
1858 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); 2052 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
1859 printf ("\n"); 2053 printf ("\n");
@@ -1862,6 +2056,8 @@ print_help (void)
1862 printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); 2056 printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)"));
1863 printf (" %s\n", "--enable-automatic-decompression"); 2057 printf (" %s\n", "--enable-automatic-decompression");
1864 printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); 2058 printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING)."));
2059 printf (" %s\n", "---cookie-jar=FILE");
2060 printf (" %s\n", _("Store cookies in the cookie jar and send them out when requested."));
1865 printf ("\n"); 2061 printf ("\n");
1866 2062
1867 printf (UT_WARN_CRIT); 2063 printf (UT_WARN_CRIT);
@@ -1941,12 +2137,13 @@ print_usage (void)
1941 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); 2137 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
1942 printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>] [-D]\n"); 2138 printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>] [-D]\n");
1943 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); 2139 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
1944 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport|curl>]\n"); 2140 printf (" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n");
1945 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); 2141 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
1946 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 2142 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
1947 printf (" [-A string] [-k string] [-S <version>] [--sni]\n"); 2143 printf (" [-A string] [-k string] [-S <version>] [--sni]\n");
1948 printf (" [-T <content-type>] [-j method]\n"); 2144 printf (" [-T <content-type>] [-j method]\n");
1949 printf (" [--http-version=<version>]\n"); 2145 printf (" [--http-version=<version>] [--enable-automatic-decompression]\n");
2146 printf (" [--cookie-jar=<cookie jar file>\n");
1950 printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname); 2147 printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname);
1951 printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n"); 2148 printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n");
1952 printf ("\n"); 2149 printf ("\n");
@@ -1980,9 +2177,12 @@ curlhelp_buffer_write_callback (void *buffer, size_t size, size_t nmemb, void *s
1980 curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream; 2177 curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream;
1981 2178
1982 while (buf->bufsize < buf->buflen + size * nmemb + 1) { 2179 while (buf->bufsize < buf->buflen + size * nmemb + 1) {
1983 buf->bufsize *= buf->bufsize * 2; 2180 buf->bufsize = buf->bufsize * 2;
1984 buf->buf = (char *)realloc (buf->buf, buf->bufsize); 2181 buf->buf = (char *)realloc (buf->buf, buf->bufsize);
1985 if (buf->buf == NULL) return -1; 2182 if (buf->buf == NULL) {
2183 fprintf(stderr, "malloc failed (%d) %s\n", errno, strerror(errno));
2184 return -1;
2185 }
1986 } 2186 }
1987 2187
1988 memcpy (buf->buf + buf->buflen, buffer, size * nmemb); 2188 memcpy (buf->buf + buf->buflen, buffer, size * nmemb);
@@ -2103,11 +2303,10 @@ curlhelp_parse_statusline (const char *buf, curlhelp_statusline *status_line)
2103 if( strchr( p, '.' ) != NULL ) { 2303 if( strchr( p, '.' ) != NULL ) {
2104 2304
2105 /* HTTP 1.x case */ 2305 /* HTTP 1.x case */
2106 char *ppp; 2306 strtok( p, "." );
2107 ppp = strtok( p, "." );
2108 status_line->http_major = (int)strtol( p, &pp, 10 ); 2307 status_line->http_major = (int)strtol( p, &pp, 10 );
2109 if( *pp != '\0' ) { free( first_line_buf ); return -1; } 2308 if( *pp != '\0' ) { free( first_line_buf ); return -1; }
2110 ppp = strtok( NULL, " " ); 2309 strtok( NULL, " " );
2111 status_line->http_minor = (int)strtol( p, &pp, 10 ); 2310 status_line->http_minor = (int)strtol( p, &pp, 10 );
2112 if( *pp != '\0' ) { free( first_line_buf ); return -1; } 2311 if( *pp != '\0' ) { free( first_line_buf ); return -1; }
2113 p += 4; /* 1.x SP */ 2312 p += 4; /* 1.x SP */
@@ -2188,43 +2387,73 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA
2188 size_t msglen; 2387 size_t msglen;
2189 2388
2190 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2389 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2191 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2390 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2192 headers, &nof_headers, 0); 2391 headers, &nof_headers, 0);
2193 2392
2194 server_date = get_header_value (headers, nof_headers, "date"); 2393 server_date = get_header_value (headers, nof_headers, "date");
2195 document_date = get_header_value (headers, nof_headers, "last-modified"); 2394 document_date = get_header_value (headers, nof_headers, "last-modified");
2196 2395
2197 if (!server_date || !*server_date) { 2396 if (!server_date || !*server_date) {
2198 snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sServer date unknown, "), *msg); 2397 char tmp[DEFAULT_BUFFER_SIZE];
2199 date_result = max_state_alt(STATE_UNKNOWN, date_result); 2398
2200 } else if (!document_date || !*document_date) { 2399 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sServer date unknown, "), *msg);
2201 snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sDocument modification date unknown, "), *msg); 2400 strcpy(*msg, tmp);
2202 date_result = max_state_alt(STATE_CRITICAL, date_result); 2401
2402 date_result = max_state_alt(STATE_UNKNOWN, date_result);
2403
2404 } else if (!document_date || !*document_date) {
2405 char tmp[DEFAULT_BUFFER_SIZE];
2406
2407 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sDocument modification date unknown, "), *msg);
2408 strcpy(*msg, tmp);
2409
2410 date_result = max_state_alt(STATE_CRITICAL, date_result);
2411
2203 } else { 2412 } else {
2204 time_t srv_data = curl_getdate (server_date, NULL); 2413 time_t srv_data = curl_getdate (server_date, NULL);
2205 time_t doc_data = curl_getdate (document_date, NULL); 2414 time_t doc_data = curl_getdate (document_date, NULL);
2206 if (verbose >= 2) 2415 if (verbose >= 2)
2207 printf ("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data, document_date, (int)doc_data); 2416 printf ("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data, document_date, (int)doc_data);
2208 if (srv_data <= 0) { 2417 if (srv_data <= 0) {
2209 snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); 2418 char tmp[DEFAULT_BUFFER_SIZE];
2210 date_result = max_state_alt(STATE_CRITICAL, date_result); 2419
2211 } else if (doc_data <= 0) { 2420 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sServer date \"%100s\" unparsable, "), *msg, server_date);
2212 snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); 2421 strcpy(*msg, tmp);
2213 date_result = max_state_alt(STATE_CRITICAL, date_result); 2422
2214 } else if (doc_data > srv_data + 30) { 2423 date_result = max_state_alt(STATE_CRITICAL, date_result);
2215 snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data); 2424 } else if (doc_data <= 0) {
2216 date_result = max_state_alt(STATE_CRITICAL, date_result); 2425 char tmp[DEFAULT_BUFFER_SIZE];
2217 } else if (doc_data < srv_data - maximum_age) { 2426
2218 int n = (srv_data - doc_data); 2427 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date);
2219 if (n > (60 * 60 * 24 * 2)) { 2428 strcpy(*msg, tmp);
2220 snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sLast modified %.1f days ago, "), *msg, ((float) n) / (60 * 60 * 24)); 2429
2221 date_result = max_state_alt(STATE_CRITICAL, date_result); 2430 date_result = max_state_alt(STATE_CRITICAL, date_result);
2222 } else { 2431 } else if (doc_data > srv_data + 30) {
2223 snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60); 2432 char tmp[DEFAULT_BUFFER_SIZE];
2224 date_result = max_state_alt(STATE_CRITICAL, date_result); 2433
2225 } 2434 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data);
2226 } 2435 strcpy(*msg, tmp);
2227 } 2436
2437 date_result = max_state_alt(STATE_CRITICAL, date_result);
2438 } else if (doc_data < srv_data - maximum_age) {
2439 int n = (srv_data - doc_data);
2440 if (n > (60 * 60 * 24 * 2)) {
2441 char tmp[DEFAULT_BUFFER_SIZE];
2442
2443 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %.1f days ago, "), *msg, ((float) n) / (60 * 60 * 24));
2444 strcpy(*msg, tmp);
2445
2446 date_result = max_state_alt(STATE_CRITICAL, date_result);
2447 } else {
2448 char tmp[DEFAULT_BUFFER_SIZE];
2449
2450 snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60);
2451 strcpy(*msg, tmp);
2452
2453 date_result = max_state_alt(STATE_CRITICAL, date_result);
2454 }
2455 }
2456 }
2228 2457
2229 if (server_date) free (server_date); 2458 if (server_date) free (server_date);
2230 if (document_date) free (document_date); 2459 if (document_date) free (document_date);
@@ -2246,7 +2475,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri
2246 curlhelp_statusline status_line; 2475 curlhelp_statusline status_line;
2247 2476
2248 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2477 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2249 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2478 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2250 headers, &nof_headers, 0); 2479 headers, &nof_headers, 0);
2251 2480
2252 content_length_s = get_header_value (headers, nof_headers, "content-length"); 2481 content_length_s = get_header_value (headers, nof_headers, "content-length");
@@ -2266,7 +2495,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri
2266 2495
2267/* TODO: is there a better way in libcurl to check for the SSL library? */ 2496/* TODO: is there a better way in libcurl to check for the SSL library? */
2268curlhelp_ssl_library 2497curlhelp_ssl_library
2269curlhelp_get_ssl_library (CURL* curl) 2498curlhelp_get_ssl_library ()
2270{ 2499{
2271 curl_version_info_data* version_data; 2500 curl_version_info_data* version_data;
2272 char *ssl_version; 2501 char *ssl_version;
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c
index ced13d0..c24ca24 100644
--- a/plugins/check_dbi.c
+++ b/plugins/check_dbi.c
@@ -141,21 +141,28 @@ main (int argc, char **argv)
141 if (verbose > 2) 141 if (verbose > 2)
142 printf ("Initializing DBI\n"); 142 printf ("Initializing DBI\n");
143 143
144 if (dbi_initialize (NULL) < 0) { 144 dbi_inst *instance_p;
145
146 if (dbi_initialize_r(NULL, instance_p) < 0) {
145 printf ("UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n"); 147 printf ("UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n");
146 return STATE_UNKNOWN; 148 return STATE_UNKNOWN;
147 } 149 }
148 150
151 if (instance_p == NULL) {
152 printf ("UNKNOWN - failed to initialize DBI.\n");
153 return STATE_UNKNOWN;
154 }
155
149 if (verbose) 156 if (verbose)
150 printf ("Opening DBI driver '%s'\n", np_dbi_driver); 157 printf ("Opening DBI driver '%s'\n", np_dbi_driver);
151 158
152 driver = dbi_driver_open (np_dbi_driver); 159 driver = dbi_driver_open_r(np_dbi_driver, instance_p);
153 if (! driver) { 160 if (! driver) {
154 printf ("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", 161 printf ("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n",
155 np_dbi_driver); 162 np_dbi_driver);
156 163
157 printf ("Known drivers:\n"); 164 printf ("Known drivers:\n");
158 for (driver = dbi_driver_list (NULL); driver; driver = dbi_driver_list (driver)) { 165 for (driver = dbi_driver_list_r(NULL, instance_p); driver; driver = dbi_driver_list_r(driver, instance_p)) {
159 printf (" - %s\n", dbi_driver_get_name (driver)); 166 printf (" - %s\n", dbi_driver_get_name (driver));
160 } 167 }
161 return STATE_UNKNOWN; 168 return STATE_UNKNOWN;
@@ -426,6 +433,7 @@ process_arguments (int argc, char **argv)
426 else 433 else
427 timeout_interval = atoi (optarg); 434 timeout_interval = atoi (optarg);
428 435
436 break;
429 case 'H': /* host */ 437 case 'H': /* host */
430 if (!is_host (optarg)) 438 if (!is_host (optarg))
431 usage2 (_("Invalid hostname/address"), optarg); 439 usage2 (_("Invalid hostname/address"), optarg);
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index c526d05..05e5502 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -112,11 +112,12 @@ enum
112{ 112{
113 SYNC_OPTION = CHAR_MAX + 1, 113 SYNC_OPTION = CHAR_MAX + 1,
114 NO_SYNC_OPTION, 114 NO_SYNC_OPTION,
115 BLOCK_SIZE_OPTION 115 BLOCK_SIZE_OPTION,
116 IGNORE_MISSING
116}; 117};
117 118
118#ifdef _AIX 119#ifdef _AIX
119 #pragma alloca 120#pragma alloca
120#endif 121#endif
121 122
122int process_arguments (int, char **); 123int process_arguments (int, char **);
@@ -126,13 +127,10 @@ int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, ch
126void print_help (void); 127void print_help (void);
127void print_usage (void); 128void print_usage (void);
128double calculate_percent(uintmax_t, uintmax_t); 129double calculate_percent(uintmax_t, uintmax_t);
129void stat_path (struct parameter_list *p); 130bool stat_path (struct parameter_list *p);
130void get_stats (struct parameter_list *p, struct fs_usage *fsp); 131void get_stats (struct parameter_list *p, struct fs_usage *fsp);
131void get_path_stats (struct parameter_list *p, struct fs_usage *fsp); 132void get_path_stats (struct parameter_list *p, struct fs_usage *fsp);
132 133
133double w_dfp = -1.0;
134double c_dfp = -1.0;
135char *path;
136char *exclude_device; 134char *exclude_device;
137char *units; 135char *units;
138uintmax_t mult = 1024 * 1024; 136uintmax_t mult = 1024 * 1024;
@@ -140,6 +138,7 @@ int verbose = 0;
140int erronly = FALSE; 138int erronly = FALSE;
141int display_mntp = FALSE; 139int display_mntp = FALSE;
142int exact_match = FALSE; 140int exact_match = FALSE;
141bool ignore_missing = false;
143int freespace_ignore_reserved = FALSE; 142int freespace_ignore_reserved = FALSE;
144int display_inodes_perfdata = FALSE; 143int display_inodes_perfdata = FALSE;
145char *warn_freespace_units = NULL; 144char *warn_freespace_units = NULL;
@@ -155,6 +154,7 @@ char *crit_usedinodes_percent = NULL;
155char *warn_freeinodes_percent = NULL; 154char *warn_freeinodes_percent = NULL;
156char *crit_freeinodes_percent = NULL; 155char *crit_freeinodes_percent = NULL;
157int path_selected = FALSE; 156int path_selected = FALSE;
157bool path_ignored = false;
158char *group = NULL; 158char *group = NULL;
159struct stat *stat_buf; 159struct stat *stat_buf;
160struct name_list *seen = NULL; 160struct name_list *seen = NULL;
@@ -166,12 +166,13 @@ main (int argc, char **argv)
166 int result = STATE_UNKNOWN; 166 int result = STATE_UNKNOWN;
167 int disk_result = STATE_UNKNOWN; 167 int disk_result = STATE_UNKNOWN;
168 char *output; 168 char *output;
169 char *ignored;
169 char *details; 170 char *details;
170 char *perf; 171 char *perf;
171 char *perf_ilabel; 172 char *perf_ilabel;
172 char *preamble; 173 char *preamble = " - free space:";
174 char *ignored_preamble = " - ignored paths:";
173 char *flag_header; 175 char *flag_header;
174 double inode_space_pct;
175 int temp_result; 176 int temp_result;
176 177
177 struct mount_entry *me; 178 struct mount_entry *me;
@@ -182,8 +183,8 @@ main (int argc, char **argv)
182 char mountdir[32]; 183 char mountdir[32];
183#endif 184#endif
184 185
185 preamble = strdup (" - free space:");
186 output = strdup (""); 186 output = strdup ("");
187 ignored = strdup ("");
187 details = strdup (""); 188 details = strdup ("");
188 perf = strdup (""); 189 perf = strdup ("");
189 perf_ilabel = strdup (""); 190 perf_ilabel = strdup ("");
@@ -204,7 +205,7 @@ main (int argc, char **argv)
204 /* If a list of paths has not been selected, find entire 205 /* If a list of paths has not been selected, find entire
205 mount list and create list of paths 206 mount list and create list of paths
206 */ 207 */
207 if (path_selected == FALSE) { 208 if (path_selected == FALSE && path_ignored == false) {
208 for (me = mount_list; me; me = me->me_next) { 209 for (me = mount_list; me; me = me->me_next) {
209 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) { 210 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
210 path = np_add_parameter(&path_select_list, me->me_mountdir); 211 path = np_add_parameter(&path_select_list, me->me_mountdir);
@@ -214,24 +215,49 @@ main (int argc, char **argv)
214 set_all_thresholds(path); 215 set_all_thresholds(path);
215 } 216 }
216 } 217 }
217 np_set_best_match(path_select_list, mount_list, exact_match); 218
219 if (path_ignored == false) {
220 np_set_best_match(path_select_list, mount_list, exact_match);
221 }
218 222
219 /* Error if no match found for specified paths */ 223 /* Error if no match found for specified paths */
220 temp_list = path_select_list; 224 temp_list = path_select_list;
221 225
222 while (temp_list) { 226 while (path_select_list) {
223 if (! temp_list->best_match) { 227 if (! path_select_list->best_match && ignore_missing == true) {
224 die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name); 228 /* If the first element will be deleted, the temp_list must be updated with the new start address as well */
229 if (path_select_list == temp_list) {
230 temp_list = path_select_list->name_next;
231 }
232 /* Add path argument to list of ignored paths to inform about missing paths being ignored and not alerted */
233 xasprintf (&ignored, "%s %s;", ignored, path_select_list->name);
234 /* Delete the path from the list so that it is not stat-checked later in the code. */
235 path_select_list = np_del_parameter(path_select_list, path_select_list->name_prev);
236 } else if (! path_select_list->best_match) {
237 /* Without --ignore-missing option, exit with Critical state. */
238 die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), path_select_list->name);
239 } else {
240 /* Continue jumping through the list */
241 path_select_list = path_select_list->name_next;
225 } 242 }
243 }
226 244
227 temp_list = temp_list->name_next; 245 path_select_list = temp_list;
246
247 if (! path_select_list && ignore_missing == true) {
248 result = STATE_OK;
249 if (verbose >= 2) {
250 printf ("None of the provided paths were found\n");
251 }
228 } 252 }
229 253
230 /* Process for every path in list */ 254 /* Process for every path in list */
231 for (path = path_select_list; path; path=path->name_next) { 255 for (path = path_select_list; path; path=path->name_next) {
232 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) 256 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL)
233 printf("Thresholds(pct) for %s warn: %f crit %f\n",path->name, path->freespace_percent->warning->end, 257 printf("Thresholds(pct) for %s warn: %f crit %f\n",
234 path->freespace_percent->critical->end); 258 path->name,
259 path->freespace_percent->warning->end,
260 path->freespace_percent->critical->end);
235 261
236 if (verbose >= 3 && path->group != NULL) 262 if (verbose >= 3 && path->group != NULL)
237 printf("Group of %s: %s\n",path->name,path->group); 263 printf("Group of %s: %s\n",path->name,path->group);
@@ -241,6 +267,10 @@ main (int argc, char **argv)
241 267
242 me = path->best_match; 268 me = path->best_match;
243 269
270 if (!me) {
271 continue;
272 }
273
244#ifdef __CYGWIN__ 274#ifdef __CYGWIN__
245 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) 275 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11)
246 continue; 276 continue;
@@ -259,8 +289,12 @@ main (int argc, char **argv)
259 if (path->group == NULL) { 289 if (path->group == NULL) {
260 /* Skip remote filesystems if we're not interested in them */ 290 /* Skip remote filesystems if we're not interested in them */
261 if (me->me_remote && show_local_fs) { 291 if (me->me_remote && show_local_fs) {
262 if (stat_remote_fs) 292 if (stat_remote_fs) {
263 stat_path(path); 293 if (!stat_path(path) && ignore_missing == true) {
294 result = STATE_OK;
295 xasprintf (&ignored, "%s %s;", ignored, path->name);
296 }
297 }
264 continue; 298 continue;
265 /* Skip pseudo fs's if we haven't asked for all fs's */ 299 /* Skip pseudo fs's if we haven't asked for all fs's */
266 } else if (me->me_dummy && !show_all_fs) { 300 } else if (me->me_dummy && !show_all_fs) {
@@ -279,14 +313,20 @@ main (int argc, char **argv)
279 } 313 }
280 } 314 }
281 315
282 stat_path(path); 316 if (!stat_path(path)) {
317 if (ignore_missing == true) {
318 result = STATE_OK;
319 xasprintf (&ignored, "%s %s;", ignored, path->name);
320 }
321 continue;
322 }
283 get_fs_usage (me->me_mountdir, me->me_devname, &fsp); 323 get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
284 324
285 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { 325 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
286 get_stats (path, &fsp); 326 get_stats (path, &fsp);
287 327
288 if (verbose >= 3) { 328 if (verbose >= 3) {
289 printf ("For %s, used_pct=%g free_pct=%g used_units=%llu free_units=%llu total_units=%llu used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%llu mult=%llu\n", 329 printf ("For %s, used_pct=%g free_pct=%g used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%lu mult=%lu\n",
290 me->me_mountdir, 330 me->me_mountdir,
291 path->dused_pct, 331 path->dused_pct,
292 path->dfree_pct, 332 path->dfree_pct,
@@ -367,10 +407,10 @@ main (int argc, char **argv)
367 critical_high_tide = UINT64_MAX; 407 critical_high_tide = UINT64_MAX;
368 408
369 if (path->freeinodes_percent->warning != NULL) { 409 if (path->freeinodes_percent->warning != NULL) {
370 warning_high_tide = llabs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total )); 410 warning_high_tide = (uint64_t) fabs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total ));
371 } 411 }
372 if (path->freeinodes_percent->critical != NULL) { 412 if (path->freeinodes_percent->critical != NULL) {
373 critical_high_tide = llabs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total )); 413 critical_high_tide = (uint64_t) fabs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total ));
374 } 414 }
375 415
376 xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); 416 xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir);
@@ -404,22 +444,18 @@ main (int argc, char **argv)
404 xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : "")); 444 xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : ""));
405 } 445 }
406 free(flag_header); 446 free(flag_header);
407 /* TODO: Need to do a similar debug line
408 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%%"),
409 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
410 me->me_devname, me->me_type, me->me_mountdir,
411 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
412 */
413
414 } 447 }
415
416 } 448 }
417 449
418 if (verbose >= 2) 450 if (verbose >= 2)
419 xasprintf (&output, "%s%s", output, details); 451 xasprintf (&output, "%s%s", output, details);
420 452
453 if (strcmp(output, "") == 0 && ! erronly) {
454 preamble = "";
455 xasprintf (&output, " - No disks were found for provided parameters;");
456 }
421 457
422 printf ("DISK %s%s%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf); 458 printf ("DISK %s%s%s%s%s|%s\n", state_text (result), ((erronly && result==STATE_OK)) ? "" : preamble, output, (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf);
423 return result; 459 return result;
424} 460}
425 461
@@ -488,6 +524,7 @@ process_arguments (int argc, char **argv)
488 {"ignore-ereg-partition", required_argument, 0, 'i'}, 524 {"ignore-ereg-partition", required_argument, 0, 'i'},
489 {"ignore-eregi-path", required_argument, 0, 'I'}, 525 {"ignore-eregi-path", required_argument, 0, 'I'},
490 {"ignore-eregi-partition", required_argument, 0, 'I'}, 526 {"ignore-eregi-partition", required_argument, 0, 'I'},
527 {"ignore-missing", no_argument, 0, IGNORE_MISSING},
491 {"local", no_argument, 0, 'l'}, 528 {"local", no_argument, 0, 'l'},
492 {"stat-remote-fs", no_argument, 0, 'L'}, 529 {"stat-remote-fs", no_argument, 0, 'L'},
493 {"iperfdata", no_argument, 0, 'P'}, 530 {"iperfdata", no_argument, 0, 'P'},
@@ -547,7 +584,7 @@ process_arguments (int argc, char **argv)
547 584
548 /* Awful mistake where the range values do not make sense. Normally, 585 /* Awful mistake where the range values do not make sense. Normally,
549 you alert if the value is within the range, but since we are using 586 you alert if the value is within the range, but since we are using
550 freespace, we have to alert if outside the range. Thus we artifically 587 freespace, we have to alert if outside the range. Thus we artificially
551 force @ at the beginning of the range, so that it is backwards compatible 588 force @ at the beginning of the range, so that it is backwards compatible
552 */ 589 */
553 case 'c': /* critical threshold */ 590 case 'c': /* critical threshold */
@@ -586,21 +623,36 @@ process_arguments (int argc, char **argv)
586 if (! strcasecmp (optarg, "bytes")) { 623 if (! strcasecmp (optarg, "bytes")) {
587 mult = (uintmax_t)1; 624 mult = (uintmax_t)1;
588 units = strdup ("B"); 625 units = strdup ("B");
589 } else if ( (! strcmp (optarg, "kB")) || (!strcmp(optarg, "KiB")) ) { 626 } else if (!strcmp(optarg, "KiB")) {
590 mult = (uintmax_t)1024; 627 mult = (uintmax_t)1024;
591 units = strdup ("kiB"); 628 units = strdup ("KiB");
592 } else if ( (! strcmp (optarg, "MB")) || (!strcmp(optarg, "MiB")) ) { 629 } else if (! strcmp (optarg, "kB")) {
630 mult = (uintmax_t)1000;
631 units = strdup ("kB");
632 } else if (!strcmp(optarg, "MiB")) {
593 mult = (uintmax_t)1024 * 1024; 633 mult = (uintmax_t)1024 * 1024;
594 units = strdup ("MiB"); 634 units = strdup ("MiB");
595 } else if ( (! strcmp (optarg, "GB")) || (!strcmp(optarg, "GiB")) ) { 635 } else if (! strcmp (optarg, "MB")) {
636 mult = (uintmax_t)1000 * 1000;
637 units = strdup ("MB");
638 } else if (!strcmp(optarg, "GiB")) {
596 mult = (uintmax_t)1024 * 1024 * 1024; 639 mult = (uintmax_t)1024 * 1024 * 1024;
597 units = strdup ("GiB"); 640 units = strdup ("GiB");
598 } else if ( (! strcmp (optarg, "TB")) || (!strcmp(optarg, "TiB")) ) { 641 } else if (! strcmp (optarg, "GB")){
642 mult = (uintmax_t)1000 * 1000 * 1000;
643 units = strdup ("GB");
644 } else if (!strcmp(optarg, "TiB")) {
599 mult = (uintmax_t)1024 * 1024 * 1024 * 1024; 645 mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
600 units = strdup ("TiB"); 646 units = strdup ("TiB");
601 } else if ( (! strcmp (optarg, "PB")) || (!strcmp(optarg, "PiB")) ) { 647 } else if (! strcmp (optarg, "TB")) {
648 mult = (uintmax_t)1000 * 1000 * 1000 * 1000;
649 units = strdup ("TB");
650 } else if (!strcmp(optarg, "PiB")) {
602 mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024; 651 mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024;
603 units = strdup ("PiB"); 652 units = strdup ("PiB");
653 } else if (! strcmp (optarg, "PB")){
654 mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000;
655 units = strdup ("PB");
604 } else { 656 } else {
605 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg); 657 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
606 } 658 }
@@ -639,12 +691,19 @@ process_arguments (int argc, char **argv)
639 /* add parameter if not found. overwrite thresholds if path has already been added */ 691 /* add parameter if not found. overwrite thresholds if path has already been added */
640 if (! (se = np_find_parameter(path_select_list, optarg))) { 692 if (! (se = np_find_parameter(path_select_list, optarg))) {
641 se = np_add_parameter(&path_select_list, optarg); 693 se = np_add_parameter(&path_select_list, optarg);
694
695 if (stat(optarg, &stat_buf[0]) && ignore_missing == true) {
696 path_ignored = true;
697 break;
698 }
642 } 699 }
643 se->group = group; 700 se->group = group;
644 set_all_thresholds(se); 701 set_all_thresholds(se);
645 702
646 /* With autofs, it is required to stat() the path before re-populating the mount_list */ 703 /* With autofs, it is required to stat() the path before re-populating the mount_list */
647 stat_path(se); 704 if (!stat_path(se)) {
705 break;
706 }
648 /* NB: We can't free the old mount_list "just like that": both list pointers and struct 707 /* NB: We can't free the old mount_list "just like that": both list pointers and struct
649 * pointers are copied around. One of the reason it wasn't done yet is that other parts 708 * pointers are copied around. One of the reason it wasn't done yet is that other parts
650 * of check_disk need the same kind of cleanup so it'd better be done as a whole */ 709 * of check_disk need the same kind of cleanup so it'd better be done as a whole */
@@ -687,6 +746,7 @@ process_arguments (int argc, char **argv)
687 break; 746 break;
688 case 'I': 747 case 'I':
689 cflags |= REG_ICASE; 748 cflags |= REG_ICASE;
749 // Intentional fallthrough
690 case 'i': 750 case 'i':
691 if (!path_selected) 751 if (!path_selected)
692 die (STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); 752 die (STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly"));
@@ -724,10 +784,15 @@ process_arguments (int argc, char **argv)
724 cflags = default_cflags; 784 cflags = default_cflags;
725 break; 785 break;
726 786
787 case IGNORE_MISSING:
788 ignore_missing = true;
789 break;
727 case 'A': 790 case 'A':
728 optarg = strdup(".*"); 791 optarg = strdup(".*");
792 // Intentional fallthrough
729 case 'R': 793 case 'R':
730 cflags |= REG_ICASE; 794 cflags |= REG_ICASE;
795 // Intentional fallthrough
731 case 'r': 796 case 'r':
732 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 797 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
733 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 798 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
@@ -757,7 +822,11 @@ process_arguments (int argc, char **argv)
757 } 822 }
758 } 823 }
759 824
760 if (!fnd) 825 if (!fnd && ignore_missing == true) {
826 path_ignored = true;
827 /* path_selected = TRUE;*/
828 break;
829 } else if (!fnd)
761 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), 830 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"),
762 _("Regular expression did not match any path or disk"), optarg); 831 _("Regular expression did not match any path or disk"), optarg);
763 832
@@ -817,7 +886,7 @@ process_arguments (int argc, char **argv)
817 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c])) 886 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
818 crit_usedspace_percent = argv[c++]; 887 crit_usedspace_percent = argv[c++];
819 888
820 if (argc > c && path == NULL) { 889 if (argc > c) {
821 se = np_add_parameter(&path_select_list, strdup(argv[c++])); 890 se = np_add_parameter(&path_select_list, strdup(argv[c++]));
822 path_selected = TRUE; 891 path_selected = TRUE;
823 set_all_thresholds(se); 892 set_all_thresholds(se);
@@ -860,51 +929,6 @@ set_all_thresholds (struct parameter_list *path)
860 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); 929 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
861} 930}
862 931
863/* TODO: Remove?
864
865int
866validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
867{
868 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
869 printf (_("INPUT ERROR: No thresholds specified"));
870 print_path (mypath);
871 return ERROR;
872 }
873 else if ((wp >= 0.0 || cp >= 0.0) &&
874 (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
875 printf (_("\
876INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
877 cp, wp);
878 print_path (mypath);
879 return ERROR;
880 }
881 else if ((iwp >= 0.0 || icp >= 0.0) &&
882 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
883 printf (_("\
884INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
885 icp, iwp);
886 print_path (mypath);
887 return ERROR;
888 }
889 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
890 printf (_("\
891INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
892 (unsigned long)c, (unsigned long)w);
893 print_path (mypath);
894 return ERROR;
895 }
896
897 return OK;
898}
899
900*/
901
902
903
904
905
906
907
908void 932void
909print_help (void) 933print_help (void)
910{ 934{
@@ -959,7 +983,7 @@ print_help (void)
959 printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); 983 printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems"));
960 printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); 984 printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)"));
961 printf (" %s\n", "-M, --mountpoint"); 985 printf (" %s\n", "-M, --mountpoint");
962 printf (" %s\n", _("Display the mountpoint instead of the partition")); 986 printf (" %s\n", _("Display the (block) device instead of the mount point"));
963 printf (" %s\n", "-m, --megabytes"); 987 printf (" %s\n", "-m, --megabytes");
964 printf (" %s\n", _("Same as '--units MB'")); 988 printf (" %s\n", _("Same as '--units MB'"));
965 printf (" %s\n", "-A, --all"); 989 printf (" %s\n", "-A, --all");
@@ -972,6 +996,9 @@ print_help (void)
972 printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); 996 printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)"));
973 printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); 997 printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION");
974 printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); 998 printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)"));
999 printf (" %s\n", "--ignore-missing");
1000 printf (" %s\n", _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible."));
1001 printf (" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)"));
975 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1002 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
976 printf (" %s\n", "-u, --units=STRING"); 1003 printf (" %s\n", "-u, --units=STRING");
977 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); 1004 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
@@ -1000,12 +1027,12 @@ void
1000print_usage (void) 1027print_usage (void)
1001{ 1028{
1002 printf ("%s\n", _("Usage:")); 1029 printf ("%s\n", _("Usage:"));
1003 printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname); 1030 printf (" %s {-w absolute_limit |-w percentage_limit% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit% | -K inode_percentage_limit } {-p path | -x device}\n", progname);
1004 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); 1031 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
1005 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); 1032 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n");
1006} 1033}
1007 1034
1008void 1035bool
1009stat_path (struct parameter_list *p) 1036stat_path (struct parameter_list *p)
1010{ 1037{
1011 /* Stat entry to check that dir exists and is accessible */ 1038 /* Stat entry to check that dir exists and is accessible */
@@ -1014,9 +1041,14 @@ stat_path (struct parameter_list *p)
1014 if (stat (p->name, &stat_buf[0])) { 1041 if (stat (p->name, &stat_buf[0])) {
1015 if (verbose >= 3) 1042 if (verbose >= 3)
1016 printf("stat failed on %s\n", p->name); 1043 printf("stat failed on %s\n", p->name);
1017 printf("DISK %s - ", _("CRITICAL")); 1044 if (ignore_missing == true) {
1018 die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); 1045 return false;
1046 } else {
1047 printf("DISK %s - ", _("CRITICAL"));
1048 die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno));
1049 }
1019 } 1050 }
1051 return true;
1020} 1052}
1021 1053
1022 1054
@@ -1036,13 +1068,20 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
1036 continue; 1068 continue;
1037#endif 1069#endif
1038 if (p_list->group && ! (strcmp(p_list->group, p->group))) { 1070 if (p_list->group && ! (strcmp(p_list->group, p->group))) {
1039 stat_path(p_list); 1071 if (! stat_path(p_list))
1072 continue;
1040 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); 1073 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
1041 get_path_stats(p_list, &tmpfsp); 1074 get_path_stats(p_list, &tmpfsp);
1042 if (verbose >= 3) 1075 if (verbose >= 3)
1043 printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", 1076 printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n",
1044 p_list->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, p_list->dfree_units, 1077 p_list->group,
1045 p_list->dtotal_units, mult); 1078 tmpfsp.fsu_blocks,
1079 tmpfsp.fsu_blocksize,
1080 p_list->best_match->me_mountdir,
1081 p_list->dused_units,
1082 p_list->dfree_units,
1083 p_list->dtotal_units,
1084 mult);
1046 1085
1047 /* prevent counting the first FS of a group twice since its parameter_list entry 1086 /* prevent counting the first FS of a group twice since its parameter_list entry
1048 * is used to carry the information of all file systems of the entire group */ 1087 * is used to carry the information of all file systems of the entire group */
@@ -1063,14 +1102,12 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
1063 first = 0; 1102 first = 0;
1064 } 1103 }
1065 if (verbose >= 3) 1104 if (verbose >= 3)
1066 printf("Group %s now has: used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", 1105 printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n",
1067 p->group, 1106 p->group,
1068 tmpfsp.fsu_bavail,
1069 tmpfsp.fsu_blocksize,
1070 p->best_match->me_mountdir,
1071 p->dused_units, 1107 p->dused_units,
1072 p->dfree_units, 1108 p->dfree_units,
1073 p->dtotal_units, 1109 p->dtotal_units,
1110 tmpfsp.fsu_blocksize,
1074 mult); 1111 mult);
1075 } 1112 }
1076 /* modify devname and mountdir for output */ 1113 /* modify devname and mountdir for output */
@@ -1090,7 +1127,7 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1090 p->available_to_root = fsp->fsu_bfree; 1127 p->available_to_root = fsp->fsu_bfree;
1091 p->used = fsp->fsu_blocks - fsp->fsu_bfree; 1128 p->used = fsp->fsu_blocks - fsp->fsu_bfree;
1092 if (freespace_ignore_reserved) { 1129 if (freespace_ignore_reserved) {
1093 /* option activated : we substract the root-reserved space from the total */ 1130 /* option activated : we subtract the root-reserved space from the total */
1094 p->total = fsp->fsu_blocks - p->available_to_root + p->available; 1131 p->total = fsp->fsu_blocks - p->available_to_root + p->available;
1095 } else { 1132 } else {
1096 /* default behaviour : take all the blocks into account */ 1133 /* default behaviour : take all the blocks into account */
@@ -1101,11 +1138,11 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1101 p->dfree_units = p->available*fsp->fsu_blocksize/mult; 1138 p->dfree_units = p->available*fsp->fsu_blocksize/mult;
1102 p->dtotal_units = p->total*fsp->fsu_blocksize/mult; 1139 p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
1103 /* Free file nodes. Not sure the workaround is required, but in case...*/ 1140 /* Free file nodes. Not sure the workaround is required, but in case...*/
1104 p->inodes_free = fsp->fsu_favail > fsp->fsu_ffree ? 0 : fsp->fsu_favail; 1141 p->inodes_free = fsp->fsu_ffree;
1105 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ 1142 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */
1106 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; 1143 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree;
1107 if (freespace_ignore_reserved) { 1144 if (freespace_ignore_reserved) {
1108 /* option activated : we substract the root-reserved inodes from the total */ 1145 /* option activated : we subtract the root-reserved inodes from the total */
1109 /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ 1146 /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */
1110 /* for others, fsp->fsu_ffree == fsp->fsu_favail */ 1147 /* for others, fsp->fsu_ffree == fsp->fsu_favail */
1111 p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free; 1148 p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free;
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index 9de6caf..7ffce98 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -75,7 +75,7 @@ main (int argc, char **argv)
75{ 75{
76 char *command_line = NULL; 76 char *command_line = NULL;
77 char input_buffer[MAX_INPUT_BUFFER]; 77 char input_buffer[MAX_INPUT_BUFFER];
78 char *address = NULL; /* comma seperated str with addrs/ptrs (sorted) */ 78 char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */
79 char **addresses = NULL; 79 char **addresses = NULL;
80 int n_addresses = 0; 80 int n_addresses = 0;
81 char *msg = NULL; 81 char *msg = NULL;
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index 521d0fe..23a9e99 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -37,6 +37,7 @@ const char *email = "devel@monitoring-plugins.org";
37#include "popen.h" 37#include "popen.h"
38#include "netutils.h" 38#include "netutils.h"
39#include "utils.h" 39#include "utils.h"
40#include <stdbool.h>
40 41
41enum { 42enum {
42 PACKET_COUNT = 1, 43 PACKET_COUNT = 1,
@@ -65,13 +66,14 @@ double crta;
65double wrta; 66double wrta;
66int cpl_p = FALSE; 67int cpl_p = FALSE;
67int wpl_p = FALSE; 68int wpl_p = FALSE;
69bool alive_p = FALSE;
68int crta_p = FALSE; 70int crta_p = FALSE;
69int wrta_p = FALSE; 71int wrta_p = FALSE;
70 72
71int 73int
72main (int argc, char **argv) 74main (int argc, char **argv)
73{ 75{
74/* normaly should be int result = STATE_UNKNOWN; */ 76/* normally should be int result = STATE_UNKNOWN; */
75 77
76 int status = STATE_UNKNOWN; 78 int status = STATE_UNKNOWN;
77 int result = 0; 79 int result = 0;
@@ -147,9 +149,11 @@ main (int argc, char **argv)
147 (void) fclose (child_stderr); 149 (void) fclose (child_stderr);
148 150
149 /* close the pipe */ 151 /* close the pipe */
150 if (result = spclose (child_process)) 152 result = spclose (child_process);
153 if (result) {
151 /* need to use max_state not max */ 154 /* need to use max_state not max */
152 status = max_state (status, STATE_WARNING); 155 status = max_state (status, STATE_WARNING);
156 }
153 157
154 if (result > 1 ) { 158 if (result > 1 ) {
155 status = max_state (status, STATE_UNKNOWN); 159 status = max_state (status, STATE_UNKNOWN);
@@ -171,10 +175,7 @@ main (int argc, char **argv)
171} 175}
172 176
173 177
174 178int textscan (char *buf) {
175int
176textscan (char *buf)
177{
178 char *rtastr = NULL; 179 char *rtastr = NULL;
179 char *losstr = NULL; 180 char *losstr = NULL;
180 char *xmtstr = NULL; 181 char *xmtstr = NULL;
@@ -183,6 +184,20 @@ textscan (char *buf)
183 double xmt; 184 double xmt;
184 int status = STATE_UNKNOWN; 185 int status = STATE_UNKNOWN;
185 186
187 /* stops testing after the first successful reply. */
188 if (alive_p && strstr(buf, "avg, 0% loss)")) {
189 rtastr = strstr (buf, "ms (");
190 rtastr = 1 + index(rtastr, '(');
191 rta = strtod(rtastr, NULL);
192 loss=strtod("0",NULL);
193 die (STATE_OK,
194 _("FPING %s - %s (rta=%f ms)|%s\n"),
195 state_text (STATE_OK), server_name,rta,
196 /* No loss since we only waited for the first reply
197 perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, TRUE, 0, TRUE, 100), */
198 fperfdata ("rta", rta/1.0e3, "s", wrta_p, wrta/1.0e3, crta_p, crta/1.0e3, TRUE, 0, FALSE, 0));
199 }
200
186 if (strstr (buf, "not found")) { 201 if (strstr (buf, "not found")) {
187 die (STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name); 202 die (STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name);
188 203
@@ -278,6 +293,7 @@ process_arguments (int argc, char **argv)
278 {"sourceif", required_argument, 0, 'I'}, 293 {"sourceif", required_argument, 0, 'I'},
279 {"critical", required_argument, 0, 'c'}, 294 {"critical", required_argument, 0, 'c'},
280 {"warning", required_argument, 0, 'w'}, 295 {"warning", required_argument, 0, 'w'},
296 {"alive", no_argument, 0, 'a'},
281 {"bytes", required_argument, 0, 'b'}, 297 {"bytes", required_argument, 0, 'b'},
282 {"number", required_argument, 0, 'n'}, 298 {"number", required_argument, 0, 'n'},
283 {"target-timeout", required_argument, 0, 'T'}, 299 {"target-timeout", required_argument, 0, 'T'},
@@ -304,7 +320,7 @@ process_arguments (int argc, char **argv)
304 } 320 }
305 321
306 while (1) { 322 while (1) {
307 c = getopt_long (argc, argv, "+hVvH:S:c:w:b:n:T:i:I:46", longopts, &option); 323 c = getopt_long (argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:46", longopts, &option);
308 324
309 if (c == -1 || c == EOF || c == 1) 325 if (c == -1 || c == EOF || c == 1)
310 break; 326 break;
@@ -312,6 +328,9 @@ process_arguments (int argc, char **argv)
312 switch (c) { 328 switch (c) {
313 case '?': /* print short usage statement if args not parsable */ 329 case '?': /* print short usage statement if args not parsable */
314 usage5 (); 330 usage5 ();
331 case 'a': /* host alive mode */
332 alive_p = TRUE;
333 break;
315 case 'h': /* help */ 334 case 'h': /* help */
316 print_help (); 335 print_help ();
317 exit (STATE_UNKNOWN); 336 exit (STATE_UNKNOWN);
@@ -335,6 +354,7 @@ process_arguments (int argc, char **argv)
335 break; 354 break;
336 case 'I': /* sourceip */ 355 case 'I': /* sourceip */
337 sourceif = strscpy (sourceif, optarg); 356 sourceif = strscpy (sourceif, optarg);
357 break;
338 case '4': /* IPv4 only */ 358 case '4': /* IPv4 only */
339 address_family = AF_INET; 359 address_family = AF_INET;
340 break; 360 break;
@@ -446,9 +466,7 @@ get_threshold (char *arg, char *rv[2])
446} 466}
447 467
448 468
449void 469void print_help (void) {
450print_help (void)
451{
452 470
453 print_revision (progname, NP_VERSION); 471 print_revision (progname, NP_VERSION);
454 472
@@ -474,6 +492,8 @@ print_help (void)
474 printf (" %s\n", _("warning threshold pair")); 492 printf (" %s\n", _("warning threshold pair"));
475 printf (" %s\n", "-c, --critical=THRESHOLD"); 493 printf (" %s\n", "-c, --critical=THRESHOLD");
476 printf (" %s\n", _("critical threshold pair")); 494 printf (" %s\n", _("critical threshold pair"));
495 printf (" %s\n", "-a, --alive");
496 printf (" %s\n", _("Return OK after first successful reply"));
477 printf (" %s\n", "-b, --bytes=INTEGER"); 497 printf (" %s\n", "-b, --bytes=INTEGER");
478 printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE); 498 printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE);
479 printf (" %s\n", "-n, --number=INTEGER"); 499 printf (" %s\n", "-n, --number=INTEGER");
diff --git a/plugins/check_game.c b/plugins/check_game.c
index 709dae1..a534b69 100644
--- a/plugins/check_game.c
+++ b/plugins/check_game.c
@@ -318,7 +318,7 @@ print_help (void)
318 printf ("%s\n", _("Notes:")); 318 printf ("%s\n", _("Notes:"));
319 printf (" %s\n", _("This plugin uses the 'qstat' command, the popular game server status query tool.")); 319 printf (" %s\n", _("This plugin uses the 'qstat' command, the popular game server status query tool."));
320 printf (" %s\n", _("If you don't have the package installed, you will need to download it from")); 320 printf (" %s\n", _("If you don't have the package installed, you will need to download it from"));
321 printf (" %s\n", _("http://www.activesw.com/people/steve/qstat.html before you can use this plugin.")); 321 printf (" %s\n", _("https://github.com/multiplay/qstat before you can use this plugin."));
322 322
323 printf (UT_SUPPORT); 323 printf (UT_SUPPORT);
324} 324}
diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c
index 6546556..c34bb08 100644
--- a/plugins/check_hpjd.c
+++ b/plugins/check_hpjd.c
@@ -66,7 +66,7 @@ void print_usage (void);
66 66
67char *community = NULL; 67char *community = NULL;
68char *address = NULL; 68char *address = NULL;
69char *port = NULL; 69unsigned int port = 0;
70int check_paper_out = 1; 70int check_paper_out = 1;
71 71
72int 72int
@@ -121,8 +121,12 @@ main (int argc, char **argv)
121 HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); 121 HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY);
122 122
123 /* get the command to run */ 123 /* get the command to run */
124 sprintf (command_line, "%s -OQa -m : -v 1 -c %s %s:%hd %s", PATH_TO_SNMPGET, community, 124 sprintf (command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s",
125 address, port, query_string); 125 PATH_TO_SNMPGET,
126 community,
127 address,
128 port,
129 query_string);
126 130
127 /* run the command */ 131 /* run the command */
128 child_process = spopen (command_line); 132 child_process = spopen (command_line);
@@ -349,6 +353,7 @@ process_arguments (int argc, char **argv)
349 usage2 (_("Port must be a positive short integer"), optarg); 353 usage2 (_("Port must be a positive short integer"), optarg);
350 else 354 else
351 port = atoi(optarg); 355 port = atoi(optarg);
356 break;
352 case 'D': /* disable paper out check*/ 357 case 'D': /* disable paper out check*/
353 check_paper_out = 0; 358 check_paper_out = 0;
354 break; 359 break;
@@ -380,11 +385,8 @@ process_arguments (int argc, char **argv)
380 community = strdup (DEFAULT_COMMUNITY); 385 community = strdup (DEFAULT_COMMUNITY);
381 } 386 }
382 387
383 if (port == NULL) { 388 if (port == 0) {
384 if (argv[c] != NULL ) 389 port = atoi(DEFAULT_PORT);
385 port = argv[c];
386 else
387 port = atoi (DEFAULT_PORT);
388 } 390 }
389 391
390 return validate_arguments (); 392 return validate_arguments ();
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 34fb4f0..718c8ee 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -31,13 +31,14 @@
31* 31*
32*****************************************************************************/ 32*****************************************************************************/
33 33
34/* splint -I. -I../../plugins -I../../lib/ -I/usr/kerberos/include/ ../../plugins/check_http.c */
35
36const char *progname = "check_http"; 34const char *progname = "check_http";
37const char *copyright = "1999-2013"; 35const char *copyright = "1999-2022";
38const char *email = "devel@monitoring-plugins.org"; 36const char *email = "devel@monitoring-plugins.org";
39 37
38// Do NOT sort those headers, it will break the build
39// TODO: Fix this
40#include "common.h" 40#include "common.h"
41#include "base64.h"
41#include "netutils.h" 42#include "netutils.h"
42#include "utils.h" 43#include "utils.h"
43#include "base64.h" 44#include "base64.h"
@@ -52,11 +53,13 @@ enum {
52 MAX_IPV4_HOSTLENGTH = 255, 53 MAX_IPV4_HOSTLENGTH = 255,
53 HTTP_PORT = 80, 54 HTTP_PORT = 80,
54 HTTPS_PORT = 443, 55 HTTPS_PORT = 443,
55 MAX_PORT = 65535 56 MAX_PORT = 65535,
57 DEFAULT_MAX_REDIRS = 15
56}; 58};
57 59
58#ifdef HAVE_SSL 60#ifdef HAVE_SSL
59int check_cert = FALSE; 61bool check_cert = false;
62bool continue_after_check_cert = false;
60int ssl_version = 0; 63int ssl_version = 0;
61int days_till_exp_warn, days_till_exp_crit; 64int days_till_exp_warn, days_till_exp_crit;
62char *randbuff; 65char *randbuff;
@@ -67,7 +70,7 @@ X509 *server_cert;
67# define my_recv(buf, len) read(sd, buf, len) 70# define my_recv(buf, len) read(sd, buf, len)
68# define my_send(buf, len) send(sd, buf, len, 0) 71# define my_send(buf, len) send(sd, buf, len, 0)
69#endif /* HAVE_SSL */ 72#endif /* HAVE_SSL */
70int no_body = FALSE; 73bool no_body = false;
71int maximum_age = -1; 74int maximum_age = -1;
72 75
73enum { 76enum {
@@ -89,7 +92,7 @@ struct timeval tv_temp;
89#define HTTP_URL "/" 92#define HTTP_URL "/"
90#define CRLF "\r\n" 93#define CRLF "\r\n"
91 94
92int specify_port = FALSE; 95bool specify_port = false;
93int server_port = HTTP_PORT; 96int server_port = HTTP_PORT;
94int virtual_port = 0; 97int virtual_port = 0;
95char server_port_text[6] = ""; 98char server_port_text[6] = "";
@@ -104,28 +107,26 @@ int server_expect_yn = 0;
104char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; 107char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
105char header_expect[MAX_INPUT_BUFFER] = ""; 108char header_expect[MAX_INPUT_BUFFER] = "";
106char string_expect[MAX_INPUT_BUFFER] = ""; 109char string_expect[MAX_INPUT_BUFFER] = "";
107char output_header_search[30] = "";
108char output_string_search[30] = "";
109char *warning_thresholds = NULL; 110char *warning_thresholds = NULL;
110char *critical_thresholds = NULL; 111char *critical_thresholds = NULL;
111thresholds *thlds; 112thresholds *thlds;
112char user_auth[MAX_INPUT_BUFFER] = ""; 113char user_auth[MAX_INPUT_BUFFER] = "";
113char proxy_auth[MAX_INPUT_BUFFER] = ""; 114char proxy_auth[MAX_INPUT_BUFFER] = "";
114int display_html = FALSE; 115bool display_html = false;
115char **http_opt_headers; 116char **http_opt_headers;
116int http_opt_headers_count = 0; 117int http_opt_headers_count = 0;
117int onredirect = STATE_OK; 118int onredirect = STATE_OK;
118int followsticky = STICKY_NONE; 119int followsticky = STICKY_NONE;
119int use_ssl = FALSE; 120bool use_ssl = false;
120int use_sni = FALSE; 121bool use_sni = false;
121int verbose = FALSE; 122bool verbose = false;
122int show_extended_perfdata = FALSE; 123bool show_extended_perfdata = false;
123int show_body = FALSE; 124bool show_body = false;
124int sd; 125int sd;
125int min_page_len = 0; 126int min_page_len = 0;
126int max_page_len = 0; 127int max_page_len = 0;
127int redir_depth = 0; 128int redir_depth = 0;
128int max_depth = 15; 129int max_depth = DEFAULT_MAX_REDIRS;
129char *http_method; 130char *http_method;
130char *http_method_proxy; 131char *http_method_proxy;
131char *http_post_data; 132char *http_post_data;
@@ -134,10 +135,11 @@ char buffer[MAX_INPUT_BUFFER];
134char *client_cert = NULL; 135char *client_cert = NULL;
135char *client_privkey = NULL; 136char *client_privkey = NULL;
136 137
137int process_arguments (int, char **); 138// Forward function declarations
139bool process_arguments (int, char **);
138int check_http (void); 140int check_http (void);
139void redir (char *pos, char *status_line); 141void redir (char *pos, char *status_line);
140int server_type_check(const char *type); 142bool server_type_check(const char *type);
141int server_port_check(int ssl_flag); 143int server_port_check(int ssl_flag);
142char *perfd_time (double microsec); 144char *perfd_time (double microsec);
143char *perfd_time_connect (double microsec); 145char *perfd_time_connect (double microsec);
@@ -148,6 +150,7 @@ char *perfd_time_transfer (double microsec);
148char *perfd_size (int page_len); 150char *perfd_size (int page_len);
149void print_help (void); 151void print_help (void);
150void print_usage (void); 152void print_usage (void);
153char *unchunk_content(const char *content);
151 154
152int 155int
153main (int argc, char **argv) 156main (int argc, char **argv)
@@ -167,10 +170,10 @@ main (int argc, char **argv)
167 /* Parse extra opts if any */ 170 /* Parse extra opts if any */
168 argv=np_extra_opts (&argc, argv, progname); 171 argv=np_extra_opts (&argc, argv, progname);
169 172
170 if (process_arguments (argc, argv) == ERROR) 173 if (process_arguments (argc, argv) == false)
171 usage4 (_("Could not parse arguments")); 174 usage4 (_("Could not parse arguments"));
172 175
173 if (display_html == TRUE) 176 if (display_html == true)
174 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", 177 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">",
175 use_ssl ? "https" : "http", host_name ? host_name : server_address, 178 use_ssl ? "https" : "http", host_name ? host_name : server_address,
176 server_port, server_url); 179 server_port, server_url);
@@ -193,9 +196,11 @@ test_file (char *path)
193 usage2 (_("file does not exist or is not readable"), path); 196 usage2 (_("file does not exist or is not readable"), path);
194} 197}
195 198
196/* process command-line arguments */ 199/*
197int 200 * process command-line arguments
198process_arguments (int argc, char **argv) 201 * returns true on success, false otherwise
202 */
203bool process_arguments (int argc, char **argv)
199{ 204{
200 int c = 1; 205 int c = 1;
201 char *p; 206 char *p;
@@ -203,7 +208,9 @@ process_arguments (int argc, char **argv)
203 208
204 enum { 209 enum {
205 INVERT_REGEX = CHAR_MAX + 1, 210 INVERT_REGEX = CHAR_MAX + 1,
206 SNI_OPTION 211 SNI_OPTION,
212 MAX_REDIRS_OPTION,
213 CONTINUE_AFTER_CHECK_CERT
207 }; 214 };
208 215
209 int option = 0; 216 int option = 0;
@@ -231,6 +238,7 @@ process_arguments (int argc, char **argv)
231 {"certificate", required_argument, 0, 'C'}, 238 {"certificate", required_argument, 0, 'C'},
232 {"client-cert", required_argument, 0, 'J'}, 239 {"client-cert", required_argument, 0, 'J'},
233 {"private-key", required_argument, 0, 'K'}, 240 {"private-key", required_argument, 0, 'K'},
241 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
234 {"useragent", required_argument, 0, 'A'}, 242 {"useragent", required_argument, 0, 'A'},
235 {"header", required_argument, 0, 'k'}, 243 {"header", required_argument, 0, 'k'},
236 {"no-body", no_argument, 0, 'N'}, 244 {"no-body", no_argument, 0, 'N'},
@@ -242,11 +250,12 @@ process_arguments (int argc, char **argv)
242 {"use-ipv6", no_argument, 0, '6'}, 250 {"use-ipv6", no_argument, 0, '6'},
243 {"extended-perfdata", no_argument, 0, 'E'}, 251 {"extended-perfdata", no_argument, 0, 'E'},
244 {"show-body", no_argument, 0, 'B'}, 252 {"show-body", no_argument, 0, 'B'},
253 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
245 {0, 0, 0, 0} 254 {0, 0, 0, 0}
246 }; 255 };
247 256
248 if (argc < 2) 257 if (argc < 2)
249 return ERROR; 258 return false;
250 259
251 for (c = 1; c < argc; c++) { 260 for (c = 1; c < argc; c++) {
252 if (strcmp ("-to", argv[c]) == 0) 261 if (strcmp ("-to", argv[c]) == 0)
@@ -302,10 +311,10 @@ process_arguments (int argc, char **argv)
302 /* xasprintf (&http_opt_headers, "%s", optarg); */ 311 /* xasprintf (&http_opt_headers, "%s", optarg); */
303 break; 312 break;
304 case 'L': /* show html link */ 313 case 'L': /* show html link */
305 display_html = TRUE; 314 display_html = true;
306 break; 315 break;
307 case 'n': /* do not show html link */ 316 case 'n': /* do not show html link */
308 display_html = FALSE; 317 display_html = false;
309 break; 318 break;
310 case 'C': /* Check SSL cert validity */ 319 case 'C': /* Check SSL cert validity */
311#ifdef HAVE_SSL 320#ifdef HAVE_SSL
@@ -326,9 +335,14 @@ process_arguments (int argc, char **argv)
326 usage2 (_("Invalid certificate expiration period"), optarg); 335 usage2 (_("Invalid certificate expiration period"), optarg);
327 days_till_exp_warn = atoi (optarg); 336 days_till_exp_warn = atoi (optarg);
328 } 337 }
329 check_cert = TRUE; 338 check_cert = true;
330 goto enable_ssl; 339 goto enable_ssl;
331#endif 340#endif
341 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
342#ifdef HAVE_SSL
343 continue_after_check_cert = true;
344 break;
345#endif
332 case 'J': /* use client certificate */ 346 case 'J': /* use client certificate */
333#ifdef HAVE_SSL 347#ifdef HAVE_SSL
334 test_file(optarg); 348 test_file(optarg);
@@ -346,7 +360,7 @@ process_arguments (int argc, char **argv)
346 enable_ssl: 360 enable_ssl:
347 /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps when we include multiple 361 /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps when we include multiple
348 parameters, like -S and -C combinations */ 362 parameters, like -S and -C combinations */
349 use_ssl = TRUE; 363 use_ssl = true;
350 if (c=='S' && optarg != NULL) { 364 if (c=='S' && optarg != NULL) {
351 int got_plus = strchr(optarg, '+') != NULL; 365 int got_plus = strchr(optarg, '+') != NULL;
352 366
@@ -363,7 +377,7 @@ process_arguments (int argc, char **argv)
363 else 377 else
364 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); 378 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)"));
365 } 379 }
366 if (specify_port == FALSE) 380 if (specify_port == false)
367 server_port = HTTPS_PORT; 381 server_port = HTTPS_PORT;
368#else 382#else
369 /* -C -J and -K fall through to here without SSL */ 383 /* -C -J and -K fall through to here without SSL */
@@ -371,8 +385,15 @@ process_arguments (int argc, char **argv)
371#endif 385#endif
372 break; 386 break;
373 case SNI_OPTION: 387 case SNI_OPTION:
374 use_sni = TRUE; 388 use_sni = true;
375 break; 389 break;
390 case MAX_REDIRS_OPTION:
391 if (!is_intnonneg (optarg))
392 usage2 (_("Invalid max_redirs count"), optarg);
393 else {
394 max_depth = atoi (optarg);
395 }
396 break;
376 case 'f': /* onredirect */ 397 case 'f': /* onredirect */
377 if (!strcmp (optarg, "stickyport")) 398 if (!strcmp (optarg, "stickyport"))
378 onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT; 399 onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT;
@@ -402,7 +423,7 @@ process_arguments (int argc, char **argv)
402 host_name_length = strlen (host_name) - strlen (p) - 1; 423 host_name_length = strlen (host_name) - strlen (p) - 1;
403 free (host_name); 424 free (host_name);
404 host_name = strndup (optarg, host_name_length); 425 host_name = strndup (optarg, host_name_length);
405 if (specify_port == FALSE) 426 if (specify_port == false)
406 server_port = virtual_port; 427 server_port = virtual_port;
407 } 428 }
408 } else if ((p = strchr (host_name, ':')) != NULL 429 } else if ((p = strchr (host_name, ':')) != NULL
@@ -412,7 +433,7 @@ process_arguments (int argc, char **argv)
412 host_name_length = strlen (host_name) - strlen (p) - 1; 433 host_name_length = strlen (host_name) - strlen (p) - 1;
413 free (host_name); 434 free (host_name);
414 host_name = strndup (optarg, host_name_length); 435 host_name = strndup (optarg, host_name_length);
415 if (specify_port == FALSE) 436 if (specify_port == false)
416 server_port = virtual_port; 437 server_port = virtual_port;
417 } 438 }
418 break; 439 break;
@@ -428,7 +449,7 @@ process_arguments (int argc, char **argv)
428 usage2 (_("Invalid port number"), optarg); 449 usage2 (_("Invalid port number"), optarg);
429 else { 450 else {
430 server_port = atoi (optarg); 451 server_port = atoi (optarg);
431 specify_port = TRUE; 452 specify_port = true;
432 } 453 }
433 break; 454 break;
434 case 'a': /* authorization info */ 455 case 'a': /* authorization info */
@@ -477,6 +498,7 @@ process_arguments (int argc, char **argv)
477 break; 498 break;
478 case 'R': /* regex */ 499 case 'R': /* regex */
479 cflags |= REG_ICASE; 500 cflags |= REG_ICASE;
501 // fall through
480 case 'r': /* regex */ 502 case 'r': /* regex */
481 strncpy (regexp, optarg, MAX_RE_SIZE - 1); 503 strncpy (regexp, optarg, MAX_RE_SIZE - 1);
482 regexp[MAX_RE_SIZE - 1] = 0; 504 regexp[MAX_RE_SIZE - 1] = 0;
@@ -484,7 +506,7 @@ process_arguments (int argc, char **argv)
484 if (errcode != 0) { 506 if (errcode != 0) {
485 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 507 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
486 printf (_("Could Not Compile Regular Expression: %s"), errbuf); 508 printf (_("Could Not Compile Regular Expression: %s"), errbuf);
487 return ERROR; 509 return false;
488 } 510 }
489 break; 511 break;
490 case INVERT_REGEX: 512 case INVERT_REGEX:
@@ -501,7 +523,7 @@ process_arguments (int argc, char **argv)
501#endif 523#endif
502 break; 524 break;
503 case 'v': /* verbose */ 525 case 'v': /* verbose */
504 verbose = TRUE; 526 verbose = true;
505 break; 527 break;
506 case 'm': /* min_page_length */ 528 case 'm': /* min_page_length */
507 { 529 {
@@ -526,7 +548,7 @@ process_arguments (int argc, char **argv)
526 break; 548 break;
527 } 549 }
528 case 'N': /* no-body */ 550 case 'N': /* no-body */
529 no_body = TRUE; 551 no_body = true;
530 break; 552 break;
531 case 'M': /* max-age */ 553 case 'M': /* max-age */
532 { 554 {
@@ -547,10 +569,10 @@ process_arguments (int argc, char **argv)
547 } 569 }
548 break; 570 break;
549 case 'E': /* show extended perfdata */ 571 case 'E': /* show extended perfdata */
550 show_extended_perfdata = TRUE; 572 show_extended_perfdata = true;
551 break; 573 break;
552 case 'B': /* print body content after status line */ 574 case 'B': /* print body content after status line */
553 show_body = TRUE; 575 show_body = true;
554 break; 576 break;
555 } 577 }
556 } 578 }
@@ -587,7 +609,7 @@ process_arguments (int argc, char **argv)
587 if (virtual_port == 0) 609 if (virtual_port == 0)
588 virtual_port = server_port; 610 virtual_port = server_port;
589 611
590 return TRUE; 612 return true;
591} 613}
592 614
593 615
@@ -927,7 +949,7 @@ check_http (void)
927 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */ 949 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */
928 950
929 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 951 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
930 && host_name != NULL && use_ssl == TRUE) { 952 && host_name != NULL && use_ssl == true) {
931 953
932 if (verbose) printf ("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, server_port, host_name, HTTPS_PORT); 954 if (verbose) printf ("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, server_port, host_name, HTTPS_PORT);
933 asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent); 955 asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent);
@@ -961,7 +983,7 @@ check_http (void)
961 } 983 }
962#ifdef HAVE_SSL 984#ifdef HAVE_SSL
963 elapsed_time_connect = (double)microsec_connect / 1.0e6; 985 elapsed_time_connect = (double)microsec_connect / 1.0e6;
964 if (use_ssl == TRUE) { 986 if (use_ssl == true) {
965 gettimeofday (&tv_temp, NULL); 987 gettimeofday (&tv_temp, NULL);
966 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey); 988 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
967 if (verbose) printf ("SSL initialized\n"); 989 if (verbose) printf ("SSL initialized\n");
@@ -969,17 +991,19 @@ check_http (void)
969 die (STATE_CRITICAL, NULL); 991 die (STATE_CRITICAL, NULL);
970 microsec_ssl = deltime (tv_temp); 992 microsec_ssl = deltime (tv_temp);
971 elapsed_time_ssl = (double)microsec_ssl / 1.0e6; 993 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
972 if (check_cert == TRUE) { 994 if (check_cert == true) {
973 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 995 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
974 if (sd) close(sd); 996 if (continue_after_check_cert == false) {
975 np_net_ssl_cleanup(); 997 if (sd) close(sd);
976 return result; 998 np_net_ssl_cleanup();
999 return result;
1000 }
977 } 1001 }
978 } 1002 }
979#endif /* HAVE_SSL */ 1003#endif /* HAVE_SSL */
980 1004
981 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 1005 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
982 && host_name != NULL && use_ssl == TRUE) 1006 && host_name != NULL && use_ssl == true)
983 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method_proxy, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); 1007 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method_proxy, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent);
984 else 1008 else
985 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); 1009 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent);
@@ -1007,10 +1031,10 @@ check_http (void)
1007 * 14.23). Some server applications/configurations cause trouble if the 1031 * 14.23). Some server applications/configurations cause trouble if the
1008 * (default) port is explicitly specified in the "Host:" header line. 1032 * (default) port is explicitly specified in the "Host:" header line.
1009 */ 1033 */
1010 if ((use_ssl == FALSE && virtual_port == HTTP_PORT) || 1034 if ((use_ssl == false && virtual_port == HTTP_PORT) ||
1011 (use_ssl == TRUE && virtual_port == HTTPS_PORT) || 1035 (use_ssl == true && virtual_port == HTTPS_PORT) ||
1012 (server_address != NULL && strcmp(http_method, "CONNECT") == 0 1036 (server_address != NULL && strcmp(http_method, "CONNECT") == 0
1013 && host_name != NULL && use_ssl == TRUE)) 1037 && host_name != NULL && use_ssl == true))
1014 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name); 1038 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name);
1015 else 1039 else
1016 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port); 1040 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port);
@@ -1050,9 +1074,8 @@ check_http (void)
1050 } 1074 }
1051 1075
1052 xasprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data)); 1076 xasprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data));
1053 xasprintf (&buf, "%s%s%s", buf, http_post_data, CRLF); 1077 xasprintf (&buf, "%s%s", buf, http_post_data);
1054 } 1078 } else {
1055 else {
1056 /* or just a newline so the server knows we're done with the request */ 1079 /* or just a newline so the server knows we're done with the request */
1057 xasprintf (&buf, "%s%s", buf, CRLF); 1080 xasprintf (&buf, "%s%s", buf, CRLF);
1058 } 1081 }
@@ -1076,9 +1099,14 @@ check_http (void)
1076 *pos = ' '; 1099 *pos = ' ';
1077 } 1100 }
1078 buffer[i] = '\0'; 1101 buffer[i] = '\0';
1079 xasprintf (&full_page_new, "%s%s", full_page, buffer); 1102
1080 free (full_page); 1103 if ((full_page_new = realloc(full_page, pagesize + i + 1)) == NULL)
1104 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate memory for full_page\n"));
1105
1106 memmove(&full_page_new[pagesize], buffer, i + 1);
1107
1081 full_page = full_page_new; 1108 full_page = full_page_new;
1109
1082 pagesize += i; 1110 pagesize += i;
1083 1111
1084 if (no_body && document_headers_done (full_page)) { 1112 if (no_body && document_headers_done (full_page)) {
@@ -1090,25 +1118,7 @@ check_http (void)
1090 elapsed_time_transfer = (double)microsec_transfer / 1.0e6; 1118 elapsed_time_transfer = (double)microsec_transfer / 1.0e6;
1091 1119
1092 if (i < 0 && errno != ECONNRESET) { 1120 if (i < 0 && errno != ECONNRESET) {
1093#ifdef HAVE_SSL 1121 die(STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1094 /*
1095 if (use_ssl) {
1096 sslerr=SSL_get_error(ssl, i);
1097 if ( sslerr == SSL_ERROR_SSL ) {
1098 die (STATE_WARNING, _("HTTP WARNING - Client Certificate Required\n"));
1099 } else {
1100 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1101 }
1102 }
1103 else {
1104 */
1105#endif
1106 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1107#ifdef HAVE_SSL
1108 /* XXX
1109 }
1110 */
1111#endif
1112 } 1122 }
1113 1123
1114 /* return a CRITICAL status if we couldn't read any data */ 1124 /* return a CRITICAL status if we couldn't read any data */
@@ -1233,32 +1243,73 @@ check_http (void)
1233 } 1243 }
1234 1244
1235 /* Page and Header content checks go here */ 1245 /* Page and Header content checks go here */
1236 if (strlen (header_expect)) { 1246 if (strlen(header_expect) > 0) {
1237 if (!strstr (header, header_expect)) { 1247 if (strstr(header, header_expect) == NULL) {
1238 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search)); 1248 // We did not find the header, the rest is for building the output and setting the state
1239 if(output_header_search[sizeof(output_header_search)-1]!='\0') { 1249 char output_header_search[30] = "";
1240 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4); 1250
1251 strncpy(&output_header_search[0], header_expect,
1252 sizeof(output_header_search));
1253
1254 if (output_header_search[sizeof(output_header_search) - 1] != '\0') {
1255 bcopy("...",
1256 &output_header_search[sizeof(output_header_search) - 4],
1257 4);
1241 } 1258 }
1242 xasprintf (&msg, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); 1259
1260 xasprintf (&msg,
1261 _("%sheader '%s' not found on '%s://%s:%d%s', "),
1262 msg,
1263 output_header_search, use_ssl ? "https" : "http",
1264 host_name ? host_name : server_address, server_port,
1265 server_url);
1266
1243 result = STATE_CRITICAL; 1267 result = STATE_CRITICAL;
1244 } 1268 }
1245 } 1269 }
1246 1270
1271 // At this point we should test if the content is chunked and unchunk it, so
1272 // it can be searched (and possibly printed)
1273 const char *chunked_header_regex_string = "Transfer-Encoding: *chunked *";
1274 regex_t chunked_header_regex;
1247 1275
1248 if (strlen (string_expect)) { 1276 if (regcomp(&chunked_header_regex, chunked_header_regex_string, REG_ICASE)) {
1249 if (!strstr (page, string_expect)) { 1277 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to compile chunked_header_regex regex");
1250 strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); 1278 }
1251 if(output_string_search[sizeof(output_string_search)-1]!='\0') { 1279
1252 bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); 1280 regmatch_t chre_pmatch[1]; // We actually do not care about this, since we only want to know IF it was found
1281
1282 if (!no_body && regexec(&chunked_header_regex, header, 1, chre_pmatch, 0) == 0) {
1283 if (verbose) {
1284 printf("Found chunked content\n");
1285 }
1286 // We actually found the chunked header
1287 char *tmp = unchunk_content(page);
1288 if (tmp == NULL) {
1289 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to unchunk message body");
1290 }
1291 page = tmp;
1292 }
1293
1294 if (strlen(string_expect) > 0) {
1295 if (!strstr(page, string_expect)) {
1296 // We found the string the body, the rest is for building the output
1297 char output_string_search[30] = "";
1298 strncpy(&output_string_search[0], string_expect,
1299 sizeof(output_string_search));
1300 if (output_string_search[sizeof(output_string_search) - 1] != '\0') {
1301 bcopy("...", &output_string_search[sizeof(output_string_search) - 4],
1302 4);
1253 } 1303 }
1254 xasprintf (&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); 1304 xasprintf (&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url);
1255 result = STATE_CRITICAL; 1305 result = STATE_CRITICAL;
1256 } 1306 }
1257 } 1307 }
1258 1308
1259 if (strlen (regexp)) { 1309 if (strlen(regexp) > 0) {
1260 errcode = regexec (&preg, page, REGS, pmatch, 0); 1310 errcode = regexec(&preg, page, REGS, pmatch, 0);
1261 if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { 1311 if ((errcode == 0 && invert_regex == 0) ||
1312 (errcode == REG_NOMATCH && invert_regex == 1)) {
1262 /* OK - No-op to avoid changing the logic around it */ 1313 /* OK - No-op to avoid changing the logic around it */
1263 result = max_state_alt(STATE_OK, result); 1314 result = max_state_alt(STATE_OK, result);
1264 } 1315 }
@@ -1310,7 +1361,7 @@ check_http (void)
1310 perfd_time (elapsed_time), 1361 perfd_time (elapsed_time),
1311 perfd_size (page_len), 1362 perfd_size (page_len),
1312 perfd_time_connect (elapsed_time_connect), 1363 perfd_time_connect (elapsed_time_connect),
1313 use_ssl == TRUE ? perfd_time_ssl (elapsed_time_ssl) : "", 1364 use_ssl == true ? perfd_time_ssl (elapsed_time_ssl) : "",
1314 perfd_time_headers (elapsed_time_headers), 1365 perfd_time_headers (elapsed_time_headers),
1315 perfd_time_firstbyte (elapsed_time_firstbyte), 1366 perfd_time_firstbyte (elapsed_time_firstbyte),
1316 perfd_time_transfer (elapsed_time_transfer)); 1367 perfd_time_transfer (elapsed_time_transfer));
@@ -1332,7 +1383,94 @@ check_http (void)
1332 return STATE_UNKNOWN; 1383 return STATE_UNKNOWN;
1333} 1384}
1334 1385
1386/* Receivces a pointer to the beginning of the body of a HTTP message
1387 * which is chunked and returns a pointer to a freshly allocated memory
1388 * region containing the unchunked body or NULL if something failed.
1389 * The result must be freed by the caller.
1390 */
1391char *unchunk_content(const char *content) {
1392 // https://en.wikipedia.org/wiki/Chunked_transfer_encoding
1393 // https://www.rfc-editor.org/rfc/rfc7230#section-4.1
1394 char *result = NULL;
1395 char *start_of_chunk;
1396 char* end_of_chunk;
1397 long size_of_chunk;
1398 const char *pointer = content;
1399 char *endptr;
1400 long length_of_chunk = 0;
1401 size_t overall_size = 0;
1402
1403 while (true) {
1404 size_of_chunk = strtol(pointer, &endptr, 16);
1405 if (size_of_chunk == LONG_MIN || size_of_chunk == LONG_MAX) {
1406 // Apparently underflow or overflow, should not happen
1407 if (verbose) {
1408 printf("Got an underflow or overflow from strtol at: %u\n", __LINE__);
1409 }
1410 return NULL;
1411 }
1412 if (endptr == pointer) {
1413 // Apparently this was not a number
1414 if (verbose) {
1415 printf("Chunked content did not start with a number at all (Line: %u)\n", __LINE__);
1416 }
1417 return NULL;
1418 }
1419
1420 // So, we got the length of the chunk
1421 if (*endptr == ';') {
1422 // Chunk extension starts here
1423 while (*endptr != '\r') {
1424 endptr++;
1425 }
1426 }
1427
1428 start_of_chunk = endptr + 2;
1429 end_of_chunk = start_of_chunk + size_of_chunk;
1430 length_of_chunk = (long)(end_of_chunk - start_of_chunk);
1431 pointer = end_of_chunk + 2; //Next number should be here
1432
1433 if (length_of_chunk == 0) {
1434 // Chunk length is 0, so this is the last one
1435 break;
1436 }
1437
1438 overall_size += length_of_chunk;
1439
1440 if (result == NULL) {
1441 // Size of the chunk plus the ending NULL byte
1442 result = (char *)malloc(length_of_chunk +1);
1443 if (result == NULL) {
1444 if (verbose) {
1445 printf("Failed to allocate memory for unchunked body\n");
1446 }
1447 return NULL;
1448 }
1449 } else {
1450 // Enlarge memory to the new size plus the ending NULL byte
1451 void *tmp = realloc(result, overall_size +1);
1452 if (tmp == NULL) {
1453 if (verbose) {
1454 printf("Failed to allocate memory for unchunked body\n");
1455 }
1456 return NULL;
1457 } else {
1458 result = tmp;
1459 }
1460 }
1461
1462 memcpy(result + (overall_size - size_of_chunk), start_of_chunk, size_of_chunk);
1463 }
1335 1464
1465 if (overall_size == 0 && result == NULL) {
1466 // We might just have received the end chunk without previous content, so result is never allocated
1467 result = calloc(1, sizeof(char));
1468 // No error handling here, we can only return NULL anyway
1469 } else {
1470 result[overall_size] = '\0';
1471 }
1472 return result;
1473}
1336 1474
1337/* per RFC 2396 */ 1475/* per RFC 2396 */
1338#define URI_HTTP "%5[HTPShtps]" 1476#define URI_HTTP "%5[HTPShtps]"
@@ -1343,7 +1481,9 @@ check_http (void)
1343#define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH 1481#define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH
1344#define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT 1482#define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT
1345#define HD4 URI_HTTP "://" URI_HOST 1483#define HD4 URI_HTTP "://" URI_HOST
1346#define HD5 URI_PATH 1484/* relative reference redirect like //www.site.org/test https://tools.ietf.org/html/rfc3986 */
1485#define HD5 "//" URI_HOST "/" URI_PATH
1486#define HD6 URI_PATH
1347 1487
1348void 1488void
1349redir (char *pos, char *status_line) 1489redir (char *pos, char *status_line)
@@ -1420,9 +1560,21 @@ redir (char *pos, char *status_line)
1420 use_ssl = server_type_check (type); 1560 use_ssl = server_type_check (type);
1421 i = server_port_check (use_ssl); 1561 i = server_port_check (use_ssl);
1422 } 1562 }
1563 /* URI_HTTP, URI_HOST, URI_PATH */
1564 else if (sscanf (pos, HD5, addr, url) == 2) {
1565 if(use_ssl){
1566 strcpy (type,"https");
1567 }
1568 else{
1569 strcpy (type, server_type);
1570 }
1571 xasprintf (&url, "/%s", url);
1572 use_ssl = server_type_check (type);
1573 i = server_port_check (use_ssl);
1574 }
1423 1575
1424 /* URI_PATH */ 1576 /* URI_PATH */
1425 else if (sscanf (pos, HD5, url) == 1) { 1577 else if (sscanf (pos, HD6, url) == 1) {
1426 /* relative url */ 1578 /* relative url */
1427 if ((url[0] != '/')) { 1579 if ((url[0] != '/')) {
1428 if ((x = strrchr(server_url, '/'))) 1580 if ((x = strrchr(server_url, '/')))
@@ -1491,13 +1643,13 @@ redir (char *pos, char *status_line)
1491} 1643}
1492 1644
1493 1645
1494int 1646bool
1495server_type_check (const char *type) 1647server_type_check (const char *type)
1496{ 1648{
1497 if (strcmp (type, "https")) 1649 if (strcmp (type, "https"))
1498 return FALSE; 1650 return false;
1499 else 1651 else
1500 return TRUE; 1652 return true;
1501} 1653}
1502 1654
1503int 1655int
@@ -1512,42 +1664,42 @@ server_port_check (int ssl_flag)
1512char *perfd_time (double elapsed_time) 1664char *perfd_time (double elapsed_time)
1513{ 1665{
1514 return fperfdata ("time", elapsed_time, "s", 1666 return fperfdata ("time", elapsed_time, "s",
1515 thlds->warning?TRUE:FALSE, thlds->warning?thlds->warning->end:0, 1667 thlds->warning?true:false, thlds->warning?thlds->warning->end:0,
1516 thlds->critical?TRUE:FALSE, thlds->critical?thlds->critical->end:0, 1668 thlds->critical?true:false, thlds->critical?thlds->critical->end:0,
1517 TRUE, 0, TRUE, socket_timeout); 1669 true, 0, true, socket_timeout);
1518} 1670}
1519 1671
1520char *perfd_time_connect (double elapsed_time_connect) 1672char *perfd_time_connect (double elapsed_time_connect)
1521{ 1673{
1522 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1674 return fperfdata ("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1523} 1675}
1524 1676
1525char *perfd_time_ssl (double elapsed_time_ssl) 1677char *perfd_time_ssl (double elapsed_time_ssl)
1526{ 1678{
1527 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1679 return fperfdata ("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1528} 1680}
1529 1681
1530char *perfd_time_headers (double elapsed_time_headers) 1682char *perfd_time_headers (double elapsed_time_headers)
1531{ 1683{
1532 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1684 return fperfdata ("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1533} 1685}
1534 1686
1535char *perfd_time_firstbyte (double elapsed_time_firstbyte) 1687char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1536{ 1688{
1537 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1689 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1538} 1690}
1539 1691
1540char *perfd_time_transfer (double elapsed_time_transfer) 1692char *perfd_time_transfer (double elapsed_time_transfer)
1541{ 1693{
1542 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1694 return fperfdata ("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1543} 1695}
1544 1696
1545char *perfd_size (int page_len) 1697char *perfd_size (int page_len)
1546{ 1698{
1547 return perfdata ("size", page_len, "B", 1699 return perfdata ("size", page_len, "B",
1548 (min_page_len>0?TRUE:FALSE), min_page_len, 1700 (min_page_len>0?true:false), min_page_len,
1549 (min_page_len>0?TRUE:FALSE), 0, 1701 (min_page_len>0?true:false), 0,
1550 TRUE, 0, FALSE, 0); 1702 true, 0, false, 0);
1551} 1703}
1552 1704
1553void 1705void
@@ -1598,7 +1750,11 @@ print_help (void)
1598 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 1750 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
1599 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1751 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1600 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1752 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1601 printf (" %s\n", _("(when this option is used the URL is not checked.)")); 1753 printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use"));
1754 printf (" %s\n", _(" --continue-after-certificate to override this behavior)"));
1755 printf (" %s\n", "--continue-after-certificate");
1756 printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check."));
1757 printf (" %s\n", _("Does nothing unless -C is used."));
1602 printf (" %s\n", "-J, --client-cert=FILE"); 1758 printf (" %s\n", "-J, --client-cert=FILE");
1603 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); 1759 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1604 printf (" %s\n", _("to be used in establishing the SSL session")); 1760 printf (" %s\n", _("to be used in establishing the SSL session"));
@@ -1657,9 +1813,11 @@ print_help (void)
1657 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); 1813 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>");
1658 printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); 1814 printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the"));
1659 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); 1815 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same."));
1816 printf (" %s\n", "--max-redirs=INTEGER");
1817 printf (" %s", _("Maximal number of redirects (default: "));
1818 printf ("%d)\n", DEFAULT_MAX_REDIRS);
1660 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 1819 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
1661 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); 1820 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
1662
1663 printf (UT_WARN_CRIT); 1821 printf (UT_WARN_CRIT);
1664 1822
1665 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1823 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
@@ -1727,7 +1885,7 @@ print_usage (void)
1727 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); 1885 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
1728 printf (" [-J <client certificate file>] [-K <private key>]\n"); 1886 printf (" [-J <client certificate file>] [-K <private key>]\n");
1729 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); 1887 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
1730 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n"); 1888 printf (" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport>]\n");
1731 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); 1889 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
1732 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 1890 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
1733 printf (" [-A string] [-k string] [-S <version>] [--sni]\n"); 1891 printf (" [-A string] [-k string] [-S <version>] [--sni]\n");
diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c
index bc7bd44..a1bfe1b 100644
--- a/plugins/check_ldap.c
+++ b/plugins/check_ldap.c
@@ -222,7 +222,7 @@ main (int argc, char *argv[])
222 /* reset the alarm handler */ 222 /* reset the alarm handler */
223 alarm (0); 223 alarm (0);
224 224
225 /* calcutate the elapsed time and compare to thresholds */ 225 /* calculate the elapsed time and compare to thresholds */
226 226
227 microsec = deltime (tv); 227 microsec = deltime (tv);
228 elapsed_time = (double)microsec / 1.0e6; 228 elapsed_time = (double)microsec / 1.0e6;
@@ -432,6 +432,9 @@ validate_arguments ()
432 set_thresholds(&entries_thresholds, 432 set_thresholds(&entries_thresholds,
433 warn_entries, crit_entries); 433 warn_entries, crit_entries);
434 } 434 }
435 if (ld_passwd==NULL)
436 ld_passwd = getenv("LDAP_PASSWORD");
437
435 return OK; 438 return OK;
436} 439}
437 440
@@ -465,7 +468,7 @@ print_help (void)
465 printf (" %s\n", "-D [--bind]"); 468 printf (" %s\n", "-D [--bind]");
466 printf (" %s\n", _("ldap bind DN (if required)")); 469 printf (" %s\n", _("ldap bind DN (if required)"));
467 printf (" %s\n", "-P [--pass]"); 470 printf (" %s\n", "-P [--pass]");
468 printf (" %s\n", _("ldap password (if required)")); 471 printf (" %s\n", _("ldap password (if required, or set the password through environment variable 'LDAP_PASSWORD')"));
469 printf (" %s\n", "-T [--starttls]"); 472 printf (" %s\n", "-T [--starttls]");
470 printf (" %s\n", _("use starttls mechanism introduced in protocol version 3")); 473 printf (" %s\n", _("use starttls mechanism introduced in protocol version 3"));
471 printf (" %s\n", "-S [--ssl]"); 474 printf (" %s\n", "-S [--ssl]");
diff --git a/plugins/check_load.c b/plugins/check_load.c
index 0e4de54..313df8a 100644
--- a/plugins/check_load.c
+++ b/plugins/check_load.c
@@ -1,41 +1,43 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_load plugin 3* Monitoring check_load plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2007 Monitoring Plugins Development Team 6* Copyright (c) 1999-2007 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_load plugin 10* This file contains the check_load plugin
11* 11*
12* This plugin tests the current system load average. 12* This plugin tests the current system load average.
13* 13*
14* 14*
15* This program is free software: you can redistribute it and/or modify 15* This program is free software: you can redistribute it and/or modify
16* it under the terms of the GNU General Public License as published by 16* it under the terms of the GNU General Public License as published by
17* the Free Software Foundation, either version 3 of the License, or 17* the Free Software Foundation, either version 3 of the License, or
18* (at your option) any later version. 18* (at your option) any later version.
19* 19*
20* This program is distributed in the hope that it will be useful, 20* This program is distributed in the hope that it will be useful,
21* but WITHOUT ANY WARRANTY; without even the implied warranty of 21* but WITHOUT ANY WARRANTY; without even the implied warranty of
22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23* GNU General Public License for more details. 23* GNU General Public License for more details.
24* 24*
25* You should have received a copy of the GNU General Public License 25* You should have received a copy of the GNU General Public License
26* along with this program. If not, see <http://www.gnu.org/licenses/>. 26* along with this program. If not, see <http://www.gnu.org/licenses/>.
27* 27*
28* 28*
29*****************************************************************************/ 29*****************************************************************************/
30 30
31const char *progname = "check_load"; 31const char *progname = "check_load";
32const char *copyright = "1999-2007"; 32const char *copyright = "1999-2022";
33const char *email = "devel@monitoring-plugins.org"; 33const char *email = "devel@monitoring-plugins.org";
34 34
35#include "common.h" 35#include "./common.h"
36#include "runcmd.h" 36#include "./runcmd.h"
37#include "utils.h" 37#include "./utils.h"
38#include "popen.h" 38#include "./popen.h"
39
40#include <string.h>
39 41
40#ifdef HAVE_SYS_LOADAVG_H 42#ifdef HAVE_SYS_LOADAVG_H
41#include <sys/loadavg.h> 43#include <sys/loadavg.h>
@@ -68,7 +70,7 @@ double cload[3] = { 0.0, 0.0, 0.0 };
68#define la15 la[2] 70#define la15 la[2]
69 71
70char *status_line; 72char *status_line;
71int take_into_account_cpus = 0; 73bool take_into_account_cpus = false;
72 74
73static void 75static void
74get_threshold(char *arg, double *th) 76get_threshold(char *arg, double *th)
@@ -101,11 +103,11 @@ get_threshold(char *arg, double *th)
101int 103int
102main (int argc, char **argv) 104main (int argc, char **argv)
103{ 105{
104 int result; 106 int result = -1;
105 int i; 107 int i;
106 long numcpus; 108 long numcpus;
107 109
108 double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about unitialized arrays */ 110 double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about uninitialized arrays */
109#ifndef HAVE_GETLOADAVG 111#ifndef HAVE_GETLOADAVG
110 char input_buffer[MAX_INPUT_BUFFER]; 112 char input_buffer[MAX_INPUT_BUFFER];
111# ifdef HAVE_PROC_LOADAVG 113# ifdef HAVE_PROC_LOADAVG
@@ -164,7 +166,7 @@ main (int argc, char **argv)
164 sscanf (input_buffer, "%*[^l]load averages: %lf, %lf, %lf", &la1, &la5, &la15); 166 sscanf (input_buffer, "%*[^l]load averages: %lf, %lf, %lf", &la1, &la5, &la15);
165 } 167 }
166 else { 168 else {
167 printf (_("could not parse load from uptime %s: %s\n"), PATH_TO_UPTIME, result); 169 printf (_("could not parse load from uptime %s: %d\n"), PATH_TO_UPTIME, result);
168 return STATE_UNKNOWN; 170 return STATE_UNKNOWN;
169 } 171 }
170 172
@@ -176,13 +178,6 @@ main (int argc, char **argv)
176# endif 178# endif
177#endif 179#endif
178 180
179 if (take_into_account_cpus == 1) {
180 if ((numcpus = GET_NUMBER_OF_CPUS()) > 0) {
181 la[0] = la[0] / numcpus;
182 la[1] = la[1] / numcpus;
183 la[2] = la[2] / numcpus;
184 }
185 }
186 if ((la[0] < 0.0) || (la[1] < 0.0) || (la[2] < 0.0)) { 181 if ((la[0] < 0.0) || (la[1] < 0.0) || (la[2] < 0.0)) {
187#ifdef HAVE_GETLOADAVG 182#ifdef HAVE_GETLOADAVG
188 printf (_("Error in getloadavg()\n")); 183 printf (_("Error in getloadavg()\n"));
@@ -200,18 +195,49 @@ main (int argc, char **argv)
200 result = STATE_OK; 195 result = STATE_OK;
201 196
202 xasprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15); 197 xasprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15);
198 xasprintf(&status_line, ("total %s"), status_line);
199
200
201 double scaled_la[3] = { 0.0, 0.0, 0.0 };
202 bool is_using_scaled_load_values = false;
203
204 if (take_into_account_cpus == true && (numcpus = GET_NUMBER_OF_CPUS()) > 0) {
205 is_using_scaled_load_values = true;
206
207 scaled_la[0] = la[0] / numcpus;
208 scaled_la[1] = la[1] / numcpus;
209 scaled_la[2] = la[2] / numcpus;
210
211 char *tmp = NULL;
212 xasprintf(&tmp, _("load average: %.2f, %.2f, %.2f"), scaled_la[0], scaled_la[1], scaled_la[2]);
213 xasprintf(&status_line, "scaled %s - %s", tmp, status_line);
214 }
203 215
204 for(i = 0; i < 3; i++) { 216 for(i = 0; i < 3; i++) {
205 if(la[i] > cload[i]) { 217 if (is_using_scaled_load_values) {
206 result = STATE_CRITICAL; 218 if(scaled_la[i] > cload[i]) {
207 break; 219 result = STATE_CRITICAL;
220 break;
221 }
222 else if(scaled_la[i] > wload[i]) result = STATE_WARNING;
223 } else {
224 if(la[i] > cload[i]) {
225 result = STATE_CRITICAL;
226 break;
227 }
228 else if(la[i] > wload[i]) result = STATE_WARNING;
208 } 229 }
209 else if(la[i] > wload[i]) result = STATE_WARNING;
210 } 230 }
211 231
212 printf("LOAD %s - %s|", state_text(result), status_line); 232 printf("LOAD %s - %s|", state_text(result), status_line);
213 for(i = 0; i < 3; i++) 233 for(i = 0; i < 3; i++) {
214 printf("load%d=%.3f;%.3f;%.3f;0; ", nums[i], la[i], wload[i], cload[i]); 234 if (is_using_scaled_load_values) {
235 printf("load%d=%.3f;;;0; ", nums[i], la[i]);
236 printf("scaled_load%d=%.3f;%.3f;%.3f;0; ", nums[i], scaled_la[i], wload[i], cload[i]);
237 } else {
238 printf("load%d=%.3f;%.3f;%.3f;0; ", nums[i], la[i], wload[i], cload[i]);
239 }
240 }
215 241
216 putchar('\n'); 242 putchar('\n');
217 if (n_procs_to_show > 0) { 243 if (n_procs_to_show > 0) {
@@ -255,7 +281,7 @@ process_arguments (int argc, char **argv)
255 get_threshold(optarg, cload); 281 get_threshold(optarg, cload);
256 break; 282 break;
257 case 'r': /* Divide load average by number of CPUs */ 283 case 'r': /* Divide load average by number of CPUs */
258 take_into_account_cpus = 1; 284 take_into_account_cpus = true;
259 break; 285 break;
260 case 'V': /* version */ 286 case 'V': /* version */
261 print_revision (progname, NP_VERSION); 287 print_revision (progname, NP_VERSION);
@@ -289,7 +315,6 @@ process_arguments (int argc, char **argv)
289} 315}
290 316
291 317
292
293static int 318static int
294validate_arguments (void) 319validate_arguments (void)
295{ 320{
@@ -310,7 +335,6 @@ validate_arguments (void)
310} 335}
311 336
312 337
313
314void 338void
315print_help (void) 339print_help (void)
316{ 340{
@@ -321,7 +345,7 @@ print_help (void)
321 345
322 printf (_("This plugin tests the current system load average.")); 346 printf (_("This plugin tests the current system load average."));
323 347
324 printf ("\n\n"); 348 printf ("\n\n");
325 349
326 print_usage (); 350 print_usage ();
327 351
@@ -329,15 +353,15 @@ print_help (void)
329 printf (UT_EXTRA_OPTS); 353 printf (UT_EXTRA_OPTS);
330 354
331 printf (" %s\n", "-w, --warning=WLOAD1,WLOAD5,WLOAD15"); 355 printf (" %s\n", "-w, --warning=WLOAD1,WLOAD5,WLOAD15");
332 printf (" %s\n", _("Exit with WARNING status if load average exceeds WLOADn")); 356 printf (" %s\n", _("Exit with WARNING status if load average exceeds WLOADn"));
333 printf (" %s\n", "-c, --critical=CLOAD1,CLOAD5,CLOAD15"); 357 printf (" %s\n", "-c, --critical=CLOAD1,CLOAD5,CLOAD15");
334 printf (" %s\n", _("Exit with CRITICAL status if load average exceed CLOADn")); 358 printf (" %s\n", _("Exit with CRITICAL status if load average exceed CLOADn"));
335 printf (" %s\n", _("the load average format is the same used by \"uptime\" and \"w\"")); 359 printf (" %s\n", _("the load average format is the same used by \"uptime\" and \"w\""));
336 printf (" %s\n", "-r, --percpu"); 360 printf (" %s\n", "-r, --percpu");
337 printf (" %s\n", _("Divide the load averages by the number of CPUs (when possible)")); 361 printf (" %s\n", _("Divide the load averages by the number of CPUs (when possible)"));
338 printf (" %s\n", "-n, --procs-to-show=NUMBER_OF_PROCS"); 362 printf (" %s\n", "-n, --procs-to-show=NUMBER_OF_PROCS");
339 printf (" %s\n", _("Number of processes to show when printing the top consuming processes.")); 363 printf (" %s\n", _("Number of processes to show when printing the top consuming processes."));
340 printf (" %s\n", _("NUMBER_OF_PROCS=0 disables this feature. Default value is 0")); 364 printf (" %s\n", _("NUMBER_OF_PROCS=0 disables this feature. Default value is 0"));
341 365
342 printf (UT_SUPPORT); 366 printf (UT_SUPPORT);
343} 367}
@@ -345,8 +369,8 @@ print_help (void)
345void 369void
346print_usage (void) 370print_usage (void)
347{ 371{
348 printf ("%s\n", _("Usage:")); 372 printf ("%s\n", _("Usage:"));
349 printf ("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", progname); 373 printf ("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", progname);
350} 374}
351 375
352#ifdef PS_USES_PROCPCPU 376#ifdef PS_USES_PROCPCPU
@@ -384,8 +408,8 @@ static int print_top_consuming_processes() {
384#ifdef PS_USES_PROCPCPU 408#ifdef PS_USES_PROCPCPU
385 qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char*), cmpstringp); 409 qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char*), cmpstringp);
386#endif /* PS_USES_PROCPCPU */ 410#endif /* PS_USES_PROCPCPU */
387 int lines_to_show = chld_out.lines < (n_procs_to_show + 1) 411 int lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1)
388 ? chld_out.lines : n_procs_to_show + 1; 412 ? (int)chld_out.lines : n_procs_to_show + 1;
389 for (i = 0; i < lines_to_show; i += 1) { 413 for (i = 0; i < lines_to_show; i += 1) {
390 printf("%s\n", chld_out.line[i]); 414 printf("%s\n", chld_out.line[i]);
391 } 415 }
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index 9b7d13f..7d85554 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -140,7 +140,10 @@ main (int argc, char **argv)
140 mysql_ssl_set(&mysql,key,cert,ca_cert,ca_dir,ciphers); 140 mysql_ssl_set(&mysql,key,cert,ca_cert,ca_dir,ciphers);
141 /* establish a connection to the server and error checking */ 141 /* establish a connection to the server and error checking */
142 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) { 142 if (!mysql_real_connect(&mysql,db_host,db_user,db_pass,db,db_port,db_socket,0)) {
143 if (ignore_auth && mysql_errno (&mysql) == ER_ACCESS_DENIED_ERROR) 143 /* Depending on internally-selected auth plugin MySQL might return */
144 /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */
145 /* Semantically these errors are the same. */
146 if (ignore_auth && (mysql_errno (&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno (&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR))
144 { 147 {
145 printf("MySQL OK - Version: %s (protocol %d)\n", 148 printf("MySQL OK - Version: %s (protocol %d)\n",
146 mysql_get_server_info(&mysql), 149 mysql_get_server_info(&mysql),
@@ -572,7 +575,7 @@ print_help (void)
572 printf (" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds")); 575 printf (" %s\n", _("Exit with CRITICAL status if slave server is more then INTEGER seconds"));
573 printf (" %s\n", _("behind master")); 576 printf (" %s\n", _("behind master"));
574 printf (" %s\n", "-l, --ssl"); 577 printf (" %s\n", "-l, --ssl");
575 printf (" %s\n", _("Use ssl encryptation")); 578 printf (" %s\n", _("Use ssl encryption"));
576 printf (" %s\n", "-C, --ca-cert=STRING"); 579 printf (" %s\n", "-C, --ca-cert=STRING");
577 printf (" %s\n", _("Path to CA signing the cert")); 580 printf (" %s\n", _("Path to CA signing the cert"));
578 printf (" %s\n", "-a, --cert=STRING"); 581 printf (" %s\n", "-a, --cert=STRING");
diff --git a/plugins/check_nt.c b/plugins/check_nt.c
index 59c135d..d73d83c 100644
--- a/plugins/check_nt.c
+++ b/plugins/check_nt.c
@@ -341,7 +341,7 @@ int main(int argc, char **argv){
341 341
342 2) If the counter you're going to measure is percent-based, the code will detect 342 2) If the counter you're going to measure is percent-based, the code will detect
343 the percent sign in its name and will attribute minimum (0%) and maximum (100%) 343 the percent sign in its name and will attribute minimum (0%) and maximum (100%)
344 values automagically, as well the ¨%" sign to graph units. 344 values automagically, as well the "%" sign to graph units.
345 345
346 3) OTOH, if the counter is "absolute", you'll have to provide the following 346 3) OTOH, if the counter is "absolute", you'll have to provide the following
347 the counter unit - that is, the dimensions of the counter you're getting. Examples: 347 the counter unit - that is, the dimensions of the counter you're getting. Examples:
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c
index 914b40c..3614650 100644
--- a/plugins/check_ntp.c
+++ b/plugins/check_ntp.c
@@ -10,7 +10,7 @@
10* 10*
11* This file contains the check_ntp plugin 11* This file contains the check_ntp plugin
12* 12*
13* This plugin to check ntp servers independant of any commandline 13* This plugin to check ntp servers independent of any commandline
14* programs or external libraries. 14* programs or external libraries.
15* 15*
16* 16*
@@ -79,7 +79,7 @@ typedef struct {
79/* this structure holds data about results from querying offset from a peer */ 79/* this structure holds data about results from querying offset from a peer */
80typedef struct { 80typedef struct {
81 time_t waiting; /* ts set when we started waiting for a response */ 81 time_t waiting; /* ts set when we started waiting for a response */
82 int num_responses; /* number of successfully recieved responses */ 82 int num_responses; /* number of successfully received responses */
83 uint8_t stratum; /* copied verbatim from the ntp_message */ 83 uint8_t stratum; /* copied verbatim from the ntp_message */
84 double rtdelay; /* converted from the ntp_message */ 84 double rtdelay; /* converted from the ntp_message */
85 double rtdisp; /* converted from the ntp_message */ 85 double rtdisp; /* converted from the ntp_message */
@@ -100,7 +100,7 @@ typedef struct {
100 /* NB: not necessarily NULL terminated! */ 100 /* NB: not necessarily NULL terminated! */
101} ntp_control_message; 101} ntp_control_message;
102 102
103/* this is an association/status-word pair found in control packet reponses */ 103/* this is an association/status-word pair found in control packet responses */
104typedef struct { 104typedef struct {
105 uint16_t assoc; 105 uint16_t assoc;
106 uint16_t status; 106 uint16_t status;
@@ -355,7 +355,7 @@ int best_offset_server(const ntp_server_results *slist, int nservers){
355 * - we also "manually" handle resolving host names and connecting, because 355 * - we also "manually" handle resolving host names and connecting, because
356 * we have to do it in a way that our lazy macros don't handle currently :( */ 356 * we have to do it in a way that our lazy macros don't handle currently :( */
357double offset_request(const char *host, int *status){ 357double offset_request(const char *host, int *status){
358 int i=0, j=0, ga_result=0, num_hosts=0, *socklist=NULL, respnum=0; 358 int i=0, ga_result=0, num_hosts=0, *socklist=NULL, respnum=0;
359 int servers_completed=0, one_read=0, servers_readable=0, best_index=-1; 359 int servers_completed=0, one_read=0, servers_readable=0, best_index=-1;
360 time_t now_time=0, start_ts=0; 360 time_t now_time=0, start_ts=0;
361 ntp_message *req=NULL; 361 ntp_message *req=NULL;
@@ -488,7 +488,7 @@ double offset_request(const char *host, int *status){
488 /* cleanup */ 488 /* cleanup */
489 /* FIXME: Not closing the socket to avoid re-use of the local port 489 /* FIXME: Not closing the socket to avoid re-use of the local port
490 * which can cause old NTP packets to be read instead of NTP control 490 * which can cause old NTP packets to be read instead of NTP control
491 * pactets in jitter_request(). THERE MUST BE ANOTHER WAY... 491 * packets in jitter_request(). THERE MUST BE ANOTHER WAY...
492 * for(j=0; j<num_hosts; j++){ close(socklist[j]); } */ 492 * for(j=0; j<num_hosts; j++){ close(socklist[j]); } */
493 free(socklist); 493 free(socklist);
494 free(ufds); 494 free(ufds);
@@ -512,7 +512,7 @@ setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){
512} 512}
513 513
514/* XXX handle responses with the error bit set */ 514/* XXX handle responses with the error bit set */
515double jitter_request(const char *host, int *status){ 515double jitter_request(int *status){
516 int conn=-1, i, npeers=0, num_candidates=0, syncsource_found=0; 516 int conn=-1, i, npeers=0, num_candidates=0, syncsource_found=0;
517 int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0; 517 int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0;
518 int peers_size=0, peer_offset=0; 518 int peers_size=0, peer_offset=0;
@@ -575,7 +575,7 @@ double jitter_request(const char *host, int *status){
575 } 575 }
576 } 576 }
577 } 577 }
578 if(verbose) printf("%d candiate peers available\n", num_candidates); 578 if(verbose) printf("%d candidate peers available\n", num_candidates);
579 if(verbose && syncsource_found) printf("synchronization source found\n"); 579 if(verbose && syncsource_found) printf("synchronization source found\n");
580 if(! syncsource_found){ 580 if(! syncsource_found){
581 *status = STATE_UNKNOWN; 581 *status = STATE_UNKNOWN;
@@ -597,7 +597,7 @@ double jitter_request(const char *host, int *status){
597 /* By spec, putting the variable name "jitter" in the request 597 /* By spec, putting the variable name "jitter" in the request
598 * should cause the server to provide _only_ the jitter value. 598 * should cause the server to provide _only_ the jitter value.
599 * thus reducing net traffic, guaranteeing us only a single 599 * thus reducing net traffic, guaranteeing us only a single
600 * datagram in reply, and making intepretation much simpler 600 * datagram in reply, and making interpretation much simpler
601 */ 601 */
602 /* Older servers doesn't know what jitter is, so if we get an 602 /* Older servers doesn't know what jitter is, so if we get an
603 * error on the first pass we redo it with "dispersion" */ 603 * error on the first pass we redo it with "dispersion" */
@@ -803,7 +803,7 @@ int main(int argc, char *argv[]){
803 * (for example) will result in an error 803 * (for example) will result in an error
804 */ 804 */
805 if(do_jitter){ 805 if(do_jitter){
806 jitter=jitter_request(server_address, &jitter_result); 806 jitter=jitter_request(&jitter_result);
807 result = max_state_alt(result, get_status(jitter, jitter_thresholds)); 807 result = max_state_alt(result, get_status(jitter, jitter_thresholds));
808 /* -1 indicates that we couldn't calculate the jitter 808 /* -1 indicates that we couldn't calculate the jitter
809 * Only overrides STATE_OK from the offset */ 809 * Only overrides STATE_OK from the offset */
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c
index 6842842..49cb100 100644
--- a/plugins/check_ntp_peer.c
+++ b/plugins/check_ntp_peer.c
@@ -86,7 +86,7 @@ typedef struct {
86 /* NB: not necessarily NULL terminated! */ 86 /* NB: not necessarily NULL terminated! */
87} ntp_control_message; 87} ntp_control_message;
88 88
89/* this is an association/status-word pair found in control packet reponses */ 89/* this is an association/status-word pair found in control packet responses */
90typedef struct { 90typedef struct {
91 uint16_t assoc; 91 uint16_t assoc;
92 uint16_t status; 92 uint16_t status;
@@ -189,7 +189,7 @@ setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){
189} 189}
190 190
191/* This function does all the actual work; roughly here's what it does 191/* This function does all the actual work; roughly here's what it does
192 * beside setting the offest, jitter and stratum passed as argument: 192 * beside setting the offset, jitter and stratum passed as argument:
193 * - offset can be negative, so if it cannot get the offset, offset_result 193 * - offset can be negative, so if it cannot get the offset, offset_result
194 * is set to UNKNOWN, otherwise OK. 194 * is set to UNKNOWN, otherwise OK.
195 * - jitter and stratum are set to -1 if they cannot be retrieved so any 195 * - jitter and stratum are set to -1 if they cannot be retrieved so any
@@ -199,7 +199,7 @@ setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){
199 * status is pretty much useless as syncsource_found is a global variable 199 * status is pretty much useless as syncsource_found is a global variable
200 * used later in main to check is the server was synchronized. It works 200 * used later in main to check is the server was synchronized. It works
201 * so I left it alone */ 201 * so I left it alone */
202int ntp_request(const char *host, double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers){ 202int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers){
203 int conn=-1, i, npeers=0, num_candidates=0; 203 int conn=-1, i, npeers=0, num_candidates=0;
204 double tmp_offset = 0; 204 double tmp_offset = 0;
205 int min_peer_sel=PEER_INCLUDED; 205 int min_peer_sel=PEER_INCLUDED;
@@ -306,7 +306,7 @@ int ntp_request(const char *host, double *offset, int *offset_result, double *ji
306 /* Putting the wanted variable names in the request 306 /* Putting the wanted variable names in the request
307 * cause the server to provide _only_ the requested values. 307 * cause the server to provide _only_ the requested values.
308 * thus reducing net traffic, guaranteeing us only a single 308 * thus reducing net traffic, guaranteeing us only a single
309 * datagram in reply, and making intepretation much simpler 309 * datagram in reply, and making interpretation much simpler
310 */ 310 */
311 /* Older servers doesn't know what jitter is, so if we get an 311 /* Older servers doesn't know what jitter is, so if we get an
312 * error on the first pass we redo it with "dispersion" */ 312 * error on the first pass we redo it with "dispersion" */
@@ -585,8 +585,8 @@ int main(int argc, char *argv[]){
585 /* set socket timeout */ 585 /* set socket timeout */
586 alarm (socket_timeout); 586 alarm (socket_timeout);
587 587
588 /* This returns either OK or WARNING (See comment preceeding ntp_request) */ 588 /* This returns either OK or WARNING (See comment preceding ntp_request) */
589 result = ntp_request(server_address, &offset, &offset_result, &jitter, &stratum, &num_truechimers); 589 result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers);
590 590
591 if(offset_result == STATE_UNKNOWN) { 591 if(offset_result == STATE_UNKNOWN) {
592 /* if there's no sync peer (this overrides ntp_request output): */ 592 /* if there's no sync peer (this overrides ntp_request output): */
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c
index 391b2df..46cc604 100644
--- a/plugins/check_ntp_time.c
+++ b/plugins/check_ntp_time.c
@@ -81,7 +81,7 @@ typedef struct {
81/* this structure holds data about results from querying offset from a peer */ 81/* this structure holds data about results from querying offset from a peer */
82typedef struct { 82typedef struct {
83 time_t waiting; /* ts set when we started waiting for a response */ 83 time_t waiting; /* ts set when we started waiting for a response */
84 int num_responses; /* number of successfully recieved responses */ 84 int num_responses; /* number of successfully received responses */
85 uint8_t stratum; /* copied verbatim from the ntp_message */ 85 uint8_t stratum; /* copied verbatim from the ntp_message */
86 double rtdelay; /* converted from the ntp_message */ 86 double rtdelay; /* converted from the ntp_message */
87 double rtdisp; /* converted from the ntp_message */ 87 double rtdisp; /* converted from the ntp_message */
diff --git a/plugins/check_nwstat.c b/plugins/check_nwstat.c
index e7e8de0..3c9d23e 100644
--- a/plugins/check_nwstat.c
+++ b/plugins/check_nwstat.c
@@ -1668,7 +1668,7 @@ void print_help(void)
1668 1668
1669 printf ("\n"); 1669 printf ("\n");
1670 printf ("%s\n", _("Notes:")); 1670 printf ("%s\n", _("Notes:"));
1671 printf (" %s\n", _("- This plugin requres that the MRTGEXT.NLM file from James Drews' MRTG")); 1671 printf (" %s\n", _("- This plugin requires that the MRTGEXT.NLM file from James Drews' MRTG"));
1672 printf (" %s\n", _(" extension for NetWare be loaded on the Novell servers you wish to check.")); 1672 printf (" %s\n", _(" extension for NetWare be loaded on the Novell servers you wish to check."));
1673 printf (" %s\n", _(" (available from http://www.engr.wisc.edu/~drews/mrtg/)")); 1673 printf (" %s\n", _(" (available from http://www.engr.wisc.edu/~drews/mrtg/)"));
1674 printf (" %s\n", _("- Values for critical thresholds should be lower than warning thresholds")); 1674 printf (" %s\n", _("- Values for critical thresholds should be lower than warning thresholds"));
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index b8fc5f1..6199033 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -69,7 +69,6 @@ int process_arguments (int, char **);
69int validate_arguments (void); 69int validate_arguments (void);
70void print_usage (void); 70void print_usage (void);
71void print_help (void); 71void print_help (void);
72int is_pg_dbname (char *);
73int is_pg_logname (char *); 72int is_pg_logname (char *);
74int do_query (PGconn *, char *); 73int do_query (PGconn *, char *);
75 74
@@ -85,6 +84,8 @@ char *pgparams = NULL;
85double twarn = (double)DEFAULT_WARN; 84double twarn = (double)DEFAULT_WARN;
86double tcrit = (double)DEFAULT_CRIT; 85double tcrit = (double)DEFAULT_CRIT;
87char *pgquery = NULL; 86char *pgquery = NULL;
87#define OPTID_QUERYNAME -1000
88char *pgqueryname = NULL;
88char *query_warning = NULL; 89char *query_warning = NULL;
89char *query_critical = NULL; 90char *query_critical = NULL;
90thresholds *qthresholds = NULL; 91thresholds *qthresholds = NULL;
@@ -92,7 +93,7 @@ int verbose = 0;
92 93
93/****************************************************************************** 94/******************************************************************************
94 95
95The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ 96The (pseudo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
96tags in the comments. With in the tags, the XML is assembled sequentially. 97tags in the comments. With in the tags, the XML is assembled sequentially.
97You can define entities in tags. You also have all the #defines available as 98You can define entities in tags. You also have all the #defines available as
98entities. 99entities.
@@ -285,6 +286,7 @@ process_arguments (int argc, char **argv)
285 {"database", required_argument, 0, 'd'}, 286 {"database", required_argument, 0, 'd'},
286 {"option", required_argument, 0, 'o'}, 287 {"option", required_argument, 0, 'o'},
287 {"query", required_argument, 0, 'q'}, 288 {"query", required_argument, 0, 'q'},
289 {"queryname", required_argument, 0, OPTID_QUERYNAME},
288 {"query_critical", required_argument, 0, 'C'}, 290 {"query_critical", required_argument, 0, 'C'},
289 {"query_warning", required_argument, 0, 'W'}, 291 {"query_warning", required_argument, 0, 'W'},
290 {"verbose", no_argument, 0, 'v'}, 292 {"verbose", no_argument, 0, 'v'},
@@ -344,10 +346,10 @@ process_arguments (int argc, char **argv)
344 pgport = optarg; 346 pgport = optarg;
345 break; 347 break;
346 case 'd': /* database name */ 348 case 'd': /* database name */
347 if (!is_pg_dbname (optarg)) /* checks length and valid chars */ 349 if (strlen(optarg) >= NAMEDATALEN) {
348 usage2 (_("Database name is not valid"), optarg); 350 usage2 (_("Database name exceeds the maximum length"), optarg);
349 else /* we know length, and know optarg is terminated, so us strcpy */ 351 }
350 snprintf(dbName, NAMEDATALEN, "%s", optarg); 352 snprintf(dbName, NAMEDATALEN, "%s", optarg);
351 break; 353 break;
352 case 'l': /* login name */ 354 case 'l': /* login name */
353 if (!is_pg_logname (optarg)) 355 if (!is_pg_logname (optarg))
@@ -368,6 +370,9 @@ process_arguments (int argc, char **argv)
368 case 'q': 370 case 'q':
369 pgquery = optarg; 371 pgquery = optarg;
370 break; 372 break;
373 case OPTID_QUERYNAME:
374 pgqueryname = optarg;
375 break;
371 case 'v': 376 case 'v':
372 verbose++; 377 verbose++;
373 break; 378 break;
@@ -408,45 +413,6 @@ validate_arguments ()
408 return OK; 413 return OK;
409} 414}
410 415
411
412/******************************************************************************
413
414@@-
415<sect3>
416<title>is_pg_dbname</title>
417
418<para>&PROTO_is_pg_dbname;</para>
419
420<para>Given a database name, this function returns TRUE if the string
421is a valid PostgreSQL database name, and returns false if it is
422not.</para>
423
424<para>Valid PostgreSQL database names are less than &NAMEDATALEN;
425characters long and consist of letters, numbers, and underscores. The
426first character cannot be a number, however.</para>
427
428</sect3>
429-@@
430******************************************************************************/
431
432
433
434int
435is_pg_dbname (char *dbname)
436{
437 char txt[NAMEDATALEN];
438 char tmp[NAMEDATALEN];
439 if (strlen (dbname) > NAMEDATALEN - 1)
440 return (FALSE);
441 strncpy (txt, dbname, NAMEDATALEN - 1);
442 txt[NAMEDATALEN - 1] = 0;
443 if (sscanf (txt, "%[_a-zA-Z]%[^_a-zA-Z0-9-]", tmp, tmp) == 1)
444 return (TRUE);
445 if (sscanf (txt, "%[_a-zA-Z]%[_a-zA-Z0-9-]%[^_a-zA-Z0-9-]", tmp, tmp, tmp) ==
446 2) return (TRUE);
447 return (FALSE);
448}
449
450/** 416/**
451 417
452the tango program should eventually create an entity here based on the 418the tango program should eventually create an entity here based on the
@@ -529,6 +495,9 @@ print_help (void)
529 495
530 printf (" %s\n", "-q, --query=STRING"); 496 printf (" %s\n", "-q, --query=STRING");
531 printf (" %s\n", _("SQL query to run. Only first column in first row will be read")); 497 printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
498 printf (" %s\n", "--queryname=STRING");
499 printf (" %s\n", _("A name for the query, this string is used instead of the query"));
500 printf (" %s\n", _("in the long output of the plugin"));
532 printf (" %s\n", "-W, --query-warning=RANGE"); 501 printf (" %s\n", "-W, --query-warning=RANGE");
533 printf (" %s\n", _("SQL query value to result in warning status (double)")); 502 printf (" %s\n", _("SQL query value to result in warning status (double)"));
534 printf (" %s\n", "-C, --query-critical=RANGE"); 503 printf (" %s\n", "-C, --query-critical=RANGE");
@@ -548,7 +517,10 @@ print_help (void)
548 printf (" %s\n", _("connecting to the server. The result from the query has to be numeric.")); 517 printf (" %s\n", _("connecting to the server. The result from the query has to be numeric."));
549 printf (" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result ")); 518 printf (" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result "));
550 printf (" %s\n", _("of the last command is taken into account only. The value of the first")); 519 printf (" %s\n", _("of the last command is taken into account only. The value of the first"));
551 printf (" %s\n\n", _("column in the first row is used as the check result.")); 520 printf (" %s\n", _("column in the first row is used as the check result. If a second column is"));
521 printf (" %s\n", _("present in the result set, this is added to the plugin output with a"));
522 printf (" %s\n", _("prefix of \"Extra Info:\". This information can be displayed in the system"));
523 printf (" %s\n\n", _("executing the plugin."));
552 524
553 printf (" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual")); 525 printf (" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual"));
554 printf (" %s\n\n", _("for details about how to access internal statistics of the database server.")); 526 printf (" %s\n\n", _("for details about how to access internal statistics of the database server."));
@@ -588,6 +560,7 @@ do_query (PGconn *conn, char *query)
588 PGresult *res; 560 PGresult *res;
589 561
590 char *val_str; 562 char *val_str;
563 char *extra_info;
591 double value; 564 double value;
592 565
593 char *endptr = NULL; 566 char *endptr = NULL;
@@ -642,10 +615,22 @@ do_query (PGconn *conn, char *query)
642 : (my_status == STATE_CRITICAL) 615 : (my_status == STATE_CRITICAL)
643 ? _("CRITICAL") 616 ? _("CRITICAL")
644 : _("UNKNOWN")); 617 : _("UNKNOWN"));
645 printf (_("'%s' returned %f"), query, value); 618 if(pgqueryname) {
619 printf (_("%s returned %f"), pgqueryname, value);
620 }
621 else {
622 printf (_("'%s' returned %f"), query, value);
623 }
624
646 printf ("|query=%f;%s;%s;;\n", value, 625 printf ("|query=%f;%s;%s;;\n", value,
647 query_warning ? query_warning : "", 626 query_warning ? query_warning : "",
648 query_critical ? query_critical : ""); 627 query_critical ? query_critical : "");
628 if (PQnfields (res) > 1) {
629 extra_info = PQgetvalue (res, 0, 1);
630 if (extra_info != NULL) {
631 printf ("Extra Info: %s\n", extra_info);
632 }
633 }
649 return my_status; 634 return my_status;
650} 635}
651 636
diff --git a/plugins/check_ping.c b/plugins/check_ping.c
index 423ecbe..741f732 100644
--- a/plugins/check_ping.c
+++ b/plugins/check_ping.c
@@ -37,6 +37,8 @@ const char *email = "devel@monitoring-plugins.org";
37#include "popen.h" 37#include "popen.h"
38#include "utils.h" 38#include "utils.h"
39 39
40#include <signal.h>
41
40#define WARN_DUPLICATES "DUPLICATES FOUND! " 42#define WARN_DUPLICATES "DUPLICATES FOUND! "
41#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ 43#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */
42 44
@@ -138,7 +140,7 @@ main (int argc, char **argv)
138 if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) { 140 if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) {
139 printf ("%s\n", cmd); 141 printf ("%s\n", cmd);
140 die (STATE_UNKNOWN, 142 die (STATE_UNKNOWN,
141 _("CRITICAL - Could not interpret output from ping command\n")); 143 _("CRITICAL - Could not interpret output from ping command\n"));
142 } 144 }
143 145
144 if (pl >= cpl || rta >= crta || rta < 0) 146 if (pl >= cpl || rta >= crta || rta < 0)
@@ -163,10 +165,14 @@ main (int argc, char **argv)
163 printf ("</A>"); 165 printf ("</A>");
164 166
165 /* Print performance data */ 167 /* Print performance data */
166 printf("|%s", fperfdata ("rta", (double) rta, "ms", 168 if (pl != 100) {
167 wrta>0?TRUE:FALSE, wrta, 169 printf("|%s", fperfdata ("rta", (double) rta, "ms",
168 crta>0?TRUE:FALSE, crta, 170 wrta>0?TRUE:FALSE, wrta,
169 TRUE, 0, FALSE, 0)); 171 crta>0?TRUE:FALSE, crta,
172 TRUE, 0, FALSE, 0));
173 } else {
174 printf("| rta=U;%f;%f;;", wrta, crta);
175 }
170 printf(" %s\n", perfdata ("pl", (long) pl, "%", 176 printf(" %s\n", perfdata ("pl", (long) pl, "%",
171 wpl>0?TRUE:FALSE, wpl, 177 wpl>0?TRUE:FALSE, wpl,
172 cpl>0?TRUE:FALSE, cpl, 178 cpl>0?TRUE:FALSE, cpl,
@@ -521,12 +527,13 @@ int
521error_scan (char buf[MAX_INPUT_BUFFER], const char *addr) 527error_scan (char buf[MAX_INPUT_BUFFER], const char *addr)
522{ 528{
523 if (strstr (buf, "Network is unreachable") || 529 if (strstr (buf, "Network is unreachable") ||
524 strstr (buf, "Destination Net Unreachable") 530 strstr (buf, "Destination Net Unreachable") ||
531 strstr (buf, "No route")
525 ) 532 )
526 die (STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr); 533 die (STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr);
527 else if (strstr (buf, "Destination Host Unreachable")) 534 else if (strstr (buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable"))
528 die (STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr); 535 die (STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr);
529 else if (strstr (buf, "Destination Port Unreachable")) 536 else if (strstr (buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable"))
530 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr); 537 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr);
531 else if (strstr (buf, "Destination Protocol Unreachable")) 538 else if (strstr (buf, "Destination Protocol Unreachable"))
532 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr); 539 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr);
@@ -534,11 +541,11 @@ error_scan (char buf[MAX_INPUT_BUFFER], const char *addr)
534 die (STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr); 541 die (STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr);
535 else if (strstr (buf, "Destination Host Prohibited")) 542 else if (strstr (buf, "Destination Host Prohibited"))
536 die (STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr); 543 die (STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr);
537 else if (strstr (buf, "Packet filtered")) 544 else if (strstr (buf, "Packet filtered") || strstr(buf, "Administratively prohibited"))
538 die (STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr); 545 die (STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr);
539 else if (strstr (buf, "unknown host" )) 546 else if (strstr (buf, "unknown host" ))
540 die (STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr); 547 die (STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr);
541 else if (strstr (buf, "Time to live exceeded")) 548 else if (strstr (buf, "Time to live exceeded") || strstr(buf, "Time exceeded"))
542 die (STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr); 549 die (STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr);
543 else if (strstr (buf, "Destination unreachable: ")) 550 else if (strstr (buf, "Destination unreachable: "))
544 die (STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr); 551 die (STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr);
@@ -547,7 +554,7 @@ error_scan (char buf[MAX_INPUT_BUFFER], const char *addr)
547 if (warn_text == NULL) 554 if (warn_text == NULL)
548 warn_text = strdup (_(WARN_DUPLICATES)); 555 warn_text = strdup (_(WARN_DUPLICATES));
549 else if (! strstr (warn_text, _(WARN_DUPLICATES)) && 556 else if (! strstr (warn_text, _(WARN_DUPLICATES)) &&
550 xasprintf (&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) 557 xasprintf (&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1)
551 die (STATE_UNKNOWN, _("Unable to realloc warn_text\n")); 558 die (STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
552 return (STATE_WARNING); 559 return (STATE_WARNING);
553 } 560 }
@@ -567,7 +574,7 @@ print_help (void)
567 574
568 printf (_("Use ping to check connection statistics for a remote host.")); 575 printf (_("Use ping to check connection statistics for a remote host."));
569 576
570 printf ("\n\n"); 577 printf ("\n\n");
571 578
572 print_usage (); 579 print_usage ();
573 580
@@ -577,29 +584,29 @@ print_help (void)
577 printf (UT_IPv46); 584 printf (UT_IPv46);
578 585
579 printf (" %s\n", "-H, --hostname=HOST"); 586 printf (" %s\n", "-H, --hostname=HOST");
580 printf (" %s\n", _("host to ping")); 587 printf (" %s\n", _("host to ping"));
581 printf (" %s\n", "-w, --warning=THRESHOLD"); 588 printf (" %s\n", "-w, --warning=THRESHOLD");
582 printf (" %s\n", _("warning threshold pair")); 589 printf (" %s\n", _("warning threshold pair"));
583 printf (" %s\n", "-c, --critical=THRESHOLD"); 590 printf (" %s\n", "-c, --critical=THRESHOLD");
584 printf (" %s\n", _("critical threshold pair")); 591 printf (" %s\n", _("critical threshold pair"));
585 printf (" %s\n", "-p, --packets=INTEGER"); 592 printf (" %s\n", "-p, --packets=INTEGER");
586 printf (" %s ", _("number of ICMP ECHO packets to send")); 593 printf (" %s ", _("number of ICMP ECHO packets to send"));
587 printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS); 594 printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
588 printf (" %s\n", "-L, --link"); 595 printf (" %s\n", "-L, --link");
589 printf (" %s\n", _("show HTML in the plugin output (obsoleted by urlize)")); 596 printf (" %s\n", _("show HTML in the plugin output (obsoleted by urlize)"));
590 597
591 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 598 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
592 599
593 printf ("\n"); 600 printf ("\n");
594 printf ("%s\n", _("THRESHOLD is <rta>,<pl>% where <rta> is the round trip average travel")); 601 printf ("%s\n", _("THRESHOLD is <rta>,<pl>% where <rta> is the round trip average travel"));
595 printf ("%s\n", _("time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the")); 602 printf ("%s\n", _("time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the"));
596 printf ("%s\n", _("percentage of packet loss to trigger an alarm state.")); 603 printf ("%s\n", _("percentage of packet loss to trigger an alarm state."));
597 604
598 printf ("\n"); 605 printf ("\n");
599 printf ("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss")); 606 printf ("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss"));
600 printf ("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output")); 607 printf ("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output"));
601 printf ("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in")); 608 printf ("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in"));
602 printf ("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/")); 609 printf ("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/"));
603 610
604 printf (UT_SUPPORT); 611 printf (UT_SUPPORT);
605} 612}
@@ -607,7 +614,7 @@ print_help (void)
607void 614void
608print_usage (void) 615print_usage (void)
609{ 616{
610 printf ("%s\n", _("Usage:")); 617 printf ("%s\n", _("Usage:"));
611 printf ("%s -H <host_address> -w <wrta>,<wpl>%% -c <crta>,<cpl>%%\n", progname); 618 printf ("%s -H <host_address> -w <wrta>,<wpl>%% -c <crta>,<cpl>%%\n", progname);
612 printf (" [-p packets] [-t timeout] [-4|-6]\n"); 619 printf (" [-p packets] [-t timeout] [-4|-6]\n");
613} 620}
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index f7917c3..c17c699 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -1,34 +1,34 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_procs plugin 3* Monitoring check_procs plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2000-2008 Monitoring Plugins Development Team 6* Copyright (c) 2000-2008 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_procs plugin 10* This file contains the check_procs plugin
11* 11*
12* Checks all processes and generates WARNING or CRITICAL states if the 12* Checks all processes and generates WARNING or CRITICAL states if the
13* specified metric is outside the required threshold ranges. The metric 13* specified metric is outside the required threshold ranges. The metric
14* defaults to number of processes. Search filters can be applied to limit 14* defaults to number of processes. Search filters can be applied to limit
15* the processes to check. 15* the processes to check.
16* 16*
17* 17*
18* This program is free software: you can redistribute it and/or modify 18* This program is free software: you can redistribute it and/or modify
19* it under the terms of the GNU General Public License as published by 19* it under the terms of the GNU General Public License as published by
20* the Free Software Foundation, either version 3 of the License, or 20* the Free Software Foundation, either version 3 of the License, or
21* (at your option) any later version. 21* (at your option) any later version.
22* 22*
23* This program is distributed in the hope that it will be useful, 23* This program is distributed in the hope that it will be useful,
24* but WITHOUT ANY WARRANTY; without even the implied warranty of 24* but WITHOUT ANY WARRANTY; without even the implied warranty of
25* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26* GNU General Public License for more details. 26* GNU General Public License for more details.
27* 27*
28* You should have received a copy of the GNU General Public License 28* You should have received a copy of the GNU General Public License
29* along with this program. If not, see <http://www.gnu.org/licenses/>. 29* along with this program. If not, see <http://www.gnu.org/licenses/>.
30* 30*
31* 31*
32*****************************************************************************/ 32*****************************************************************************/
33 33
34const char *progname = "check_procs"; 34const char *progname = "check_procs";
@@ -50,7 +50,7 @@ const char *email = "devel@monitoring-plugins.org";
50 50
51int process_arguments (int, char **); 51int process_arguments (int, char **);
52int validate_arguments (void); 52int validate_arguments (void);
53int convert_to_seconds (char *); 53int convert_to_seconds (char *);
54void print_help (void); 54void print_help (void);
55void print_usage (void); 55void print_usage (void);
56 56
@@ -70,6 +70,7 @@ int options = 0; /* bitmask of filter criteria to test against */
70#define PCPU 256 70#define PCPU 256
71#define ELAPSED 512 71#define ELAPSED 512
72#define EREG_ARGS 1024 72#define EREG_ARGS 1024
73#define EXCLUDE_PROGS 2048
73 74
74#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: 75#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
75 ppid of procs are compared to pid of this proc*/ 76 ppid of procs are compared to pid of this proc*/
@@ -93,6 +94,9 @@ int rss;
93float pcpu; 94float pcpu;
94char *statopts; 95char *statopts;
95char *prog; 96char *prog;
97char *exclude_progs;
98char **exclude_progs_arr = NULL;
99char exclude_progs_counter = 0;
96char *args; 100char *args;
97char *input_filename = NULL; 101char *input_filename = NULL;
98regex_t re_args; 102regex_t re_args;
@@ -230,9 +234,9 @@ main (int argc, char **argv)
230 procseconds = convert_to_seconds(procetime); 234 procseconds = convert_to_seconds(procetime);
231 235
232 if (verbose >= 3) 236 if (verbose >= 3)
233 printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", 237 printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
234 procs, procuid, procvsz, procrss, 238 procs, procuid, procvsz, procrss,
235 procpid, procppid, procpcpu, procstat, 239 procpid, procppid, procpcpu, procstat,
236 procetime, procprog, procargs); 240 procetime, procprog, procargs);
237 241
238 /* Ignore self */ 242 /* Ignore self */
@@ -250,7 +254,26 @@ main (int argc, char **argv)
250 continue; 254 continue;
251 } 255 }
252 256
253 /* filter kernel threads (childs of KTHREAD_PARENT)*/ 257 /* Ignore excluded processes by name */
258 if(options & EXCLUDE_PROGS) {
259 int found = 0;
260 int i = 0;
261
262 for(i=0; i < (exclude_progs_counter); i++) {
263 if(!strcmp(procprog, exclude_progs_arr[i])) {
264 found = 1;
265 }
266 }
267 if(found == 0) {
268 resultsum |= EXCLUDE_PROGS;
269 } else
270 {
271 if(verbose >= 3)
272 printf("excluding - by ignorelist\n");
273 }
274 }
275
276 /* filter kernel threads (children of KTHREAD_PARENT)*/
254 /* TODO adapt for other OSes than GNU/Linux 277 /* TODO adapt for other OSes than GNU/Linux
255 sorry for not doing that, but I've no other OSes to test :-( */ 278 sorry for not doing that, but I've no other OSes to test :-( */
256 if (kthread_filter == 1) { 279 if (kthread_filter == 1) {
@@ -265,7 +288,7 @@ main (int argc, char **argv)
265 } 288 }
266 } 289 }
267 290
268 if ((options & STAT) && (strstr (statopts, procstat))) 291 if ((options & STAT) && (strstr (procstat, statopts)))
269 resultsum |= STAT; 292 resultsum |= STAT;
270 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) 293 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
271 resultsum |= ARGS; 294 resultsum |= ARGS;
@@ -292,9 +315,9 @@ main (int argc, char **argv)
292 315
293 procs++; 316 procs++;
294 if (verbose >= 2) { 317 if (verbose >= 2) {
295 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", 318 printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n",
296 procuid, procvsz, procrss, 319 procuid, procvsz, procrss,
297 procpid, procppid, procpcpu, procstat, 320 procpid, procppid, procpcpu, procstat,
298 procetime, procprog, procargs); 321 procetime, procprog, procargs);
299 } 322 }
300 323
@@ -320,7 +343,7 @@ main (int argc, char **argv)
320 result = max_state (result, i); 343 result = max_state (result, i);
321 } 344 }
322 } 345 }
323 } 346 }
324 /* This should not happen */ 347 /* This should not happen */
325 else if (verbose) { 348 else if (verbose) {
326 printf(_("Not parseable: %s"), input_buffer); 349 printf(_("Not parseable: %s"), input_buffer);
@@ -332,7 +355,7 @@ main (int argc, char **argv)
332 return STATE_UNKNOWN; 355 return STATE_UNKNOWN;
333 } 356 }
334 357
335 if ( result == STATE_UNKNOWN ) 358 if ( result == STATE_UNKNOWN )
336 result = STATE_OK; 359 result = STATE_OK;
337 360
338 /* Needed if procs found, but none match filter */ 361 /* Needed if procs found, but none match filter */
@@ -352,9 +375,9 @@ main (int argc, char **argv)
352 if (metric != METRIC_PROCS) { 375 if (metric != METRIC_PROCS) {
353 printf (_("%d crit, %d warn out of "), crit, warn); 376 printf (_("%d crit, %d warn out of "), crit, warn);
354 } 377 }
355 } 378 }
356 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); 379 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs);
357 380
358 if (strcmp(fmt,"") != 0) { 381 if (strcmp(fmt,"") != 0) {
359 printf (_(" with %s"), fmt); 382 printf (_(" with %s"), fmt);
360 } 383 }
@@ -409,6 +432,7 @@ process_arguments (int argc, char **argv)
409 {"input-file", required_argument, 0, CHAR_MAX+2}, 432 {"input-file", required_argument, 0, CHAR_MAX+2},
410 {"no-kthreads", required_argument, 0, 'k'}, 433 {"no-kthreads", required_argument, 0, 'k'},
411 {"traditional-filter", no_argument, 0, 'T'}, 434 {"traditional-filter", no_argument, 0, 'T'},
435 {"exclude-process", required_argument, 0, 'X'},
412 {0, 0, 0, 0} 436 {0, 0, 0, 0}
413 }; 437 };
414 438
@@ -417,7 +441,7 @@ process_arguments (int argc, char **argv)
417 strcpy (argv[c], "-t"); 441 strcpy (argv[c], "-t");
418 442
419 while (1) { 443 while (1) {
420 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T", 444 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:",
421 longopts, &option); 445 longopts, &option);
422 446
423 if (c == -1 || c == EOF) 447 if (c == -1 || c == EOF)
@@ -440,7 +464,7 @@ process_arguments (int argc, char **argv)
440 break; 464 break;
441 case 'c': /* critical threshold */ 465 case 'c': /* critical threshold */
442 critical_range = optarg; 466 critical_range = optarg;
443 break; 467 break;
444 case 'w': /* warning threshold */ 468 case 'w': /* warning threshold */
445 warning_range = optarg; 469 warning_range = optarg;
446 break; 470 break;
@@ -490,6 +514,23 @@ process_arguments (int argc, char **argv)
490 prog); 514 prog);
491 options |= PROG; 515 options |= PROG;
492 break; 516 break;
517 case 'X':
518 if(exclude_progs)
519 break;
520 else
521 exclude_progs = optarg;
522 xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
523 exclude_progs);
524 char *p = strtok(exclude_progs, ",");
525
526 while(p){
527 exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter);
528 exclude_progs_arr[exclude_progs_counter-1] = p;
529 p = strtok(NULL, ",");
530 }
531
532 options |= EXCLUDE_PROGS;
533 break;
493 case 'a': /* args (full path name with args) */ 534 case 'a': /* args (full path name with args) */
494 /* TODO: allow this to be passed in with --metric */ 535 /* TODO: allow this to be passed in with --metric */
495 if (args) 536 if (args)
@@ -542,11 +583,11 @@ process_arguments (int argc, char **argv)
542 if ( strcmp(optarg, "PROCS") == 0) { 583 if ( strcmp(optarg, "PROCS") == 0) {
543 metric = METRIC_PROCS; 584 metric = METRIC_PROCS;
544 break; 585 break;
545 } 586 }
546 else if ( strcmp(optarg, "VSZ") == 0) { 587 else if ( strcmp(optarg, "VSZ") == 0) {
547 metric = METRIC_VSZ; 588 metric = METRIC_VSZ;
548 break; 589 break;
549 } 590 }
550 else if ( strcmp(optarg, "RSS") == 0 ) { 591 else if ( strcmp(optarg, "RSS") == 0 ) {
551 metric = METRIC_RSS; 592 metric = METRIC_RSS;
552 break; 593 break;
@@ -559,7 +600,7 @@ process_arguments (int argc, char **argv)
559 metric = METRIC_ELAPSED; 600 metric = METRIC_ELAPSED;
560 break; 601 break;
561 } 602 }
562 603
563 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); 604 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
564 case 'k': /* linux kernel thread filter */ 605 case 'k': /* linux kernel thread filter */
565 kthread_filter = 1; 606 kthread_filter = 1;
@@ -642,7 +683,7 @@ convert_to_seconds(char *etime) {
642 seconds = 0; 683 seconds = 0;
643 684
644 for (ptr = etime; *ptr != '\0'; ptr++) { 685 for (ptr = etime; *ptr != '\0'; ptr++) {
645 686
646 if (*ptr == '-') { 687 if (*ptr == '-') {
647 hyphcnt++; 688 hyphcnt++;
648 continue; 689 continue;
@@ -745,6 +786,8 @@ print_help (void)
745 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); 786 printf (" %s\n", _("Only scan for processes with args that contain the regex STRING."));
746 printf (" %s\n", "-C, --command=COMMAND"); 787 printf (" %s\n", "-C, --command=COMMAND");
747 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); 788 printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
789 printf (" %s\n", "-X, --exclude-process");
790 printf (" %s\n", _("Exclude processes which match this comma separated list"));
748 printf (" %s\n", "-k, --no-kthreads"); 791 printf (" %s\n", "-k, --no-kthreads");
749 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); 792 printf (" %s\n", _("Only scan for non kernel threads (works on Linux only)."));
750 793
@@ -775,7 +818,7 @@ be the total number of running processes\n\n"));
775 printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); 818 printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ");
776 printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); 819 printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K"));
777 printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); 820 printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU");
778 printf (" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); 821 printf (" %s\n", _("Alert if CPU of any processes over 10\% or 20\%"));
779 822
780 printf (UT_SUPPORT); 823 printf (UT_SUPPORT);
781} 824}
@@ -786,5 +829,5 @@ print_usage (void)
786 printf ("%s\n", _("Usage:")); 829 printf ("%s\n", _("Usage:"));
787 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); 830 printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
788 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); 831 printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
789 printf (" [-C command] [-k] [-t timeout] [-v]\n"); 832 printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n");
790} 833}
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index be1001b..b1b4938 100644
--- a/plugins/check_radius.c
+++ b/plugins/check_radius.c
@@ -97,7 +97,7 @@ int verbose = FALSE;
97 97
98/****************************************************************************** 98/******************************************************************************
99 99
100The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ 100The (pseudo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
101tags in the comments. With in the tags, the XML is assembled sequentially. 101tags in the comments. With in the tags, the XML is assembled sequentially.
102You can define entities in tags. You also have all the #defines available as 102You can define entities in tags. You also have all the #defines available as
103entities. 103entities.
@@ -155,7 +155,11 @@ main (int argc, char **argv)
155{ 155{
156 struct sockaddr_storage ss; 156 struct sockaddr_storage ss;
157 char name[HOST_NAME_MAX]; 157 char name[HOST_NAME_MAX];
158#ifdef RC_BUFFER_LEN
159 char msg[RC_BUFFER_LEN];
160#else
158 char msg[BUFFER_LEN]; 161 char msg[BUFFER_LEN];
162#endif
159 SEND_DATA data; 163 SEND_DATA data;
160 int result = STATE_UNKNOWN; 164 int result = STATE_UNKNOWN;
161 uint32_t client_id, service; 165 uint32_t client_id, service;
@@ -377,7 +381,7 @@ print_help (void)
377 printf ("\n"); 381 printf ("\n");
378 printf ("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections.")); 382 printf ("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections."));
379 printf ("%s\n", _("The server to test must be specified in the invocation, as well as a user")); 383 printf ("%s\n", _("The server to test must be specified in the invocation, as well as a user"));
380 printf ("%s\n", _("name and password. A configuration file may also be present. The format of")); 384 printf ("%s\n", _("name and password. A configuration file must be present. The format of"));
381 printf ("%s\n", _("the configuration file is described in the radiusclient library sources.")); 385 printf ("%s\n", _("the configuration file is described in the radiusclient library sources."));
382 printf ("%s\n", _("The password option presents a substantial security issue because the")); 386 printf ("%s\n", _("The password option presents a substantial security issue because the"));
383 printf ("%s\n", _("password can possibly be determined by careful watching of the command line")); 387 printf ("%s\n", _("password can possibly be determined by careful watching of the command line"));
diff --git a/plugins/check_real.c b/plugins/check_real.c
index 0f1a1ba..fbdb70f 100644
--- a/plugins/check_real.c
+++ b/plugins/check_real.c
@@ -178,7 +178,7 @@ main (int argc, char **argv)
178 178
179 /* watch for the REAL connection string */ 179 /* watch for the REAL connection string */
180 result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); 180 result = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0);
181 buffer[result] = '\0'; /* null terminate recieved buffer */ 181 buffer[result] = '\0'; /* null terminate received buffer */
182 182
183 /* return a CRITICAL status if we couldn't read any data */ 183 /* return a CRITICAL status if we couldn't read any data */
184 if (result == -1) { 184 if (result == -1) {
@@ -436,7 +436,7 @@ print_help (void)
436 436
437 printf ("\n"); 437 printf ("\n");
438 printf ("%s\n", _("This plugin will attempt to open an RTSP connection with the host.")); 438 printf ("%s\n", _("This plugin will attempt to open an RTSP connection with the host."));
439 printf ("%s\n", _("Successul connects return STATE_OK, refusals and timeouts return")); 439 printf ("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return"));
440 printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful connects,")); 440 printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful connects,"));
441 printf ("%s\n", _("but incorrect response messages from the host result in STATE_WARNING return")); 441 printf ("%s\n", _("but incorrect response messages from the host result in STATE_WARNING return"));
442 printf ("%s\n", _("values.")); 442 printf ("%s\n", _("values."));
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index d37c57c..fc0ae2c 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -3,7 +3,7 @@
3* Monitoring check_smtp plugin 3* Monitoring check_smtp plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2000-2007 Monitoring Plugins Development Team 6* Copyright (c) 2000-2023 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
@@ -42,19 +42,22 @@ const char *email = "devel@monitoring-plugins.org";
42#ifdef HAVE_SSL 42#ifdef HAVE_SSL
43int check_cert = FALSE; 43int check_cert = FALSE;
44int days_till_exp_warn, days_till_exp_crit; 44int days_till_exp_warn, days_till_exp_crit;
45# define my_recv(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) 45# define my_recv(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len))
46# define my_send(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) 46# define my_send(buf, len) (((use_starttls || use_ssl) && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0))
47#else /* ifndef HAVE_SSL */ 47#else /* ifndef HAVE_SSL */
48# define my_recv(buf, len) read(sd, buf, len) 48# define my_recv(buf, len) read(sd, buf, len)
49# define my_send(buf, len) send(sd, buf, len, 0) 49# define my_send(buf, len) send(sd, buf, len, 0)
50#endif 50#endif
51 51
52enum { 52enum {
53 SMTP_PORT = 25 53 SMTP_PORT = 25,
54 SMTPS_PORT = 465
54}; 55};
56#define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n"
55#define SMTP_EXPECT "220" 57#define SMTP_EXPECT "220"
56#define SMTP_HELO "HELO " 58#define SMTP_HELO "HELO "
57#define SMTP_EHLO "EHLO " 59#define SMTP_EHLO "EHLO "
60#define SMTP_LHLO "LHLO "
58#define SMTP_QUIT "QUIT\r\n" 61#define SMTP_QUIT "QUIT\r\n"
59#define SMTP_STARTTLS "STARTTLS\r\n" 62#define SMTP_STARTTLS "STARTTLS\r\n"
60#define SMTP_AUTH_LOGIN "AUTH LOGIN\r\n" 63#define SMTP_AUTH_LOGIN "AUTH LOGIN\r\n"
@@ -81,6 +84,7 @@ int eflags = 0;
81int errcode, excode; 84int errcode, excode;
82 85
83int server_port = SMTP_PORT; 86int server_port = SMTP_PORT;
87int server_port_option = 0;
84char *server_address = NULL; 88char *server_address = NULL;
85char *server_expect = NULL; 89char *server_expect = NULL;
86char *mail_command = NULL; 90char *mail_command = NULL;
@@ -101,7 +105,11 @@ double critical_time = 0;
101int check_critical_time = FALSE; 105int check_critical_time = FALSE;
102int verbose = 0; 106int verbose = 0;
103int use_ssl = FALSE; 107int use_ssl = FALSE;
108int use_starttls = FALSE;
109int use_sni = FALSE;
110short use_proxy_prefix = FALSE;
104short use_ehlo = FALSE; 111short use_ehlo = FALSE;
112short use_lhlo = FALSE;
105short ssl_established = 0; 113short ssl_established = 0;
106char *localhostname = NULL; 114char *localhostname = NULL;
107int sd; 115int sd;
@@ -152,7 +160,9 @@ main (int argc, char **argv)
152 return STATE_CRITICAL; 160 return STATE_CRITICAL;
153 } 161 }
154 } 162 }
155 if(use_ehlo) 163 if(use_lhlo)
164 xasprintf (&helocmd, "%s%s%s", SMTP_LHLO, localhostname, "\r\n");
165 else if(use_ehlo)
156 xasprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); 166 xasprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n");
157 else 167 else
158 xasprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); 168 xasprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n");
@@ -179,6 +189,26 @@ main (int argc, char **argv)
179 result = my_tcp_connect (server_address, server_port, &sd); 189 result = my_tcp_connect (server_address, server_port, &sd);
180 190
181 if (result == STATE_OK) { /* we connected */ 191 if (result == STATE_OK) { /* we connected */
192 /* If requested, send PROXY header */
193 if (use_proxy_prefix) {
194 if (verbose)
195 printf ("Sending header %s\n", PROXY_PREFIX);
196 my_send(PROXY_PREFIX, strlen(PROXY_PREFIX));
197 }
198
199#ifdef HAVE_SSL
200 if (use_ssl) {
201 result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL));
202 if (result != STATE_OK) {
203 printf (_("CRITICAL - Cannot create SSL context.\n"));
204 close(sd);
205 np_net_ssl_cleanup();
206 return STATE_CRITICAL;
207 } else {
208 ssl_established = 1;
209 }
210 }
211#endif
182 212
183 /* watch for the SMTP connection string and */ 213 /* watch for the SMTP connection string and */
184 /* return a WARNING status if we couldn't read any data */ 214 /* return a WARNING status if we couldn't read any data */
@@ -191,27 +221,27 @@ main (int argc, char **argv)
191 xasprintf(&server_response, "%s", buffer); 221 xasprintf(&server_response, "%s", buffer);
192 222
193 /* send the HELO/EHLO command */ 223 /* send the HELO/EHLO command */
194 send(sd, helocmd, strlen(helocmd), 0); 224 my_send(helocmd, strlen(helocmd));
195 225
196 /* allow for response to helo command to reach us */ 226 /* allow for response to helo command to reach us */
197 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { 227 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) {
198 printf (_("recv() failed\n")); 228 printf (_("recv() failed\n"));
199 return STATE_WARNING; 229 return STATE_WARNING;
200 } else if(use_ehlo){ 230 } else if(use_ehlo || use_lhlo){
201 if(strstr(buffer, "250 STARTTLS") != NULL || 231 if(strstr(buffer, "250 STARTTLS") != NULL ||
202 strstr(buffer, "250-STARTTLS") != NULL){ 232 strstr(buffer, "250-STARTTLS") != NULL){
203 supports_tls=TRUE; 233 supports_tls=TRUE;
204 } 234 }
205 } 235 }
206 236
207 if(use_ssl && ! supports_tls){ 237 if(use_starttls && ! supports_tls){
208 printf(_("WARNING - TLS not supported by server\n")); 238 printf(_("WARNING - TLS not supported by server\n"));
209 smtp_quit(); 239 smtp_quit();
210 return STATE_WARNING; 240 return STATE_WARNING;
211 } 241 }
212 242
213#ifdef HAVE_SSL 243#ifdef HAVE_SSL
214 if(use_ssl) { 244 if(use_starttls) {
215 /* send the STARTTLS command */ 245 /* send the STARTTLS command */
216 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); 246 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0);
217 247
@@ -221,7 +251,7 @@ main (int argc, char **argv)
221 smtp_quit(); 251 smtp_quit();
222 return STATE_UNKNOWN; 252 return STATE_UNKNOWN;
223 } 253 }
224 result = np_net_ssl_init(sd); 254 result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL));
225 if(result != STATE_OK) { 255 if(result != STATE_OK) {
226 printf (_("CRITICAL - Cannot create SSL context.\n")); 256 printf (_("CRITICAL - Cannot create SSL context.\n"));
227 close(sd); 257 close(sd);
@@ -450,6 +480,10 @@ process_arguments (int argc, char **argv)
450 int c; 480 int c;
451 char* temp; 481 char* temp;
452 482
483 enum {
484 SNI_OPTION
485 };
486
453 int option = 0; 487 int option = 0;
454 static struct option longopts[] = { 488 static struct option longopts[] = {
455 {"hostname", required_argument, 0, 'H'}, 489 {"hostname", required_argument, 0, 'H'},
@@ -470,9 +504,14 @@ process_arguments (int argc, char **argv)
470 {"use-ipv4", no_argument, 0, '4'}, 504 {"use-ipv4", no_argument, 0, '4'},
471 {"use-ipv6", no_argument, 0, '6'}, 505 {"use-ipv6", no_argument, 0, '6'},
472 {"help", no_argument, 0, 'h'}, 506 {"help", no_argument, 0, 'h'},
507 {"lmtp", no_argument, 0, 'L'},
508 {"ssl", no_argument, 0, 's'},
509 {"tls", no_argument, 0, 's'},
473 {"starttls",no_argument,0,'S'}, 510 {"starttls",no_argument,0,'S'},
511 {"sni", no_argument, 0, SNI_OPTION},
474 {"certificate",required_argument,0,'D'}, 512 {"certificate",required_argument,0,'D'},
475 {"ignore-quit-failure",no_argument,0,'q'}, 513 {"ignore-quit-failure",no_argument,0,'q'},
514 {"proxy",no_argument,0,'r'},
476 {0, 0, 0, 0} 515 {0, 0, 0, 0}
477 }; 516 };
478 517
@@ -489,7 +528,7 @@ process_arguments (int argc, char **argv)
489 } 528 }
490 529
491 while (1) { 530 while (1) {
492 c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:F:A:U:P:q", 531 c = getopt_long (argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q",
493 longopts, &option); 532 longopts, &option);
494 533
495 if (c == -1 || c == EOF) 534 if (c == -1 || c == EOF)
@@ -506,7 +545,7 @@ process_arguments (int argc, char **argv)
506 break; 545 break;
507 case 'p': /* port */ 546 case 'p': /* port */
508 if (is_intpos (optarg)) 547 if (is_intpos (optarg))
509 server_port = atoi (optarg); 548 server_port_option = atoi (optarg);
510 else 549 else
511 usage4 (_("Port must be a positive integer")); 550 usage4 (_("Port must be a positive integer"));
512 break; 551 break;
@@ -611,11 +650,29 @@ process_arguments (int argc, char **argv)
611#else 650#else
612 usage (_("SSL support not available - install OpenSSL and recompile")); 651 usage (_("SSL support not available - install OpenSSL and recompile"));
613#endif 652#endif
653 case 's':
654 /* ssl */
655 use_ssl = TRUE;
656 server_port = SMTPS_PORT;
657 break;
614 case 'S': 658 case 'S':
615 /* starttls */ 659 /* starttls */
616 use_ssl = TRUE; 660 use_starttls = TRUE;
617 use_ehlo = TRUE; 661 use_ehlo = TRUE;
618 break; 662 break;
663 case SNI_OPTION:
664#ifdef HAVE_SSL
665 use_sni = TRUE;
666#else
667 usage (_("SSL support not available - install OpenSSL and recompile"));
668#endif
669 break;
670 case 'r':
671 use_proxy_prefix = TRUE;
672 break;
673 case 'L':
674 use_lhlo = TRUE;
675 break;
619 case '4': 676 case '4':
620 address_family = AF_INET; 677 address_family = AF_INET;
621 break; 678 break;
@@ -659,6 +716,14 @@ process_arguments (int argc, char **argv)
659 if (from_arg==NULL) 716 if (from_arg==NULL)
660 from_arg = strdup(" "); 717 from_arg = strdup(" ");
661 718
719 if (use_starttls && use_ssl) {
720 usage4 (_("Set either -s/--ssl/--tls or -S/--starttls"));
721 }
722
723 if (server_port_option != 0) {
724 server_port = server_port_option;
725 }
726
662 return validate_arguments (); 727 return validate_arguments ();
663} 728}
664 729
@@ -811,11 +876,18 @@ print_help (void)
811 printf (" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), 876 printf (" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")),
812 printf (" %s\n", "-F, --fqdn=STRING"); 877 printf (" %s\n", "-F, --fqdn=STRING");
813 printf (" %s\n", _("FQDN used for HELO")); 878 printf (" %s\n", _("FQDN used for HELO"));
879 printf (" %s\n", "-r, --proxy");
880 printf (" %s\n", _("Use PROXY protocol prefix for the connection."));
814#ifdef HAVE_SSL 881#ifdef HAVE_SSL
815 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); 882 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]");
816 printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); 883 printf (" %s\n", _("Minimum number of days a certificate has to be valid."));
884 printf (" %s\n", "-s, --ssl, --tls");
885 printf (" %s\n", _("Use SSL/TLS for the connection."));
886 printf (_(" Sets default port to %d.\n"), SMTPS_PORT);
817 printf (" %s\n", "-S, --starttls"); 887 printf (" %s\n", "-S, --starttls");
818 printf (" %s\n", _("Use STARTTLS for the connection.")); 888 printf (" %s\n", _("Use STARTTLS for the connection."));
889 printf (" %s\n", "--sni");
890 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
819#endif 891#endif
820 892
821 printf (" %s\n", "-A, --authtype=STRING"); 893 printf (" %s\n", "-A, --authtype=STRING");
@@ -824,6 +896,8 @@ print_help (void)
824 printf (" %s\n", _("SMTP AUTH username")); 896 printf (" %s\n", _("SMTP AUTH username"));
825 printf (" %s\n", "-P, --authpass=STRING"); 897 printf (" %s\n", "-P, --authpass=STRING");
826 printf (" %s\n", _("SMTP AUTH password")); 898 printf (" %s\n", _("SMTP AUTH password"));
899 printf (" %s\n", "-L, --lmtp");
900 printf (" %s\n", _("Send LHLO instead of HELO/EHLO"));
827 printf (" %s\n", "-q, --ignore-quit-failure"); 901 printf (" %s\n", "-q, --ignore-quit-failure");
828 printf (" %s\n", _("Ignore failure when sending QUIT command to server")); 902 printf (" %s\n", _("Ignore failure when sending QUIT command to server"));
829 903
@@ -834,7 +908,7 @@ print_help (void)
834 printf (UT_VERBOSE); 908 printf (UT_VERBOSE);
835 909
836 printf("\n"); 910 printf("\n");
837 printf ("%s\n", _("Successul connects return STATE_OK, refusals and timeouts return")); 911 printf ("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return"));
838 printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful")); 912 printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful"));
839 printf ("%s\n", _("connects, but incorrect response messages from the host result in")); 913 printf ("%s\n", _("connects, but incorrect response messages from the host result in"));
840 printf ("%s\n", _("STATE_WARNING return values.")); 914 printf ("%s\n", _("STATE_WARNING return values."));
@@ -850,6 +924,6 @@ print_usage (void)
850 printf ("%s\n", _("Usage:")); 924 printf ("%s\n", _("Usage:"));
851 printf ("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname); 925 printf ("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname);
852 printf ("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n"); 926 printf ("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n");
853 printf ("[-F fqdn] [-S] [-D warn days cert expire[,crit days cert expire]] [-v] \n"); 927 printf ("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-r] [--sni] [-v] \n");
854} 928}
855 929
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index afc568b..2acada2 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -1,31 +1,31 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_snmp plugin 3* Monitoring check_snmp plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2007 Monitoring Plugins Development Team 6* Copyright (c) 1999-2007 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_snmp plugin 10* This file contains the check_snmp plugin
11* 11*
12* Check status of remote machines and obtain system information via SNMP 12* Check status of remote machines and obtain system information via SNMP
13* 13*
14* 14*
15* This program is free software: you can redistribute it and/or modify 15* This program is free software: you can redistribute it and/or modify
16* it under the terms of the GNU General Public License as published by 16* it under the terms of the GNU General Public License as published by
17* the Free Software Foundation, either version 3 of the License, or 17* the Free Software Foundation, either version 3 of the License, or
18* (at your option) any later version. 18* (at your option) any later version.
19* 19*
20* This program is distributed in the hope that it will be useful, 20* This program is distributed in the hope that it will be useful,
21* but WITHOUT ANY WARRANTY; without even the implied warranty of 21* but WITHOUT ANY WARRANTY; without even the implied warranty of
22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23* GNU General Public License for more details. 23* GNU General Public License for more details.
24* 24*
25* You should have received a copy of the GNU General Public License 25* You should have received a copy of the GNU General Public License
26* along with this program. If not, see <http://www.gnu.org/licenses/>. 26* along with this program. If not, see <http://www.gnu.org/licenses/>.
27* 27*
28* 28*
29*****************************************************************************/ 29*****************************************************************************/
30 30
31const char *progname = "check_snmp"; 31const char *progname = "check_snmp";
@@ -46,6 +46,7 @@ const char *email = "devel@monitoring-plugins.org";
46#define DEFAULT_PRIV_PROTOCOL "DES" 46#define DEFAULT_PRIV_PROTOCOL "DES"
47#define DEFAULT_DELIMITER "=" 47#define DEFAULT_DELIMITER "="
48#define DEFAULT_OUTPUT_DELIMITER " " 48#define DEFAULT_OUTPUT_DELIMITER " "
49#define DEFAULT_BUFFER_SIZE 100
49 50
50#define mark(a) ((a)!=0?"*":"") 51#define mark(a) ((a)!=0?"*":"")
51 52
@@ -64,6 +65,7 @@ const char *email = "devel@monitoring-plugins.org";
64#define L_RATE_MULTIPLIER CHAR_MAX+2 65#define L_RATE_MULTIPLIER CHAR_MAX+2
65#define L_INVERT_SEARCH CHAR_MAX+3 66#define L_INVERT_SEARCH CHAR_MAX+3
66#define L_OFFSET CHAR_MAX+4 67#define L_OFFSET CHAR_MAX+4
68#define L_IGNORE_MIB_PARSING_ERRORS CHAR_MAX+5
67 69
68/* Gobble to string - stop incrementing c when c[0] match one of the 70/* Gobble to string - stop incrementing c when c[0] match one of the
69 * characters in s */ 71 * characters in s */
@@ -90,6 +92,7 @@ char *thisarg (char *str);
90char *nextarg (char *str); 92char *nextarg (char *str);
91void print_usage (void); 93void print_usage (void);
92void print_help (void); 94void print_help (void);
95char *multiply (char *str);
93 96
94#include "regex.h" 97#include "regex.h"
95char regex_expect[MAX_INPUT_BUFFER] = ""; 98char regex_expect[MAX_INPUT_BUFFER] = "";
@@ -113,6 +116,7 @@ char *authproto = NULL;
113char *privproto = NULL; 116char *privproto = NULL;
114char *authpasswd = NULL; 117char *authpasswd = NULL;
115char *privpasswd = NULL; 118char *privpasswd = NULL;
119int nulloid = STATE_UNKNOWN;
116char **oids = NULL; 120char **oids = NULL;
117size_t oids_size = 0; 121size_t oids_size = 0;
118char *label; 122char *label;
@@ -153,6 +157,10 @@ double *previous_value;
153size_t previous_size = OID_COUNT_STEP; 157size_t previous_size = OID_COUNT_STEP;
154int perf_labels = 1; 158int perf_labels = 1;
155char* ip_version = ""; 159char* ip_version = "";
160double multiplier = 1.0;
161char *fmtstr = "";
162char buffer[DEFAULT_BUFFER_SIZE];
163bool ignore_mib_parsing_errors = false;
156 164
157static char *fix_snmp_range(char *th) 165static char *fix_snmp_range(char *th)
158{ 166{
@@ -300,42 +308,55 @@ main (int argc, char **argv)
300 } 308 }
301 309
302 /* 10 arguments to pass before context and authpriv options + 1 for host and numoids. Add one for terminating NULL */ 310 /* 10 arguments to pass before context and authpriv options + 1 for host and numoids. Add one for terminating NULL */
303 command_line = calloc (10 + numcontext + numauthpriv + 1 + numoids + 1, sizeof (char *)); 311
304 command_line[0] = snmpcmd; 312 unsigned index = 0;
305 command_line[1] = strdup ("-Le"); 313 command_line = calloc (11 + numcontext + numauthpriv + 1 + numoids + 1, sizeof (char *));
306 command_line[2] = strdup ("-t"); 314
307 xasprintf (&command_line[3], "%d", timeout_interval); 315 command_line[index++] = snmpcmd;
308 command_line[4] = strdup ("-r"); 316 command_line[index++] = strdup ("-Le");
309 xasprintf (&command_line[5], "%d", retries); 317 command_line[index++] = strdup ("-t");
310 command_line[6] = strdup ("-m"); 318 xasprintf (&command_line[index++], "%d", timeout_interval);
311 command_line[7] = strdup (miblist); 319 command_line[index++] = strdup ("-r");
312 command_line[8] = "-v"; 320 xasprintf (&command_line[index++], "%d", retries);
313 command_line[9] = strdup (proto); 321 command_line[index++] = strdup ("-m");
322 command_line[index++] = strdup (miblist);
323 command_line[index++] = "-v";
324 command_line[index++] = strdup (proto);
325
326 xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s",
327 snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto);
328
329 if (ignore_mib_parsing_errors) {
330 command_line[index++] = "-Pe";
331 xasprintf(&cl_hidden_auth, "%s -Pe", cl_hidden_auth);
332 }
333
314 334
315 for (i = 0; i < numcontext; i++) { 335 for (i = 0; i < numcontext; i++) {
316 command_line[10 + i] = contextargs[i]; 336 command_line[index++] = contextargs[i];
317 } 337 }
318 338
319 for (i = 0; i < numauthpriv; i++) { 339 for (i = 0; i < numauthpriv; i++) {
320 command_line[10 + numcontext + i] = authpriv[i]; 340 command_line[index++] = authpriv[i];
321 } 341 }
322 342
323 xasprintf (&command_line[10 + numcontext + numauthpriv], "%s:%s", server_address, port); 343 xasprintf (&command_line[index++], "%s:%s", server_address, port);
324 344
325 /* This is just for display purposes, so it can remain a string */ 345 xasprintf(&cl_hidden_auth, "%s [context] [authpriv] %s:%s",
326 xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s %s %s %s:%s", 346 cl_hidden_auth,
327 snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[context]", "[authpriv]", 347 server_address,
328 server_address, port); 348 port);
329 349
330 for (i = 0; i < numoids; i++) { 350 for (i = 0; i < numoids; i++) {
331 command_line[10 + numcontext + numauthpriv + 1 + i] = oids[i]; 351 command_line[index++] = oids[i];
332 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]); 352 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
333 } 353 }
334 354
335 command_line[10 + numcontext + numauthpriv + 1 + numoids] = NULL; 355 command_line[index++] = NULL;
336 356
337 if (verbose) 357 if (verbose) {
338 printf ("%s\n", cl_hidden_auth); 358 printf ("%s\n", cl_hidden_auth);
359 }
339 360
340 /* Set signal handling and alarm */ 361 /* Set signal handling and alarm */
341 if (signal (SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) { 362 if (signal (SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) {
@@ -375,7 +396,7 @@ main (int argc, char **argv)
375 } 396 }
376 } 397 }
377 398
378 for (line=0, i=0; line < chld_out.lines; line++, i++) { 399 for (line=0, i=0; line < chld_out.lines && i < numoids ; line++, i++) {
379 if(calculate_rate) 400 if(calculate_rate)
380 conv = "%.10g"; 401 conv = "%.10g";
381 else 402 else
@@ -397,15 +418,15 @@ main (int argc, char **argv)
397 is_counter=0; 418 is_counter=0;
398 /* We strip out the datatype indicator for PHBs */ 419 /* We strip out the datatype indicator for PHBs */
399 if (strstr (response, "Gauge: ")) { 420 if (strstr (response, "Gauge: ")) {
400 show = strstr (response, "Gauge: ") + 7; 421 show = multiply (strstr (response, "Gauge: ") + 7);
401 } 422 }
402 else if (strstr (response, "Gauge32: ")) { 423 else if (strstr (response, "Gauge32: ")) {
403 show = strstr (response, "Gauge32: ") + 9; 424 show = multiply (strstr (response, "Gauge32: ") + 9);
404 } 425 }
405 else if (strstr (response, "Counter32: ")) { 426 else if (strstr (response, "Counter32: ")) {
406 show = strstr (response, "Counter32: ") + 11; 427 show = strstr (response, "Counter32: ") + 11;
407 is_counter=1; 428 is_counter=1;
408 if(!calculate_rate) 429 if(!calculate_rate)
409 strcpy(type, "c"); 430 strcpy(type, "c");
410 } 431 }
411 else if (strstr (response, "Counter64: ")) { 432 else if (strstr (response, "Counter64: ")) {
@@ -415,7 +436,10 @@ main (int argc, char **argv)
415 strcpy(type, "c"); 436 strcpy(type, "c");
416 } 437 }
417 else if (strstr (response, "INTEGER: ")) { 438 else if (strstr (response, "INTEGER: ")) {
418 show = strstr (response, "INTEGER: ") + 9; 439 show = multiply (strstr (response, "INTEGER: ") + 9);
440 if (fmtstr != "") {
441 conv = fmtstr;
442 }
419 } 443 }
420 else if (strstr (response, "OID: ")) { 444 else if (strstr (response, "OID: ")) {
421 show = strstr (response, "OID: ") + 5; 445 show = strstr (response, "OID: ") + 5;
@@ -468,9 +492,20 @@ main (int argc, char **argv)
468 /* Process this block for numeric comparisons */ 492 /* Process this block for numeric comparisons */
469 /* Make some special values,like Timeticks numeric only if a threshold is defined */ 493 /* Make some special values,like Timeticks numeric only if a threshold is defined */
470 if (thlds[i]->warning || thlds[i]->critical || calculate_rate) { 494 if (thlds[i]->warning || thlds[i]->critical || calculate_rate) {
495 if (verbose > 2) {
496 print_thresholds(" thresholds", thlds[i]);
497 }
471 ptr = strpbrk (show, "-0123456789"); 498 ptr = strpbrk (show, "-0123456789");
472 if (ptr == NULL) 499 if (ptr == NULL){
473 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show); 500 if (nulloid == 3)
501 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show);
502 else if (nulloid == 0)
503 die (STATE_OK,_("No valid data returned (%s)\n"), show);
504 else if (nulloid == 1)
505 die (STATE_WARNING,_("No valid data returned (%s)\n"), show);
506 else if (nulloid == 2)
507 die (STATE_CRITICAL,_("No valid data returned (%s)\n"), show);
508 }
474 while (i >= response_size) { 509 while (i >= response_size) {
475 response_size += OID_COUNT_STEP; 510 response_size += OID_COUNT_STEP;
476 response_value = realloc(response_value, response_size * sizeof(*response_value)); 511 response_value = realloc(response_value, response_size * sizeof(*response_value));
@@ -581,14 +616,16 @@ main (int argc, char **argv)
581 616
582 if (warning_thresholds) { 617 if (warning_thresholds) {
583 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1); 618 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
584 strncat(perfstr, warning_thresholds, sizeof(perfstr)-strlen(perfstr)-1); 619 if(thlds[i]->warning && thlds[i]->warning->text)
620 strncat(perfstr, thlds[i]->warning->text, sizeof(perfstr)-strlen(perfstr)-1);
585 } 621 }
586 622
587 if (critical_thresholds) { 623 if (critical_thresholds) {
588 if (!warning_thresholds) 624 if (!warning_thresholds)
589 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1); 625 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
590 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1); 626 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
591 strncat(perfstr, critical_thresholds, sizeof(perfstr)-strlen(perfstr)-1); 627 if(thlds[i]->critical && thlds[i]->critical->text)
628 strncat(perfstr, thlds[i]->critical->text, sizeof(perfstr)-strlen(perfstr)-1);
592 } 629 }
593 630
594 strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1); 631 strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1);
@@ -602,7 +639,7 @@ main (int argc, char **argv)
602 state_string=malloc(string_length); 639 state_string=malloc(string_length);
603 if(state_string==NULL) 640 if(state_string==NULL)
604 die(STATE_UNKNOWN, _("Cannot malloc")); 641 die(STATE_UNKNOWN, _("Cannot malloc"));
605 642
606 current_length=0; 643 current_length=0;
607 for(i=0; i<total_oids; i++) { 644 for(i=0; i<total_oids; i++) {
608 xasprintf(&temp_string,"%.0f",response_value[i]); 645 xasprintf(&temp_string,"%.0f",response_value[i]);
@@ -624,7 +661,7 @@ main (int argc, char **argv)
624 state_string[--current_length]='\0'; 661 state_string[--current_length]='\0';
625 if (verbose > 2) 662 if (verbose > 2)
626 printf("State string=%s\n",state_string); 663 printf("State string=%s\n",state_string);
627 664
628 /* This is not strictly the same as time now, but any subtle variations will cancel out */ 665 /* This is not strictly the same as time now, but any subtle variations will cancel out */
629 np_state_write_string(current_time, state_string ); 666 np_state_write_string(current_time, state_string );
630 if(previous_state==NULL) { 667 if(previous_state==NULL) {
@@ -656,6 +693,7 @@ process_arguments (int argc, char **argv)
656 {"oid", required_argument, 0, 'o'}, 693 {"oid", required_argument, 0, 'o'},
657 {"object", required_argument, 0, 'o'}, 694 {"object", required_argument, 0, 'o'},
658 {"delimiter", required_argument, 0, 'd'}, 695 {"delimiter", required_argument, 0, 'd'},
696 {"nulloid", required_argument, 0, 'z'},
659 {"output-delimiter", required_argument, 0, 'D'}, 697 {"output-delimiter", required_argument, 0, 'D'},
660 {"string", required_argument, 0, 's'}, 698 {"string", required_argument, 0, 's'},
661 {"timeout", required_argument, 0, 't'}, 699 {"timeout", required_argument, 0, 't'},
@@ -683,6 +721,9 @@ process_arguments (int argc, char **argv)
683 {"perf-oids", no_argument, 0, 'O'}, 721 {"perf-oids", no_argument, 0, 'O'},
684 {"ipv4", no_argument, 0, '4'}, 722 {"ipv4", no_argument, 0, '4'},
685 {"ipv6", no_argument, 0, '6'}, 723 {"ipv6", no_argument, 0, '6'},
724 {"multiplier", required_argument, 0, 'M'},
725 {"fmtstr", required_argument, 0, 'f'},
726 {"ignore-mib-parsing-errors", no_argument, false, L_IGNORE_MIB_PARSING_ERRORS},
686 {0, 0, 0, 0} 727 {0, 0, 0, 0}
687 }; 728 };
688 729
@@ -700,7 +741,7 @@ process_arguments (int argc, char **argv)
700 } 741 }
701 742
702 while (1) { 743 while (1) {
703 c = getopt_long (argc, argv, "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:", 744 c = getopt_long (argc, argv, "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:M:f:z:",
704 longopts, &option); 745 longopts, &option);
705 746
706 if (c == -1 || c == EOF) 747 if (c == -1 || c == EOF)
@@ -811,6 +852,12 @@ process_arguments (int argc, char **argv)
811 eval_method[j+1] |= CRIT_PRESENT; 852 eval_method[j+1] |= CRIT_PRESENT;
812 } 853 }
813 break; 854 break;
855 case 'z': /* Null OID Return Check */
856 if (!is_integer (optarg))
857 usage2 (_("Exit status must be a positive integer"), optarg);
858 else
859 nulloid = atoi(optarg);
860 break;
814 case 's': /* string or substring */ 861 case 's': /* string or substring */
815 strncpy (string_value, optarg, sizeof (string_value) - 1); 862 strncpy (string_value, optarg, sizeof (string_value) - 1);
816 string_value[sizeof (string_value) - 1] = 0; 863 string_value[sizeof (string_value) - 1] = 0;
@@ -824,6 +871,7 @@ process_arguments (int argc, char **argv)
824 break; 871 break;
825 case 'R': /* regex */ 872 case 'R': /* regex */
826 cflags = REG_ICASE; 873 cflags = REG_ICASE;
874 // fall through
827 case 'r': /* regex */ 875 case 'r': /* regex */
828 cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; 876 cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
829 strncpy (regex_expect, optarg, sizeof (regex_expect) - 1); 877 strncpy (regex_expect, optarg, sizeof (regex_expect) - 1);
@@ -932,6 +980,18 @@ process_arguments (int argc, char **argv)
932 if(verbose>2) 980 if(verbose>2)
933 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n"); 981 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n");
934 break; 982 break;
983 case 'M':
984 if ( strspn( optarg, "0123456789.," ) == strlen( optarg ) ) {
985 multiplier=strtod(optarg,NULL);
986 }
987 break;
988 case 'f':
989 if (multiplier != 1.0) {
990 fmtstr=optarg;
991 }
992 break;
993 case L_IGNORE_MIB_PARSING_ERRORS:
994 ignore_mib_parsing_errors = true;
935 } 995 }
936 } 996 }
937 997
@@ -1001,7 +1061,7 @@ validate_arguments ()
1001 contextargs[0] = strdup ("-n"); 1061 contextargs[0] = strdup ("-n");
1002 contextargs[1] = strdup (context); 1062 contextargs[1] = strdup (context);
1003 } 1063 }
1004 1064
1005 if (seclevel == NULL) 1065 if (seclevel == NULL)
1006 xasprintf(&seclevel, "noAuthNoPriv"); 1066 xasprintf(&seclevel, "noAuthNoPriv");
1007 1067
@@ -1122,6 +1182,44 @@ nextarg (char *str)
1122 1182
1123 1183
1124 1184
1185/* multiply result (values 0 < n < 1 work as divider) */
1186char *
1187multiply (char *str)
1188{
1189 char *endptr;
1190 double val;
1191 char *conv = "%f";
1192
1193 if(multiplier == 1)
1194 return(str);
1195
1196 if(verbose>2)
1197 printf(" multiply input: %s\n", str);
1198
1199 val = strtod (str, &endptr);
1200 if ((val == 0.0) && (endptr == str)) {
1201 die(STATE_UNKNOWN, _("multiplier set (%.1f), but input is not a number: %s"), multiplier, str);
1202 }
1203
1204 if(verbose>2)
1205 printf(" multiply extracted double: %f\n", val);
1206 val *= multiplier;
1207 if (fmtstr != "") {
1208 conv = fmtstr;
1209 }
1210 if (val == (int)val) {
1211 snprintf(buffer, DEFAULT_BUFFER_SIZE, "%.0f", val);
1212 } else {
1213 if(verbose>2)
1214 printf(" multiply using format: %s\n", conv);
1215 snprintf(buffer, DEFAULT_BUFFER_SIZE, conv, val);
1216 }
1217 if(verbose>2)
1218 printf(" multiply result: %s\n", buffer);
1219 return buffer;
1220}
1221
1222
1125void 1223void
1126print_help (void) 1224print_help (void)
1127{ 1225{
@@ -1161,7 +1259,7 @@ print_help (void)
1161 printf ("(%s \"%s\")\n", _("default is") ,DEFAULT_COMMUNITY); 1259 printf ("(%s \"%s\")\n", _("default is") ,DEFAULT_COMMUNITY);
1162 printf (" %s\n", "-U, --secname=USERNAME"); 1260 printf (" %s\n", "-U, --secname=USERNAME");
1163 printf (" %s\n", _("SNMPv3 username")); 1261 printf (" %s\n", _("SNMPv3 username"));
1164 printf (" %s\n", "-A, --authpassword=PASSWORD"); 1262 printf (" %s\n", "-A, --authpasswd=PASSWORD");
1165 printf (" %s\n", _("SNMPv3 authentication password")); 1263 printf (" %s\n", _("SNMPv3 authentication password"));
1166 printf (" %s\n", "-X, --privpasswd=PASSWORD"); 1264 printf (" %s\n", "-X, --privpasswd=PASSWORD");
1167 printf (" %s\n", _("SNMPv3 privacy password")); 1265 printf (" %s\n", _("SNMPv3 privacy password"));
@@ -1176,6 +1274,14 @@ print_help (void)
1176 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER); 1274 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER);
1177 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered")); 1275 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered"));
1178 printf (" %s\n", _("to be the data that should be used in the evaluation.")); 1276 printf (" %s\n", _("to be the data that should be used in the evaluation."));
1277 printf (" %s\n", "-z, --nulloid=#");
1278 printf (" %s\n", _("If the check returns a 0 length string or NULL value"));
1279 printf (" %s\n", _("This option allows you to choose what status you want it to exit"));
1280 printf (" %s\n", _("Excluding this option renders the default exit of 3(STATE_UNKNOWN)"));
1281 printf (" %s\n", _("0 = OK"));
1282 printf (" %s\n", _("1 = WARNING"));
1283 printf (" %s\n", _("2 = CRITICAL"));
1284 printf (" %s\n", _("3 = UNKNOWN"));
1179 1285
1180 /* Tests Against Integers */ 1286 /* Tests Against Integers */
1181 printf (" %s\n", "-w, --warning=THRESHOLD(s)"); 1287 printf (" %s\n", "-w, --warning=THRESHOLD(s)");
@@ -1187,7 +1293,7 @@ print_help (void)
1187 printf (" %s\n", "--rate-multiplier"); 1293 printf (" %s\n", "--rate-multiplier");
1188 printf (" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute")); 1294 printf (" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute"));
1189 printf (" %s\n", "--offset=OFFSET"); 1295 printf (" %s\n", "--offset=OFFSET");
1190 printf (" %s\n", _("Add/substract the specified OFFSET to numeric sensor data")); 1296 printf (" %s\n", _("Add/subtract the specified OFFSET to numeric sensor data"));
1191 1297
1192 /* Tests Against Strings */ 1298 /* Tests Against Strings */
1193 printf (" %s\n", "-s, --string=STRING"); 1299 printf (" %s\n", "-s, --string=STRING");
@@ -1206,6 +1312,10 @@ print_help (void)
1206 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.').")); 1312 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.')."));
1207 printf (" %s\n", "-D, --output-delimiter=STRING"); 1313 printf (" %s\n", "-D, --output-delimiter=STRING");
1208 printf (" %s\n", _("Separates output on multiple OID requests")); 1314 printf (" %s\n", _("Separates output on multiple OID requests"));
1315 printf (" %s\n", "-M, --multiplier=FLOAT");
1316 printf (" %s\n", _("Multiplies current value, 0 < n < 1 works as divider, defaults to 1"));
1317 printf (" %s\n", "-f, --fmtstr=STRING");
1318 printf (" %s\n", _("C-style format string for float values (see option -M)"));
1209 1319
1210 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1320 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
1211 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5")); 1321 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5"));
@@ -1215,6 +1325,9 @@ print_help (void)
1215 printf (" %s\n", "-O, --perf-oids"); 1325 printf (" %s\n", "-O, --perf-oids");
1216 printf (" %s\n", _("Label performance data with OIDs instead of --label's")); 1326 printf (" %s\n", _("Label performance data with OIDs instead of --label's"));
1217 1327
1328 printf (" %s\n", "--ignore-mib-parsing-errors");
1329 printf (" %s\n", _("Tell snmpget to not print errors encountered when parsing MIB files"));
1330
1218 printf (UT_VERBOSE); 1331 printf (UT_VERBOSE);
1219 1332
1220 printf ("\n"); 1333 printf ("\n");
@@ -1258,4 +1371,5 @@ print_usage (void)
1258 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n"); 1371 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n");
1259 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n"); 1372 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n");
1260 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n"); 1373 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n");
1374 printf ("[-M multiplier [-f format]]\n");
1261} 1375}
diff --git a/plugins/check_swap.c b/plugins/check_swap.c
index 685c2cc..cd965e3 100644
--- a/plugins/check_swap.c
+++ b/plugins/check_swap.c
@@ -1,30 +1,30 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_swap plugin 3* Monitoring check_swap plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) 6* Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net)
7* Copyright (c) 2000-2007 Monitoring Plugins Development Team 7* Copyright (c) 2000-2007 Monitoring Plugins Development Team
8* 8*
9* Description: 9* Description:
10* 10*
11* This file contains the check_swap plugin 11* This file contains the check_swap plugin
12* 12*
13* 13*
14* This program is free software: you can redistribute it and/or modify 14* This program is free software: you can redistribute it and/or modify
15* it under the terms of the GNU General Public License as published by 15* it under the terms of the GNU General Public License as published by
16* the Free Software Foundation, either version 3 of the License, or 16* the Free Software Foundation, either version 3 of the License, or
17* (at your option) any later version. 17* (at your option) any later version.
18* 18*
19* This program is distributed in the hope that it will be useful, 19* This program is distributed in the hope that it will be useful,
20* but WITHOUT ANY WARRANTY; without even the implied warranty of 20* but WITHOUT ANY WARRANTY; without even the implied warranty of
21* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22* GNU General Public License for more details. 22* GNU General Public License for more details.
23* 23*
24* You should have received a copy of the GNU General Public License 24* You should have received a copy of the GNU General Public License
25* along with this program. If not, see <http://www.gnu.org/licenses/>. 25* along with this program. If not, see <http://www.gnu.org/licenses/>.
26* 26*
27* 27*
28*****************************************************************************/ 28*****************************************************************************/
29 29
30const char *progname = "check_swap"; 30const char *progname = "check_swap";
@@ -34,9 +34,6 @@ const char *email = "devel@monitoring-plugins.org";
34#include "common.h" 34#include "common.h"
35#include "popen.h" 35#include "popen.h"
36#include "utils.h" 36#include "utils.h"
37#include <string.h>
38#include <math.h>
39#include <libintl.h>
40 37
41#ifdef HAVE_DECL_SWAPCTL 38#ifdef HAVE_DECL_SWAPCTL
42# ifdef HAVE_SYS_PARAM_H 39# ifdef HAVE_SYS_PARAM_H
@@ -142,14 +139,15 @@ main (int argc, char **argv)
142 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb)); 139 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb));
143 result = max_state (result, check_swap (dskfree_mb, dsktotal_mb)); 140 result = max_state (result, check_swap (dskfree_mb, dsktotal_mb));
144 if (verbose) 141 if (verbose)
145 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent); 142 xasprintf (&status, "%s [%lu (%d%%)]", status, dskfree_mb, 100 - percent);
146 } 143 }
147 } 144 }
145
148 /* 146 /*
149 * The following sscanf call looks for lines looking like: "SwapTotal: 123" and "SwapFree: 123" 147 * The following sscanf call looks for lines looking like: "SwapTotal: 123" and "SwapFree: 123"
150 * This format exists at least on Debian Linux with a 5.* kernel 148 * This format exists at least on Debian Linux with a 5.* kernel
151 */ 149 */
152 else if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%[TotalFre]%*[:] %lu %*[k]%*[B]", str, &tmp_KB)) { 150 else if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu %*[k]%*[B]", str, &tmp_KB)) {
153 if (verbose >= 3) { 151 if (verbose >= 3) {
154 printf("Got %s with %lu\n", str, tmp_KB); 152 printf("Got %s with %lu\n", str, tmp_KB);
155 } 153 }
@@ -158,7 +156,10 @@ main (int argc, char **argv)
158 dsktotal_mb = tmp_KB / 1024; 156 dsktotal_mb = tmp_KB / 1024;
159 } 157 }
160 else if (strcmp ("Free", str) == 0) { 158 else if (strcmp ("Free", str) == 0) {
161 dskfree_mb = tmp_KB / 1024; 159 dskfree_mb = dskfree_mb + tmp_KB / 1024;
160 }
161 else if (strcmp ("Cached", str) == 0) {
162 dskfree_mb = dskfree_mb + tmp_KB / 1024;
162 } 163 }
163 } 164 }
164 } 165 }
@@ -177,7 +178,7 @@ main (int argc, char **argv)
177# ifdef _AIX 178# ifdef _AIX
178 if (!allswaps) { 179 if (!allswaps) {
179 xasprintf(&swap_command, "%s", "/usr/sbin/lsps -s"); 180 xasprintf(&swap_command, "%s", "/usr/sbin/lsps -s");
180 xasprintf(&swap_format, "%s", "%f%*s %f"); 181 xasprintf(&swap_format, "%s", "%lu%*s %lu");
181 conv_factor = 1; 182 conv_factor = 1;
182 } 183 }
183# endif 184# endif
@@ -204,9 +205,9 @@ main (int argc, char **argv)
204 temp_buffer = strtok (input_buffer, " \n"); 205 temp_buffer = strtok (input_buffer, " \n");
205 while (temp_buffer) { 206 while (temp_buffer) {
206 if (strstr (temp_buffer, "blocks")) 207 if (strstr (temp_buffer, "blocks"))
207 sprintf (str, "%s %s", str, "%f"); 208 sprintf (str, "%s %s", str, "%lu");
208 else if (strstr (temp_buffer, "dskfree")) 209 else if (strstr (temp_buffer, "dskfree"))
209 sprintf (str, "%s %s", str, "%f"); 210 sprintf (str, "%s %s", str, "%lu");
210 else 211 else
211 sprintf (str, "%s %s", str, "%*s"); 212 sprintf (str, "%s %s", str, "%*s");
212 temp_buffer = strtok (NULL, " \n"); 213 temp_buffer = strtok (NULL, " \n");
@@ -385,7 +386,7 @@ main (int argc, char **argv)
385 TRUE, warn_print, 386 TRUE, warn_print,
386 TRUE, crit_print, 387 TRUE, crit_print,
387 TRUE, 0, 388 TRUE, 0,
388 TRUE, (long) total_swap_mb)); 389 TRUE, (long) total_swap_mb * 1024 * 1024));
389 390
390 return result; 391 return result;
391} 392}
@@ -406,7 +407,6 @@ check_swap(float free_swap_mb, float total_swap_mb)
406 uint64_t usage_percentage = ((total_swap_mb - free_swap_mb) / total_swap_mb) * 100; 407 uint64_t usage_percentage = ((total_swap_mb - free_swap_mb) / total_swap_mb) * 100;
407 408
408 if (crit.is_percentage && 409 if (crit.is_percentage &&
409 usage_percentage >= 0 &&
410 crit.value != 0 && 410 crit.value != 0 &&
411 usage_percentage >= (100 - crit.value)) 411 usage_percentage >= (100 - crit.value))
412 { 412 {
@@ -414,7 +414,6 @@ check_swap(float free_swap_mb, float total_swap_mb)
414 } 414 }
415 415
416 if (warn.is_percentage && 416 if (warn.is_percentage &&
417 usage_percentage >= 0 &&
418 warn.value != 0 && 417 warn.value != 0 &&
419 usage_percentage >= (100 - warn.value)) 418 usage_percentage >= (100 - warn.value))
420 { 419 {
@@ -471,10 +470,9 @@ process_arguments (int argc, char **argv)
471 if (is_uint64(optarg, &warn.value)) { 470 if (is_uint64(optarg, &warn.value)) {
472 if (warn.value > 100) { 471 if (warn.value > 100) {
473 usage4 (_("Warning threshold percentage must be <= 100!")); 472 usage4 (_("Warning threshold percentage must be <= 100!"));
474 } else {
475 break;
476 } 473 }
477 } 474 }
475 break;
478 } else { 476 } else {
479 /* It's Bytes */ 477 /* It's Bytes */
480 warn.is_percentage = 0; 478 warn.is_percentage = 0;
@@ -502,10 +500,9 @@ process_arguments (int argc, char **argv)
502 if (is_uint64(optarg, &crit.value)) { 500 if (is_uint64(optarg, &crit.value)) {
503 if (crit.value> 100) { 501 if (crit.value> 100) {
504 usage4 (_("Critical threshold percentage must be <= 100!")); 502 usage4 (_("Critical threshold percentage must be <= 100!"));
505 } else {
506 break;
507 } 503 }
508 } 504 }
505 break;
509 } else { 506 } else {
510 /* It's Bytes */ 507 /* It's Bytes */
511 crit.is_percentage = 0; 508 crit.is_percentage = 0;
@@ -523,6 +520,7 @@ process_arguments (int argc, char **argv)
523 if ((no_swap_state = mp_translate_state(optarg)) == ERROR) { 520 if ((no_swap_state = mp_translate_state(optarg)) == ERROR) {
524 usage4 (_("no-swap result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); 521 usage4 (_("no-swap result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
525 } 522 }
523 break;
526 case 'v': /* verbose */ 524 case 'v': /* verbose */
527 verbose++; 525 verbose++;
528 break; 526 break;
@@ -552,9 +550,12 @@ validate_arguments (void)
552 if (warn.value == 0 && crit.value == 0) { 550 if (warn.value == 0 && crit.value == 0) {
553 return ERROR; 551 return ERROR;
554 } 552 }
555 else if (warn.value < crit.value) { 553 else if ((warn.is_percentage == crit.is_percentage) && (warn.value < crit.value)) {
556 usage4 554 /* This is NOT triggered if warn and crit are different units, e.g warn is percentage
557 (_("Warning should be more than critical")); 555 * and crit is absolute. We cannot determine the condition at this point since we
556 * dont know the value of total swap yet
557 */
558 usage4(_("Warning should be more than critical"));
558 } 559 }
559 return OK; 560 return OK;
560} 561}
@@ -570,7 +571,7 @@ print_help (void)
570 571
571 printf ("%s\n", _("Check swap space on local machine.")); 572 printf ("%s\n", _("Check swap space on local machine."));
572 573
573 printf ("\n\n"); 574 printf ("\n\n");
574 575
575 print_usage (); 576 print_usage ();
576 577
@@ -578,23 +579,23 @@ print_help (void)
578 printf (UT_EXTRA_OPTS); 579 printf (UT_EXTRA_OPTS);
579 580
580 printf (" %s\n", "-w, --warning=INTEGER"); 581 printf (" %s\n", "-w, --warning=INTEGER");
581 printf (" %s\n", _("Exit with WARNING status if less than INTEGER bytes of swap space are free")); 582 printf (" %s\n", _("Exit with WARNING status if less than INTEGER bytes of swap space are free"));
582 printf (" %s\n", "-w, --warning=PERCENT%%"); 583 printf (" %s\n", "-w, --warning=PERCENT%");
583 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of swap space is free")); 584 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of swap space is free"));
584 printf (" %s\n", "-c, --critical=INTEGER"); 585 printf (" %s\n", "-c, --critical=INTEGER");
585 printf (" %s\n", _("Exit with CRITICAL status if less than INTEGER bytes of swap space are free")); 586 printf (" %s\n", _("Exit with CRITICAL status if less than INTEGER bytes of swap space are free"));
586 printf (" %s\n", "-c, --critical=PERCENT%%"); 587 printf (" %s\n", "-c, --critical=PERCENT%");
587 printf (" %s\n", _("Exit with CRITICAL status if less than PERCENT of swap space is free")); 588 printf (" %s\n", _("Exit with CRITICAL status if less than PERCENT of swap space is free"));
588 printf (" %s\n", "-a, --allswaps"); 589 printf (" %s\n", "-a, --allswaps");
589 printf (" %s\n", _("Conduct comparisons for all swap partitions, one by one")); 590 printf (" %s\n", _("Conduct comparisons for all swap partitions, one by one"));
590 printf (" %s\n", "-n, --no-swap=<ok|warning|critical|unknown>"); 591 printf (" %s\n", "-n, --no-swap=<ok|warning|critical|unknown>");
591 printf (" %s %s\n", _("Resulting state when there is no swap regardless of thresholds. Default:"), state_text(no_swap_state)); 592 printf (" %s %s\n", _("Resulting state when there is no swap regardless of thresholds. Default:"), state_text(no_swap_state));
592 printf (UT_VERBOSE); 593 printf (UT_VERBOSE);
593 594
594 printf ("\n"); 595 printf ("\n");
595 printf ("%s\n", _("Notes:")); 596 printf ("%s\n", _("Notes:"));
596 printf (" %s\n", _("Both INTEGER and PERCENT thresholds can be specified, they are all checked.")); 597 printf (" %s\n", _("Both INTEGER and PERCENT thresholds can be specified, they are all checked."));
597 printf (" %s\n", _("On AIX, if -a is specified, uses lsps -a, otherwise uses lsps -s.")); 598 printf (" %s\n", _("On AIX, if -a is specified, uses lsps -a, otherwise uses lsps -s."));
598 599
599 printf (UT_SUPPORT); 600 printf (UT_SUPPORT);
600} 601}
@@ -604,6 +605,6 @@ void
604print_usage (void) 605print_usage (void)
605{ 606{
606 printf ("%s\n", _("Usage:")); 607 printf ("%s\n", _("Usage:"));
607 printf (" %s [-av] -w <percent_free>%% -c <percent_free>%%\n",progname); 608 printf (" %s [-av] -w <percent_free>%% -c <percent_free>%%\n",progname);
608 printf (" -w <bytes_free> -c <bytes_free> [-n <state>]\n"); 609 printf (" -w <bytes_free> -c <bytes_free> [-n <state>]\n");
609} 610}
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c
index 1365b9c..1d307cf 100644
--- a/plugins/check_tcp.c
+++ b/plugins/check_tcp.c
@@ -128,7 +128,7 @@ main (int argc, char **argv)
128 SERVICE[i] = toupper(SERVICE[i]); 128 SERVICE[i] = toupper(SERVICE[i]);
129 } 129 }
130 130
131 /* set up a resonable buffer at first (will be realloc()'ed if 131 /* set up a reasonable buffer at first (will be realloc()'ed if
132 * user specifies other options) */ 132 * user specifies other options) */
133 server_expect = calloc(sizeof(char *), 2); 133 server_expect = calloc(sizeof(char *), 2);
134 134
diff --git a/plugins/check_ups.c b/plugins/check_ups.c
index e9e56a5..68737c4 100644
--- a/plugins/check_ups.c
+++ b/plugins/check_ups.c
@@ -89,7 +89,7 @@ char *ups_status;
89int temp_output_c = 0; 89int temp_output_c = 0;
90 90
91int determine_status (void); 91int determine_status (void);
92int get_ups_variable (const char *, char *, size_t); 92int get_ups_variable (const char *, char *);
93 93
94int process_arguments (int, char **); 94int process_arguments (int, char **);
95int validate_arguments (void); 95int validate_arguments (void);
@@ -189,7 +189,7 @@ main (int argc, char **argv)
189 } 189 }
190 190
191 /* get the ups utility voltage if possible */ 191 /* get the ups utility voltage if possible */
192 res=get_ups_variable ("input.voltage", temp_buffer, sizeof (temp_buffer)); 192 res=get_ups_variable ("input.voltage", temp_buffer);
193 if (res == NOSUCHVAR) supported_options &= ~UPS_UTILITY; 193 if (res == NOSUCHVAR) supported_options &= ~UPS_UTILITY;
194 else if (res != OK) 194 else if (res != OK)
195 return STATE_CRITICAL; 195 return STATE_CRITICAL;
@@ -224,7 +224,7 @@ main (int argc, char **argv)
224 } 224 }
225 225
226 /* get the ups battery percent if possible */ 226 /* get the ups battery percent if possible */
227 res=get_ups_variable ("battery.charge", temp_buffer, sizeof (temp_buffer)); 227 res=get_ups_variable ("battery.charge", temp_buffer);
228 if (res == NOSUCHVAR) supported_options &= ~UPS_BATTPCT; 228 if (res == NOSUCHVAR) supported_options &= ~UPS_BATTPCT;
229 else if ( res != OK) 229 else if ( res != OK)
230 return STATE_CRITICAL; 230 return STATE_CRITICAL;
@@ -253,7 +253,7 @@ main (int argc, char **argv)
253 } 253 }
254 254
255 /* get the ups load percent if possible */ 255 /* get the ups load percent if possible */
256 res=get_ups_variable ("ups.load", temp_buffer, sizeof (temp_buffer)); 256 res=get_ups_variable ("ups.load", temp_buffer);
257 if ( res == NOSUCHVAR ) supported_options &= ~UPS_LOADPCT; 257 if ( res == NOSUCHVAR ) supported_options &= ~UPS_LOADPCT;
258 else if ( res != OK) 258 else if ( res != OK)
259 return STATE_CRITICAL; 259 return STATE_CRITICAL;
@@ -282,7 +282,7 @@ main (int argc, char **argv)
282 } 282 }
283 283
284 /* get the ups temperature if possible */ 284 /* get the ups temperature if possible */
285 res=get_ups_variable ("ups.temperature", temp_buffer, sizeof (temp_buffer)); 285 res=get_ups_variable ("ups.temperature", temp_buffer);
286 if ( res == NOSUCHVAR ) supported_options &= ~UPS_TEMP; 286 if ( res == NOSUCHVAR ) supported_options &= ~UPS_TEMP;
287 else if ( res != OK) 287 else if ( res != OK)
288 return STATE_CRITICAL; 288 return STATE_CRITICAL;
@@ -342,7 +342,7 @@ determine_status (void)
342 char *ptr; 342 char *ptr;
343 int res; 343 int res;
344 344
345 res=get_ups_variable ("ups.status", recv_buffer, sizeof (recv_buffer)); 345 res=get_ups_variable ("ups.status", recv_buffer);
346 if (res == NOSUCHVAR) return OK; 346 if (res == NOSUCHVAR) return OK;
347 if (res != STATE_OK) { 347 if (res != STATE_OK) {
348 printf ("%s\n", _("Invalid response received from host")); 348 printf ("%s\n", _("Invalid response received from host"));
@@ -388,7 +388,7 @@ determine_status (void)
388 388
389/* gets a variable value for a specific UPS */ 389/* gets a variable value for a specific UPS */
390int 390int
391get_ups_variable (const char *varname, char *buf, size_t buflen) 391get_ups_variable (const char *varname, char *buf)
392{ 392{
393 /* char command[MAX_INPUT_BUFFER]; */ 393 /* char command[MAX_INPUT_BUFFER]; */
394 char temp_buffer[MAX_INPUT_BUFFER]; 394 char temp_buffer[MAX_INPUT_BUFFER];
@@ -402,7 +402,10 @@ get_ups_variable (const char *varname, char *buf, size_t buflen)
402 402
403 /* create the command string to send to the UPS daemon */ 403 /* create the command string to send to the UPS daemon */
404 /* Add LOGOUT to avoid read failure logs */ 404 /* Add LOGOUT to avoid read failure logs */
405 sprintf (send_buffer, "GET VAR %s %s\nLOGOUT\n", ups_name, varname); 405 if (snprintf (send_buffer, sizeof(send_buffer), "GET VAR %s %s\nLOGOUT\n", ups_name, varname) >= sizeof(send_buffer)) {
406 printf("%s\n", _("UPS name to long for buffer"));
407 return ERROR;
408 }
406 409
407 /* send the command to the daemon and get a response back */ 410 /* send the command to the daemon and get a response back */
408 if (process_tcp_request 411 if (process_tcp_request
@@ -504,7 +507,7 @@ process_arguments (int argc, char **argv)
504 usage2 (_("Invalid hostname/address"), optarg); 507 usage2 (_("Invalid hostname/address"), optarg);
505 } 508 }
506 break; 509 break;
507 case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for Farenheit) */ 510 case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for Fahrenheit) */
508 temp_output_c = 1; 511 temp_output_c = 1;
509 break; 512 break;
510 case 'u': /* ups name */ 513 case 'u': /* ups name */
diff --git a/plugins/check_users.c b/plugins/check_users.c
index f6f4b36..2a9ee98 100644
--- a/plugins/check_users.c
+++ b/plugins/check_users.c
@@ -1,33 +1,33 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_users plugin 3* Monitoring check_users plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2000-2012 Monitoring Plugins Development Team 6* Copyright (c) 2000-2012 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_users plugin 10* This file contains the check_users plugin
11* 11*
12* This plugin checks the number of users currently logged in on the local 12* This plugin checks the number of users currently logged in on the local
13* system and generates an error if the number exceeds the thresholds 13* system and generates an error if the number exceeds the thresholds
14* specified. 14* specified.
15* 15*
16* 16*
17* This program is free software: you can redistribute it and/or modify 17* This program is free software: you can redistribute it and/or modify
18* it under the terms of the GNU General Public License as published by 18* it under the terms of the GNU General Public License as published by
19* the Free Software Foundation, either version 3 of the License, or 19* the Free Software Foundation, either version 3 of the License, or
20* (at your option) any later version. 20* (at your option) any later version.
21* 21*
22* This program is distributed in the hope that it will be useful, 22* This program is distributed in the hope that it will be useful,
23* but WITHOUT ANY WARRANTY; without even the implied warranty of 23* but WITHOUT ANY WARRANTY; without even the implied warranty of
24* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25* GNU General Public License for more details. 25* GNU General Public License for more details.
26* 26*
27* You should have received a copy of the GNU General Public License 27* You should have received a copy of the GNU General Public License
28* along with this program. If not, see <http://www.gnu.org/licenses/>. 28* along with this program. If not, see <http://www.gnu.org/licenses/>.
29* 29*
30* 30*
31*****************************************************************************/ 31*****************************************************************************/
32 32
33const char *progname = "check_users"; 33const char *progname = "check_users";
@@ -48,6 +48,11 @@ const char *email = "devel@monitoring-plugins.org";
48# include "popen.h" 48# include "popen.h"
49#endif 49#endif
50 50
51#ifdef HAVE_LIBSYSTEMD
52#include <systemd/sd-daemon.h>
53#include <systemd/sd-login.h>
54#endif
55
51#define possibly_set(a,b) ((a) == 0 ? (b) : 0) 56#define possibly_set(a,b) ((a) == 0 ? (b) : 0)
52 57
53int process_arguments (int, char **); 58int process_arguments (int, char **);
@@ -85,6 +90,11 @@ main (int argc, char **argv)
85 90
86 users = 0; 91 users = 0;
87 92
93#ifdef HAVE_LIBSYSTEMD
94 if (sd_booted () > 0)
95 users = sd_get_sessions (NULL);
96 else {
97#endif
88#if HAVE_WTSAPI32_H 98#if HAVE_WTSAPI32_H
89 if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 99 if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE,
90 0, 1, &wtsinfo, &wtscount)) { 100 0, 1, &wtsinfo, &wtscount)) {
@@ -156,6 +166,9 @@ main (int argc, char **argv)
156 if (spclose (child_process)) 166 if (spclose (child_process))
157 result = possibly_set (result, STATE_UNKNOWN); 167 result = possibly_set (result, STATE_UNKNOWN);
158#endif 168#endif
169#ifdef HAVE_LIBSYSTEMD
170 }
171#endif
159 172
160 /* check the user count against warning and critical thresholds */ 173 /* check the user count against warning and critical thresholds */
161 result = get_status((double)users, thlds); 174 result = get_status((double)users, thlds);
@@ -163,7 +176,7 @@ main (int argc, char **argv)
163 if (result == STATE_UNKNOWN) 176 if (result == STATE_UNKNOWN)
164 printf ("%s\n", _("Unable to read output")); 177 printf ("%s\n", _("Unable to read output"));
165 else { 178 else {
166 printf (_("USERS %s - %d users currently logged in |%s\n"), 179 printf (_("USERS %s - %d users currently logged in |%s\n"),
167 state_text(result), users, 180 state_text(result), users,
168 sperfdata_int("users", users, "", warning_range, 181 sperfdata_int("users", users, "", warning_range,
169 critical_range, TRUE, 0, FALSE, 0)); 182 critical_range, TRUE, 0, FALSE, 0));
diff --git a/plugins/picohttpparser/picohttpparser.c b/plugins/picohttpparser/picohttpparser.c
index 74ccc3e..d0bfac6 100644
--- a/plugins/picohttpparser/picohttpparser.c
+++ b/plugins/picohttpparser/picohttpparser.c
@@ -242,7 +242,7 @@ static const char *is_complete(const char *buf, const char *buf_end, size_t last
242 } while (0) 242 } while (0)
243 243
244/* returned pointer is always within [buf, buf_end), or null */ 244/* returned pointer is always within [buf, buf_end), or null */
245static const char *parse_http_version(const char *buf, const char *buf_end, int *minor_version, int *ret) 245static const char *parse_http_version(const char *buf, const char *buf_end, int *major_version, int *minor_version, int *ret)
246{ 246{
247 /* we want at least [HTTP/1.<two chars>] to try to parse */ 247 /* we want at least [HTTP/1.<two chars>] to try to parse */
248 if (buf_end - buf < 9) { 248 if (buf_end - buf < 9) {
@@ -254,9 +254,13 @@ static const char *parse_http_version(const char *buf, const char *buf_end, int
254 EXPECT_CHAR_NO_CHECK('T'); 254 EXPECT_CHAR_NO_CHECK('T');
255 EXPECT_CHAR_NO_CHECK('P'); 255 EXPECT_CHAR_NO_CHECK('P');
256 EXPECT_CHAR_NO_CHECK('/'); 256 EXPECT_CHAR_NO_CHECK('/');
257 EXPECT_CHAR_NO_CHECK('1'); 257 PARSE_INT(major_version, 1);
258 EXPECT_CHAR_NO_CHECK('.'); 258 if (*major_version == 1) {
259 PARSE_INT(minor_version, 1); 259 EXPECT_CHAR_NO_CHECK('.');
260 PARSE_INT(minor_version, 1);
261 } else {
262 *minor_version = 0;
263 }
260 return buf; 264 return buf;
261} 265}
262 266
@@ -339,7 +343,7 @@ static const char *parse_headers(const char *buf, const char *buf_end, struct ph
339} 343}
340 344
341static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path, 345static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path,
342 size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, 346 size_t *path_len, int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers,
343 size_t max_headers, int *ret) 347 size_t max_headers, int *ret)
344{ 348{
345 /* skip first empty line (some clients add CRLF after POST content) */ 349 /* skip first empty line (some clients add CRLF after POST content) */
@@ -364,7 +368,7 @@ static const char *parse_request(const char *buf, const char *buf_end, const cha
364 *ret = -1; 368 *ret = -1;
365 return NULL; 369 return NULL;
366 } 370 }
367 if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { 371 if ((buf = parse_http_version(buf, buf_end, major_version, minor_version, ret)) == NULL) {
368 return NULL; 372 return NULL;
369 } 373 }
370 if (*buf == '\015') { 374 if (*buf == '\015') {
@@ -381,7 +385,7 @@ static const char *parse_request(const char *buf, const char *buf_end, const cha
381} 385}
382 386
383int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path, 387int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path,
384 size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len) 388 size_t *path_len, int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len)
385{ 389{
386 const char *buf = buf_start, *buf_end = buf_start + len; 390 const char *buf = buf_start, *buf_end = buf_start + len;
387 size_t max_headers = *num_headers; 391 size_t max_headers = *num_headers;
@@ -391,16 +395,17 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si
391 *method_len = 0; 395 *method_len = 0;
392 *path = NULL; 396 *path = NULL;
393 *path_len = 0; 397 *path_len = 0;
398 *major_version = -1;
394 *minor_version = -1; 399 *minor_version = -1;
395 *num_headers = 0; 400 *num_headers = 0;
396 401
397 /* if last_len != 0, check if the request is complete (a fast countermeasure 402 /* if last_len != 0, check if the request is complete (a fast countermeasure
398 againt slowloris */ 403 against slowloris */
399 if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) { 404 if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) {
400 return r; 405 return r;
401 } 406 }
402 407
403 if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, minor_version, headers, num_headers, max_headers, 408 if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, major_version, minor_version, headers, num_headers, max_headers,
404 &r)) == NULL) { 409 &r)) == NULL) {
405 return r; 410 return r;
406 } 411 }
@@ -408,11 +413,11 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si
408 return (int)(buf - buf_start); 413 return (int)(buf - buf_start);
409} 414}
410 415
411static const char *parse_response(const char *buf, const char *buf_end, int *minor_version, int *status, const char **msg, 416static const char *parse_response(const char *buf, const char *buf_end, int *major_version, int *minor_version, int *status, const char **msg,
412 size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret) 417 size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret)
413{ 418{
414 /* parse "HTTP/1.x" */ 419 /* parse "HTTP/1.x" */
415 if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { 420 if ((buf = parse_http_version(buf, buf_end, major_version, minor_version, ret)) == NULL) {
416 return NULL; 421 return NULL;
417 } 422 }
418 /* skip space */ 423 /* skip space */
@@ -430,7 +435,7 @@ static const char *parse_response(const char *buf, const char *buf_end, int *min
430 } 435 }
431 PARSE_INT_3(status); 436 PARSE_INT_3(status);
432 437
433 /* get message includig preceding space */ 438 /* get message including preceding space */
434 if ((buf = get_token_to_eol(buf, buf_end, msg, msg_len, ret)) == NULL) { 439 if ((buf = get_token_to_eol(buf, buf_end, msg, msg_len, ret)) == NULL) {
435 return NULL; 440 return NULL;
436 } 441 }
@@ -451,13 +456,14 @@ static const char *parse_response(const char *buf, const char *buf_end, int *min
451 return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); 456 return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret);
452} 457}
453 458
454int phr_parse_response(const char *buf_start, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, 459int phr_parse_response(const char *buf_start, size_t len, int *major_version, int *minor_version, int *status, const char **msg, size_t *msg_len,
455 struct phr_header *headers, size_t *num_headers, size_t last_len) 460 struct phr_header *headers, size_t *num_headers, size_t last_len)
456{ 461{
457 const char *buf = buf_start, *buf_end = buf + len; 462 const char *buf = buf_start, *buf_end = buf + len;
458 size_t max_headers = *num_headers; 463 size_t max_headers = *num_headers;
459 int r; 464 int r;
460 465
466 *major_version = -1;
461 *minor_version = -1; 467 *minor_version = -1;
462 *status = 0; 468 *status = 0;
463 *msg = NULL; 469 *msg = NULL;
@@ -470,7 +476,7 @@ int phr_parse_response(const char *buf_start, size_t len, int *minor_version, in
470 return r; 476 return r;
471 } 477 }
472 478
473 if ((buf = parse_response(buf, buf_end, minor_version, status, msg, msg_len, headers, num_headers, max_headers, &r)) == NULL) { 479 if ((buf = parse_response(buf, buf_end, major_version, minor_version, status, msg, msg_len, headers, num_headers, max_headers, &r)) == NULL) {
474 return r; 480 return r;
475 } 481 }
476 482
diff --git a/plugins/picohttpparser/picohttpparser.h b/plugins/picohttpparser/picohttpparser.h
index 0849f84..8f13b36 100644
--- a/plugins/picohttpparser/picohttpparser.h
+++ b/plugins/picohttpparser/picohttpparser.h
@@ -49,10 +49,10 @@ struct phr_header {
49/* returns number of bytes consumed if successful, -2 if request is partial, 49/* returns number of bytes consumed if successful, -2 if request is partial,
50 * -1 if failed */ 50 * -1 if failed */
51int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, 51int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len,
52 int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len); 52 int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len);
53 53
54/* ditto */ 54/* ditto */
55int phr_parse_response(const char *_buf, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, 55int phr_parse_response(const char *_buf, size_t len, int *major_version, int *minor_version, int *status, const char **msg, size_t *msg_len,
56 struct phr_header *headers, size_t *num_headers, size_t last_len); 56 struct phr_header *headers, size_t *num_headers, size_t last_len);
57 57
58/* ditto */ 58/* ditto */
diff --git a/plugins/popen.c b/plugins/popen.c
index 9eb49b6..723817d 100644
--- a/plugins/popen.c
+++ b/plugins/popen.c
@@ -14,7 +14,7 @@
14* FILE * spopen(const char *); 14* FILE * spopen(const char *);
15* int spclose(FILE *); 15* int spclose(FILE *);
16* 16*
17* Code taken with liitle modification from "Advanced Programming for the Unix 17* Code taken with little modification from "Advanced Programming for the Unix
18* Environment" by W. Richard Stevens 18* Environment" by W. Richard Stevens
19* 19*
20* This is considered safe in that no shell is spawned, and the environment 20* This is considered safe in that no shell is spawned, and the environment
diff --git a/plugins/runcmd.c b/plugins/runcmd.c
index a7155d2..c1d675d 100644
--- a/plugins/runcmd.c
+++ b/plugins/runcmd.c
@@ -44,6 +44,8 @@
44# include <sys/wait.h> 44# include <sys/wait.h>
45#endif 45#endif
46 46
47#include "./utils.h"
48
47/** macros **/ 49/** macros **/
48#ifndef WEXITSTATUS 50#ifndef WEXITSTATUS
49# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) 51# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
@@ -203,7 +205,7 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
203 } 205 }
204 206
205 /* parent picks up execution here */ 207 /* parent picks up execution here */
206 /* close childs descriptors in our address space */ 208 /* close children descriptors in our address space */
207 close(pfd[1]); 209 close(pfd[1]);
208 close(pfderr[1]); 210 close(pfderr[1]);
209 211
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index 14f6579..666a012 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -134,7 +134,16 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
134 return STATE_CRITICAL; 134 return STATE_CRITICAL;
135 } 135 }
136 if (cert && privkey) { 136 if (cert && privkey) {
137 SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM); 137#ifdef USE_OPENSSL
138 if (!SSL_CTX_use_certificate_chain_file(c, cert)) {
139#elif USE_GNUTLS
140 if (!SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM)) {
141#else
142#error Unported for unknown SSL library
143#endif
144 printf ("%s\n", _("CRITICAL - Unable to open certificate chain file!\n"));
145 return STATE_CRITICAL;
146 }
138 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM); 147 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
139#ifdef USE_OPENSSL 148#ifdef USE_OPENSSL
140 if (!SSL_CTX_check_private_key(c)) { 149 if (!SSL_CTX_check_private_key(c)) {
@@ -191,17 +200,6 @@ int np_net_ssl_read(void *buf, int num) {
191 return SSL_read(s, buf, num); 200 return SSL_read(s, buf, num);
192} 201}
193 202
194int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
195# ifdef USE_OPENSSL
196 X509 *certificate = NULL;
197 certificate=SSL_get_peer_certificate(s);
198 return(np_net_ssl_check_certificate(certificate, days_till_exp_warn, days_till_exp_crit));
199# else /* ifndef USE_OPENSSL */
200 printf("%s\n", _("WARNING - Plugin does not support checking certificates."));
201 return STATE_WARNING;
202# endif /* USE_OPENSSL */
203}
204
205int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit){ 203int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit){
206# ifdef USE_OPENSSL 204# ifdef USE_OPENSSL
207 X509_NAME *subj=NULL; 205 X509_NAME *subj=NULL;
@@ -328,4 +326,16 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int
328# endif /* USE_OPENSSL */ 326# endif /* USE_OPENSSL */
329} 327}
330 328
329int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
330# ifdef USE_OPENSSL
331 X509 *certificate = NULL;
332 certificate=SSL_get_peer_certificate(s);
333 return(np_net_ssl_check_certificate(certificate, days_till_exp_warn, days_till_exp_crit));
334# else /* ifndef USE_OPENSSL */
335 printf("%s\n", _("WARNING - Plugin does not support checking certificates."));
336 return STATE_WARNING;
337# endif /* USE_OPENSSL */
338}
339
340
331#endif /* HAVE_SSL */ 341#endif /* HAVE_SSL */
diff --git a/plugins/t/check_by_ssh.t b/plugins/t/check_by_ssh.t
index 1d2939e..b6479f1 100644
--- a/plugins/t/check_by_ssh.t
+++ b/plugins/t/check_by_ssh.t
@@ -19,19 +19,19 @@ plan skip_all => "SSH_HOST and SSH_IDENTITY must be defined" unless ($ssh_servic
19plan tests => 42; 19plan tests => 42;
20 20
21# Some random check strings/response 21# Some random check strings/response
22my @responce = ('OK: Everything is fine', 22my @response = ('OK: Everything is fine',
23 'WARNING: Hey, pick me, pick me', 23 'WARNING: Hey, pick me, pick me',
24 'CRITICAL: Shit happens', 24 'CRITICAL: Shit happens',
25 'UNKNOWN: What can I do for ya', 25 'UNKNOWN: What can I do for ya',
26 'WOOPS: What did I smoke', 26 'WOOPS: What did I smoke',
27); 27);
28my @responce_re; 28my @response_re;
29my @check; 29my @check;
30for (@responce) { 30for (@response) {
31 push(@check, "echo $_"); 31 push(@check, "echo $_");
32 my $re_str = $_; 32 my $re_str = $_;
33 $re_str =~ s{(.)} { "\Q$1" }ge; 33 $re_str =~ s{(.)} { "\Q$1" }ge;
34 push(@responce_re, $re_str); 34 push(@response_re, $re_str);
35} 35}
36 36
37my $result; 37my $result;
@@ -47,7 +47,7 @@ for (my $i=0; $i<4; $i++) {
47 "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[$i]; exit $i'" 47 "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[$i]; exit $i'"
48 ); 48 );
49 cmp_ok($result->return_code, '==', $i, "Exit with return code $i"); 49 cmp_ok($result->return_code, '==', $i, "Exit with return code $i");
50 is($result->output, $responce[$i], "Status text is correct for check $i"); 50 is($result->output, $response[$i], "Status text is correct for check $i");
51} 51}
52 52
53$result = NPTest->testCmd( 53$result = NPTest->testCmd(
@@ -84,7 +84,7 @@ $result = NPTest->testCmd(
84 "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[4]; exit 8'" 84 "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[4]; exit 8'"
85 ); 85 );
86cmp_ok($result->return_code, '==', 8, "Exit with return code 8 (out of bounds)"); 86cmp_ok($result->return_code, '==', 8, "Exit with return code 8 (out of bounds)");
87is($result->output, $responce[4], "Return proper status text even with unknown status codes"); 87is($result->output, $response[4], "Return proper status text even with unknown status codes");
88 88
89$result = NPTest->testCmd( 89$result = NPTest->testCmd(
90 "./check_by_ssh -i $ssh_key -H $ssh_service -F $ssh_conf -C 'exit 0'" 90 "./check_by_ssh -i $ssh_key -H $ssh_service -F $ssh_conf -C 'exit 0'"
@@ -108,7 +108,7 @@ my %linemap = (
108foreach my $line (0, 2, 4, 6) { 108foreach my $line (0, 2, 4, 6) {
109 my $code = $linemap{$line}; 109 my $code = $linemap{$line};
110 my $statline = $line+1; 110 my $statline = $line+1;
111 is($lines[$line], "$responce[$code]", "multiple checks status text is correct for line $line"); 111 is($lines[$line], "$response[$code]", "multiple checks status text is correct for line $line");
112 is($lines[$statline], "STATUS CODE: $code", "multiple check status code is correct for line $line"); 112 is($lines[$statline], "STATUS CODE: $code", "multiple check status code is correct for line $line");
113} 113}
114 114
@@ -124,7 +124,7 @@ close(PASV) or die("Unable to close '/tmp/check_by_ssh.$$': $!");
124cmp_ok(scalar(@pasv), '==', 1, 'One passive result for one check performed'); 124cmp_ok(scalar(@pasv), '==', 1, 'One passive result for one check performed');
125for (0) { 125for (0) {
126 if ($pasv[$_]) { 126 if ($pasv[$_]) {
127 like($pasv[$_], '/^\[\d+\] PROCESS_SERVICE_CHECK_RESULT;flint;serv;2;' . $responce_re[2] . '$/', 'proper result for passive check'); 127 like($pasv[$_], '/^\[\d+\] PROCESS_SERVICE_CHECK_RESULT;flint;serv;2;' . $response_re[2] . '$/', 'proper result for passive check');
128 } else { 128 } else {
129 fail('proper result for passive check'); 129 fail('proper result for passive check');
130 } 130 }
@@ -144,7 +144,7 @@ for (0, 1, 2, 3, 4) {
144 if ($pasv[$_]) { 144 if ($pasv[$_]) {
145 my $ret = $_; 145 my $ret = $_;
146 $ret = 9 if ($_ == 4); 146 $ret = 9 if ($_ == 4);
147 like($pasv[$_], '/^\[\d+\] PROCESS_SERVICE_CHECK_RESULT;flint;c' . $_ . ';' . $ret . ';' . $responce_re[$_] . '$/', "proper result for passive check $_"); 147 like($pasv[$_], '/^\[\d+\] PROCESS_SERVICE_CHECK_RESULT;flint;c' . $_ . ';' . $ret . ';' . $response_re[$_] . '$/', "proper result for passive check $_");
148 } else { 148 } else {
149 fail("proper result for passive check $_"); 149 fail("proper result for passive check $_");
150 } 150 }
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t
index 45ee533..eae98cc 100644
--- a/plugins/t/check_curl.t
+++ b/plugins/t/check_curl.t
@@ -1,15 +1,22 @@
1#! /usr/bin/perl -w -I .. 1#! /usr/bin/perl -w -I ..
2# 2#
3# HyperText Transfer Protocol (HTTP) Test via check_http 3# HyperText Transfer Protocol (HTTP) Test via check_curl
4# 4#
5# 5#
6 6
7use strict; 7use strict;
8use Test::More; 8use Test::More;
9use POSIX qw/mktime strftime/; 9use POSIX qw/mktime strftime/;
10use NPTest;
11 10
12plan tests => 58; 11use vars qw($tests $has_ipv6);
12
13BEGIN {
14 use NPTest;
15 $has_ipv6 = NPTest::has_ipv6();
16 $tests = $has_ipv6 ? 59 : 57;
17 plan tests => $tests;
18}
19
13 20
14my $successOutput = '/OK.*HTTP.*second/'; 21my $successOutput = '/OK.*HTTP.*second/';
15 22
@@ -18,6 +25,7 @@ my $plugin = 'check_http';
18$plugin = 'check_curl' if $0 =~ m/check_curl/mx; 25$plugin = 'check_curl' if $0 =~ m/check_curl/mx;
19 26
20my $host_tcp_http = getTestParameter("NP_HOST_TCP_HTTP", "A host providing the HTTP Service (a web server)", "localhost"); 27my $host_tcp_http = getTestParameter("NP_HOST_TCP_HTTP", "A host providing the HTTP Service (a web server)", "localhost");
28my $host_tcp_http_ipv6 = getTestParameter("NP_HOST_TCP_HTTP_IPV6", "An IPv6 address providing a HTTP Service (a web server)", "::1");
21my $host_tls_http = getTestParameter("NP_HOST_TLS_HTTP", "A host providing the HTTPS Service (a tls web server)", "localhost"); 29my $host_tls_http = getTestParameter("NP_HOST_TLS_HTTP", "A host providing the HTTPS Service (a tls web server)", "localhost");
22my $host_tls_cert = getTestParameter("NP_HOST_TLS_CERT", "the common name of the certificate.", "localhost"); 30my $host_tls_cert = getTestParameter("NP_HOST_TLS_CERT", "the common name of the certificate.", "localhost");
23my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1"); 31my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1");
@@ -31,26 +39,35 @@ my $faketime = -x '/usr/bin/faketime' ? 1 : 0;
31 39
32 40
33$res = NPTest->testCmd( 41$res = NPTest->testCmd(
34 "./$plugin $host_tcp_http -wt 300 -ct 600" 42 "./$plugin $host_tcp_http -wt 300 -ct 600"
35 ); 43 );
36cmp_ok( $res->return_code, '==', 0, "Webserver $host_tcp_http responded" ); 44cmp_ok( $res->return_code, '==', 0, "Webserver $host_tcp_http responded" );
37like( $res->output, $successOutput, "Output OK" ); 45like( $res->output, $successOutput, "Output OK" );
38 46
47if ($has_ipv6) {
48 # Test for IPv6 formatting
49 $res = NPTest->testCmd(
50 "./$plugin -I $host_tcp_http_ipv6 -wt 300 -ct 600"
51 );
52 cmp_ok( $res->return_code, '==', 0, "IPv6 URL formatting is working" );
53 like( $res->output, $successOutput, "Output OK" );
54}
55
39$res = NPTest->testCmd( 56$res = NPTest->testCmd(
40 "./$plugin $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there' -k 'carl:frown'" 57 "./$plugin $host_tcp_http -wt 300 -ct 600 -v -v -v -k 'bob:there' -k 'carl:frown'"
41 ); 58 );
42like( $res->output, '/bob:there\r\ncarl:frown\r\n/', "Got headers with multiple -k options" ); 59like( $res->output, '/bob:there\r\ncarl:frown\r\n/', "Got headers with multiple -k options" );
43 60
44$res = NPTest->testCmd( 61$res = NPTest->testCmd(
45 "./$plugin $host_nonresponsive -wt 1 -ct 2 -t 3" 62 "./$plugin $host_nonresponsive -wt 1 -ct 2 -t 3"
46 ); 63 );
47cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" ); 64cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" );
48# was CRITICAL only, but both check_curl and check_http print HTTP CRITICAL (puzzle?!) 65# was CRITICAL only, but both check_curl and check_http print HTTP CRITICAL (puzzle?!)
49like( $res->output, "/HTTP CRITICAL - Invalid HTTP response received from host on port 80: cURL returned 28 - Connection timed out after/", "Output OK"); 66like( $res->output, "/HTTP CRITICAL - Invalid HTTP response received from host on port 80: cURL returned 28 - Connection timed out after/", "Output OK");
50 67
51$res = NPTest->testCmd( 68$res = NPTest->testCmd(
52 "./$plugin $hostname_invalid -wt 1 -ct 2" 69 "./$plugin $hostname_invalid -wt 1 -ct 2"
53 ); 70 );
54cmp_ok( $res->return_code, '==', 2, "Webserver $hostname_invalid not valid" ); 71cmp_ok( $res->return_code, '==', 2, "Webserver $hostname_invalid not valid" );
55# The first part of the message comes from the OS catalogue, so cannot check this. 72# The first part of the message comes from the OS catalogue, so cannot check this.
56# On Debian, it is Name or service not known, on Darwin, it is No address associated with nodename 73# On Debian, it is Name or service not known, on Darwin, it is No address associated with nodename
@@ -95,7 +112,7 @@ SKIP: {
95 $res = NPTest->testCmd("./$plugin -v -H $host_tls_http:443 -S -p 443"); 112 $res = NPTest->testCmd("./$plugin -v -H $host_tls_http:443 -S -p 443");
96 like( $res->output, '/^Host: '.$host_tls_http.'\s*$/ms', "Host Header OK" ); 113 like( $res->output, '/^Host: '.$host_tls_http.'\s*$/ms', "Host Header OK" );
97 114
98 $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -D -p 443"); 115 $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -D -S -p 443");
99 like( $res->output, '/(^Host: '.$host_tls_http.'\s*$)|(cURL returned 60)/ms', "Host Header OK" ); 116 like( $res->output, '/(^Host: '.$host_tls_http.'\s*$)|(cURL returned 60)/ms', "Host Header OK" );
100}; 117};
101 118
@@ -188,11 +205,6 @@ SKIP: {
188 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); 205 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
189 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); 206 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' );
190 207
191 $res = NPTest->testCmd(
192 "./$plugin --ssl -H www.e-paycobalt.com"
193 );
194 cmp_ok( $res->return_code, "==", 0, "Can read https for www.e-paycobalt.com (uses AES certificate)" );
195
196 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f curl" ); 208 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f curl" );
197 is( $res->return_code, 0, "Redirection based on location is okay"); 209 is( $res->return_code, 0, "Redirection based on location is okay");
198 210
diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t
index ec527e7..ca035ce 100644
--- a/plugins/t/check_disk.t
+++ b/plugins/t/check_disk.t
@@ -23,7 +23,7 @@ my $mountpoint2_valid = getTestParameter( "NP_MOUNTPOINT2_VALID", "Path to anoth
23if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { 23if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") {
24 plan skip_all => "Need 2 mountpoints to test"; 24 plan skip_all => "Need 2 mountpoints to test";
25} else { 25} else {
26 plan tests => 78; 26 plan tests => 88;
27} 27}
28 28
29$result = NPTest->testCmd( 29$result = NPTest->testCmd(
@@ -326,19 +326,19 @@ cmp_ok( $result->return_code, '==', 0, "grouping: exit ok if the sum of free meg
326$result = NPTest->testCmd( "./check_disk -w ". ($free_mb_on_all - 1) ." -c ". ($free_mb_on_all - 1) ." -p $mountpoint_valid -g group -p $mountpoint2_valid" ); 326$result = NPTest->testCmd( "./check_disk -w ". ($free_mb_on_all - 1) ." -c ". ($free_mb_on_all - 1) ." -p $mountpoint_valid -g group -p $mountpoint2_valid" );
327cmp_ok( $result->return_code, '==', 3, "Invalid options: -p must come after groupname"); 327cmp_ok( $result->return_code, '==', 3, "Invalid options: -p must come after groupname");
328 328
329# regex: exit unknown if given regex is not compileable 329# regex: exit unknown if given regex is not compilable
330$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -r '('" ); 330$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -r '('" );
331cmp_ok( $result->return_code, '==', 3, "Exit UNKNOWN if regex is not compileable"); 331cmp_ok( $result->return_code, '==', 3, "Exit UNKNOWN if regex is not compilable");
332 332
333# ignore: exit unknown, if all pathes are deselected using -i 333# ignore: exit unknown, if all paths are deselected using -i
334$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '$mountpoint_valid' -i '$mountpoint2_valid'" ); 334$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '$mountpoint_valid' -i '$mountpoint2_valid'" );
335cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored (case sensitive)"); 335cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored (case sensitive)");
336 336
337# ignore: exit unknown, if all pathes are deselected using -I 337# ignore: exit unknown, if all paths are deselected using -I
338$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -I '".uc($mountpoint_valid)."' -I '".uc($mountpoint2_valid)."'" ); 338$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -I '".uc($mountpoint_valid)."' -I '".uc($mountpoint2_valid)."'" );
339cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored (case insensitive)"); 339cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored (case insensitive)");
340 340
341# ignore: exit unknown, if all pathes are deselected using -i 341# ignore: exit unknown, if all paths are deselected using -i
342$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '.*'" ); 342$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '.*'" );
343cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored using -i '.*'"); 343cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored using -i '.*'");
344 344
@@ -347,7 +347,32 @@ $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mo
347like( $result->output, qr/$mountpoint_valid/, "output data does have $mountpoint_valid in it"); 347like( $result->output, qr/$mountpoint_valid/, "output data does have $mountpoint_valid in it");
348unlike( $result->output, qr/$mountpoint2_valid/, "output data does not have $mountpoint2_valid in it"); 348unlike( $result->output, qr/$mountpoint2_valid/, "output data does not have $mountpoint2_valid in it");
349 349
350# ignore: test if all pathes are listed when ignore regex doesn't match 350# ignore: test if all paths are listed when ignore regex doesn't match
351$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '^barbazJodsf\$'"); 351$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '^barbazJodsf\$'");
352like( $result->output, qr/$mountpoint_valid/, "ignore: output data does have $mountpoint_valid when regex doesn't match"); 352like( $result->output, qr/$mountpoint_valid/, "ignore: output data does have $mountpoint_valid when regex doesn't match");
353like( $result->output, qr/$mountpoint2_valid/,"ignore: output data does have $mountpoint2_valid when regex doesn't match"); 353like( $result->output, qr/$mountpoint2_valid/,"ignore: output data does have $mountpoint2_valid when regex doesn't match");
354
355# ignore-missing: exit okay, when fs is not accessible
356$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p /bob");
357cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for not existing filesystem /bob");
358like( $result->output, '/^DISK OK - No disks were found for provided parameters; - ignored paths: /bob;.*$/', 'Output OK');
359
360# ignore-missing: exit okay, when regex does not match
361$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r /bob");
362cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching");
363like( $result->output, '/^DISK OK - No disks were found for provided parameters;.*$/', 'Output OK');
364
365# ignore-missing: exit okay, when fs with exact match (-E) is not found
366$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -E -p /etc");
367cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay when exact match does not find fs");
368like( $result->output, '/^DISK OK - No disks were found for provided parameters; - ignored paths: /etc;.*$/', 'Output OK');
369
370# ignore-missing: exit okay, when checking one existing fs and one non-existing fs (regex)
371$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r '/bob' -r '^/\$'");
372cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching");
373like( $result->output, '/^DISK OK - free space: \/ .*$/', 'Output OK');
374
375# ignore-missing: exit okay, when checking one existing fs and one non-existing fs (path)
376$result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p '/bob' -p '/'");
377cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching");
378like( $result->output, '/^DISK OK - free space: / .*; - ignored paths: /bob;.*$/', 'Output OK'); \ No newline at end of file
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t
index c137f7b..1f2fbdf 100644
--- a/plugins/t/check_http.t
+++ b/plugins/t/check_http.t
@@ -9,7 +9,7 @@ use Test::More;
9use POSIX qw/mktime strftime/; 9use POSIX qw/mktime strftime/;
10use NPTest; 10use NPTest;
11 11
12plan tests => 50; 12plan tests => 49;
13 13
14my $successOutput = '/OK.*HTTP.*second/'; 14my $successOutput = '/OK.*HTTP.*second/';
15 15
@@ -103,7 +103,7 @@ SKIP: {
103 cmp_ok( $res->return_code, "==", 0, "And also when not found"); 103 cmp_ok( $res->return_code, "==", 0, "And also when not found");
104} 104}
105SKIP: { 105SKIP: {
106 skip "No internet access", 23 if $internet_access eq "no"; 106 skip "No internet access", 22 if $internet_access eq "no";
107 107
108 $res = NPTest->testCmd( 108 $res = NPTest->testCmd(
109 "./$plugin --ssl $host_tls_http" 109 "./$plugin --ssl $host_tls_http"
@@ -166,12 +166,6 @@ SKIP: {
166 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); 166 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
167 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); 167 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' );
168 168
169 $res = NPTest->testCmd(
170 "./$plugin --ssl -H www.e-paycobalt.com"
171 );
172 cmp_ok( $res->return_code, "==", 0, "Can read https for www.e-paycobalt.com (uses AES certificate)" );
173
174
175 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f follow" ); 169 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f follow" );
176 is( $res->return_code, 0, "Redirection based on location is okay"); 170 is( $res->return_code, 0, "Redirection based on location is okay");
177 171
@@ -184,13 +178,13 @@ SKIP: {
184 178
185 $res = NPTest->testCmd( "./$plugin -I $host_tcp_proxy -p $port_tcp_proxy -u http://$host_tcp_http -e 200,301,302"); 179 $res = NPTest->testCmd( "./$plugin -I $host_tcp_proxy -p $port_tcp_proxy -u http://$host_tcp_http -e 200,301,302");
186 is( $res->return_code, 0, "Proxy HTTP works"); 180 is( $res->return_code, 0, "Proxy HTTP works");
187 like($res->output, qr/OK: Status line output matched/, "Proxy HTTP Output is sufficent"); 181 like($res->output, qr/OK: Status line output matched/, "Proxy HTTP Output is sufficient");
188 182
189 $res = NPTest->testCmd( "./$plugin -I $host_tcp_proxy -p $port_tcp_proxy -H $host_tls_http -S -j CONNECT"); 183 $res = NPTest->testCmd( "./$plugin -I $host_tcp_proxy -p $port_tcp_proxy -H $host_tls_http -S -j CONNECT");
190 is( $res->return_code, 0, "Proxy HTTP CONNECT works"); 184 is( $res->return_code, 0, "Proxy HTTP CONNECT works");
191 like($res->output, qr/HTTP OK:/, "Proxy HTTP CONNECT output sufficent"); 185 like($res->output, qr/HTTP OK:/, "Proxy HTTP CONNECT output sufficient");
192 186
193 $res = NPTest->testCmd( "./$plugin -I $host_tcp_proxy -p $port_tcp_proxy -H $host_tls_http -S -j CONNECT:HEAD"); 187 $res = NPTest->testCmd( "./$plugin -I $host_tcp_proxy -p $port_tcp_proxy -H $host_tls_http -S -j CONNECT:HEAD");
194 is( $res->return_code, 0, "Proxy HTTP CONNECT works with override method"); 188 is( $res->return_code, 0, "Proxy HTTP CONNECT works with override method");
195 like($res->output, qr/HTTP OK:/, "Proxy HTTP CONNECT output sufficent"); 189 like($res->output, qr/HTTP OK:/, "Proxy HTTP CONNECT output sufficient");
196} 190}
diff --git a/plugins/t/check_load.t b/plugins/t/check_load.t
index 60837ef..bba8947 100644
--- a/plugins/t/check_load.t
+++ b/plugins/t/check_load.t
@@ -11,10 +11,12 @@ use NPTest;
11my $res; 11my $res;
12 12
13my $loadValue = "[0-9]+\.?[0-9]+"; 13my $loadValue = "[0-9]+\.?[0-9]+";
14my $successOutput = "/^LOAD OK - load average: $loadValue, $loadValue, $loadValue/"; 14my $successOutput = "/^LOAD OK - total load average: $loadValue, $loadValue, $loadValue/";
15my $failureOutput = "/^LOAD CRITICAL - load average: $loadValue, $loadValue, $loadValue/"; 15my $successScaledOutput = "/^LOAD OK - scaled load average: $loadValue, $loadValue, $loadValue - total load average: $loadValue, $loadValue, $loadValue/";
16my $failureOutput = "/^LOAD CRITICAL - total load average: $loadValue, $loadValue, $loadValue/";
17my $failurScaledOutput = "/^LOAD CRITICAL - scaled load average: $loadValue, $loadValue, $loadValue - total load average: $loadValue, $loadValue, $loadValue/";
16 18
17plan tests => 11; 19plan tests => 13;
18 20
19$res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100" ); 21$res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100" );
20cmp_ok( $res->return_code, 'eq', 0, "load not over 100"); 22cmp_ok( $res->return_code, 'eq', 0, "load not over 100");
@@ -26,7 +28,7 @@ like( $res->output, $failureOutput, "Output OK");
26 28
27$res = NPTest->testCmd( "./check_load -r -w 0,0,0 -c 0,0,0" ); 29$res = NPTest->testCmd( "./check_load -r -w 0,0,0 -c 0,0,0" );
28cmp_ok( $res->return_code, 'eq', 2, "Load over 0 with per cpu division"); 30cmp_ok( $res->return_code, 'eq', 2, "Load over 0 with per cpu division");
29like( $res->output, $failureOutput, "Output OK"); 31like( $res->output, $failurScaledOutput, "Output OK");
30 32
31$res = NPTest->testCmd( "./check_load -w 100 -c 100,110" ); 33$res = NPTest->testCmd( "./check_load -w 100 -c 100,110" );
32cmp_ok( $res->return_code, 'eq', 0, "Plugin can handle non-triplet-arguments"); 34cmp_ok( $res->return_code, 'eq', 0, "Plugin can handle non-triplet-arguments");
@@ -34,3 +36,8 @@ like( $res->output, $successOutput, "Output OK");
34like( $res->perf_output, "/load1=$loadValue;100.000;100.000/", "Test handling of non triplet thresholds (load1)"); 36like( $res->perf_output, "/load1=$loadValue;100.000;100.000/", "Test handling of non triplet thresholds (load1)");
35like( $res->perf_output, "/load5=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load5)"); 37like( $res->perf_output, "/load5=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load5)");
36like( $res->perf_output, "/load15=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load15)"); 38like( $res->perf_output, "/load15=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load15)");
39
40
41$res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100 -r" );
42cmp_ok( $res->return_code, 'eq', 0, "load not over 100");
43like( $res->output, $successScaledOutput, "Output OK");
diff --git a/plugins/t/check_mysql.t b/plugins/t/check_mysql.t
index e426bf5..baf3acc 100644
--- a/plugins/t/check_mysql.t
+++ b/plugins/t/check_mysql.t
@@ -5,7 +5,7 @@
5# 5#
6# 6#
7# These are the database permissions required for this test: 7# These are the database permissions required for this test:
8# GRANT SELECT ON $db.* TO $user@$host INDENTIFIED BY '$password'; 8# GRANT SELECT ON $db.* TO $user@$host IDENTIFIED BY '$password';
9# GRANT SUPER, REPLICATION CLIENT ON *.* TO $user@$host; 9# GRANT SUPER, REPLICATION CLIENT ON *.* TO $user@$host;
10# Check with: 10# Check with:
11# mysql -u$user -p$password -h$host $db 11# mysql -u$user -p$password -h$host $db
@@ -23,9 +23,9 @@ plan tests => 15;
23my $bad_login_output = '/Access denied for user /'; 23my $bad_login_output = '/Access denied for user /';
24my $mysqlserver = getTestParameter("NP_MYSQL_SERVER", "A MySQL Server hostname or IP with no slaves setup"); 24my $mysqlserver = getTestParameter("NP_MYSQL_SERVER", "A MySQL Server hostname or IP with no slaves setup");
25my $mysqlsocket = getTestParameter("NP_MYSQL_SOCKET", "Full path to a MySQL Server socket with no slaves setup"); 25my $mysqlsocket = getTestParameter("NP_MYSQL_SOCKET", "Full path to a MySQL Server socket with no slaves setup");
26my $mysql_login_details = getTestParameter("NP_MYSQL_LOGIN_DETAILS", "Command line parameters to specify login access (requires REPLICATION CLIENT privleges)", "-u test -ptest"); 26my $mysql_login_details = getTestParameter("NP_MYSQL_LOGIN_DETAILS", "Command line parameters to specify login access (requires REPLICATION CLIENT privileges)", "-u test -ptest");
27my $with_slave = getTestParameter("NP_MYSQL_WITH_SLAVE", "MySQL server with slaves setup"); 27my $with_slave = getTestParameter("NP_MYSQL_WITH_SLAVE", "MySQL server with slaves setup");
28my $with_slave_login = getTestParameter("NP_MYSQL_WITH_SLAVE_LOGIN", "Login details for server with slave (requires REPLICATION CLIENT privleges)", $mysql_login_details || "-u test -ptest"); 28my $with_slave_login = getTestParameter("NP_MYSQL_WITH_SLAVE_LOGIN", "Login details for server with slave (requires REPLICATION CLIENT privileges)", $mysql_login_details || "-u test -ptest");
29 29
30my $result; 30my $result;
31 31
diff --git a/plugins/t/check_mysql_query.t b/plugins/t/check_mysql_query.t
index 96899ac..c30245b 100644
--- a/plugins/t/check_mysql_query.t
+++ b/plugins/t/check_mysql_query.t
@@ -31,7 +31,7 @@ $result = NPTest->testCmd("./check_mysql_query -q 'SELECT 1+1' -H $mysqlserver $
31cmp_ok( $result->return_code, '==', 0, "Can run query"); 31cmp_ok( $result->return_code, '==', 0, "Can run query");
32 32
33$result = NPTest->testCmd("./check_mysql_query -H $mysqlserver $mysql_login_details"); 33$result = NPTest->testCmd("./check_mysql_query -H $mysqlserver $mysql_login_details");
34cmp_ok( $result->return_code, '==', 3, "Missing query parmeter"); 34cmp_ok( $result->return_code, '==', 3, "Missing query parameter");
35like( $result->output, "/Must specify a SQL query to run/", "Missing query error message"); 35like( $result->output, "/Must specify a SQL query to run/", "Missing query error message");
36 36
37$result = NPTest->testCmd("./check_mysql_query -q 'SELECT 1+1' -H $mysqlserver -u dummy -d mysql"); 37$result = NPTest->testCmd("./check_mysql_query -q 'SELECT 1+1' -H $mysqlserver -u dummy -d mysql");
diff --git a/plugins/t/check_nagios.t b/plugins/t/check_nagios.t
index 81fc24d..f38f5e9 100644
--- a/plugins/t/check_nagios.t
+++ b/plugins/t/check_nagios.t
@@ -36,7 +36,7 @@ cmp_ok( $result->return_code, '==', 1, "Log over 5 minutes old" );
36like ( $result->output, $warningOutput, "Output for warning correct" ); 36like ( $result->output, $warningOutput, "Output for warning correct" );
37 37
38my $now = time; 38my $now = time;
39# This substitution is dependant on the testcase 39# This substitution is dependent on the testcase
40system( "perl -pe 's/1133537544/$now/' $nagios1 > $nagios1.tmp" ) == 0 or die "Problem with munging $nagios1"; 40system( "perl -pe 's/1133537544/$now/' $nagios1 > $nagios1.tmp" ) == 0 or die "Problem with munging $nagios1";
41 41
42$result = NPTest->testCmd( 42$result = NPTest->testCmd(
diff --git a/plugins/t/check_smtp.t b/plugins/t/check_smtp.t
index aa6dae4..1a1ebe3 100644
--- a/plugins/t/check_smtp.t
+++ b/plugins/t/check_smtp.t
@@ -8,12 +8,14 @@ use strict;
8use Test::More; 8use Test::More;
9use NPTest; 9use NPTest;
10 10
11my $host_tcp_smtp = getTestParameter( "NP_HOST_TCP_SMTP", 11my $host_tcp_smtp = getTestParameter( "NP_HOST_TCP_SMTP",
12 "A host providing an SMTP Service (a mail server)", "mailhost"); 12 "A host providing an SMTP Service (a mail server)", "mailhost");
13my $host_tcp_smtp_tls = getTestParameter( "NP_HOST_TCP_SMTP_TLS", 13my $host_tcp_smtp_starttls = getTestParameter( "NP_HOST_TCP_SMTP_STARTTLS",
14 "A host providing SMTP with STARTTLS", $host_tcp_smtp);
15my $host_tcp_smtp_nostarttls = getTestParameter( "NP_HOST_TCP_SMTP_NOSTARTTLS",
16 "A host providing SMTP without STARTTLS", "");
17my $host_tcp_smtp_tls = getTestParameter( "NP_HOST_TCP_SMTP_TLS",
14 "A host providing SMTP with TLS", $host_tcp_smtp); 18 "A host providing SMTP with TLS", $host_tcp_smtp);
15my $host_tcp_smtp_notls = getTestParameter( "NP_HOST_TCP_SMTP_NOTLS",
16 "A host providing SMTP without TLS", "");
17 19
18my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE", 20my $host_nonresponsive = getTestParameter( "NP_HOST_NONRESPONSIVE",
19 "The hostname of system not responsive to network requests", "10.0.0.1" ); 21 "The hostname of system not responsive to network requests", "10.0.0.1" );
@@ -22,7 +24,7 @@ my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID",
22 "An invalid (not known to DNS) hostname", "nosuchhost" ); 24 "An invalid (not known to DNS) hostname", "nosuchhost" );
23my $res; 25my $res;
24 26
25plan tests => 10; 27plan tests => 16;
26 28
27SKIP: { 29SKIP: {
28 skip "No SMTP server defined", 4 unless $host_tcp_smtp; 30 skip "No SMTP server defined", 4 unless $host_tcp_smtp;
@@ -42,22 +44,38 @@ SKIP: {
42 local $TODO = "Output is over two lines"; 44 local $TODO = "Output is over two lines";
43 like ( $res->output, qr/^SMTP WARNING/, "Correct error message" ); 45 like ( $res->output, qr/^SMTP WARNING/, "Correct error message" );
44 } 46 }
47
48 $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp --ssl -p 25" );
49 is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp with TLS on standard SMTP port" );
50 like ($res->output, qr/^CRITICAL - Cannot make SSL connection\./, "Check output of connecting to $host_tcp_smtp with TLS on standard SMTP port");
45} 51}
46 52
47SKIP: { 53SKIP: {
48 skip "No SMTP server with TLS defined", 1 unless $host_tcp_smtp_tls; 54 skip "No SMTP server with STARTTLS defined", 1 unless $host_tcp_smtp_starttls;
49 # SSL connection for TLS 55 # SSL connection for STARTTLS
50 $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p 25 -S" ); 56 $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_starttls -p 25 -S" );
51 is ($res->return_code, 0, "OK, with STARTTLS" ); 57 is ($res->return_code, 0, "OK, with STARTTLS" );
52} 58}
53 59
54SKIP: { 60SKIP: {
55 skip "No SMTP server without TLS defined", 2 unless $host_tcp_smtp_notls; 61 skip "No SMTP server without STARTTLS defined", 2 unless $host_tcp_smtp_nostarttls;
56 $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_notls -p 25 -S" ); 62 $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_nostarttls -p 25 -S" );
57 is ($res->return_code, 1, "OK, got warning from server without TLS"); 63 is ($res->return_code, 1, "OK, got warning from server without STARTTLS");
58 is ($res->output, "WARNING - TLS not supported by server", "Right error message" ); 64 is ($res->output, "WARNING - TLS not supported by server", "Right error message" );
59} 65}
60 66
67SKIP: {
68 skip "No SMTP server with TLS defined", 1 unless $host_tcp_smtp_tls;
69 $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls --ssl" );
70 is ($res->return_code, 0, "Check rc of connecting to $host_tcp_smtp_tls with TLS" );
71 like ($res->output, qr/^SMTP OK - /, "Check output of connecting to $host_tcp_smtp_tls with TLS" );
72
73 my $unused_port = 4465;
74 $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p $unused_port --ssl" );
75 is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port" );
76 like ($res->output, qr/^connect to address $host_tcp_smtp_tls and port $unused_port: Connection refused/, "Check output of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port");
77}
78
61$res = NPTest->testCmd( "./check_smtp $host_nonresponsive" ); 79$res = NPTest->testCmd( "./check_smtp $host_nonresponsive" );
62is ($res->return_code, 2, "CRITICAL - host non responding" ); 80is ($res->return_code, 2, "CRITICAL - host non responding" );
63 81
diff --git a/plugins/t/check_snmp.t b/plugins/t/check_snmp.t
index f2f218f..576cc50 100644
--- a/plugins/t/check_snmp.t
+++ b/plugins/t/check_snmp.t
@@ -26,22 +26,22 @@ $res = NPTest->testCmd( "./check_snmp -t 1" );
26is( $res->return_code, 3, "No host name" ); 26is( $res->return_code, 3, "No host name" );
27is( $res->output, "No host specified" ); 27is( $res->output, "No host specified" );
28 28
29$res = NPTest->testCmd( "./check_snmp -H fakehostname" ); 29$res = NPTest->testCmd( "./check_snmp -H fakehostname --ignore-mib-parsing-errors" );
30is( $res->return_code, 3, "No OIDs specified" ); 30is( $res->return_code, 3, "No OIDs specified" );
31is( $res->output, "No OIDs specified" ); 31is( $res->output, "No OIDs specified" );
32 32
33$res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3 -U not_a_user --seclevel=rubbish" ); 33$res = NPTest->testCmd( "./check_snmp -H fakehost --ignore-mib-parsing-errors -o oids -P 3 -U not_a_user --seclevel=rubbish" );
34is( $res->return_code, 3, "Invalid seclevel" ); 34is( $res->return_code, 3, "Invalid seclevel" );
35like( $res->output, "/check_snmp: Invalid seclevel - rubbish/" ); 35like( $res->output, "/check_snmp: Invalid seclevel - rubbish/" );
36 36
37$res = NPTest->testCmd( "./check_snmp -H fakehost -o oids -P 3c" ); 37$res = NPTest->testCmd( "./check_snmp -H fakehost --ignore-mib-parsing-errors -o oids -P 3c" );
38is( $res->return_code, 3, "Invalid protocol" ); 38is( $res->return_code, 3, "Invalid protocol" );
39like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" ); 39like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" );
40 40
41SKIP: { 41SKIP: {
42 skip "no snmp host defined", 50 if ( ! $host_snmp ); 42 skip "no snmp host defined", 50 if ( ! $host_snmp );
43 43
44 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:"); 44 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:");
45 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" ); 45 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" );
46 like($res->output, '/^SNMP OK - (\d+)/', "String contains SNMP OK"); 46 like($res->output, '/^SNMP OK - (\d+)/', "String contains SNMP OK");
47 $res->output =~ /^SNMP OK - (\d+)/; 47 $res->output =~ /^SNMP OK - (\d+)/;
@@ -51,111 +51,111 @@ SKIP: {
51 51
52 52
53 # some more threshold tests 53 # some more threshold tests
54 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1"); 54 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1");
55 cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1" ); 55 cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1" );
56 56
57 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1:"); 57 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1:");
58 cmp_ok( $res->return_code, '==', 0, "Threshold test -c 1:" ); 58 cmp_ok( $res->return_code, '==', 0, "Threshold test -c 1:" );
59 59
60 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c ~:1"); 60 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c ~:1");
61 cmp_ok( $res->return_code, '==', 2, "Threshold test -c ~:1" ); 61 cmp_ok( $res->return_code, '==', 2, "Threshold test -c ~:1" );
62 62
63 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1:10"); 63 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1:10");
64 cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1:10" ); 64 cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1:10" );
65 65
66 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c \@1:10"); 66 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c \@1:10");
67 cmp_ok( $res->return_code, '==', 0, "Threshold test -c \@1:10" ); 67 cmp_ok( $res->return_code, '==', 0, "Threshold test -c \@1:10" );
68 68
69 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 10:1"); 69 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 10:1");
70 cmp_ok( $res->return_code, '==', 0, "Threshold test -c 10:1" ); 70 cmp_ok( $res->return_code, '==', 0, "Threshold test -c 10:1" );
71 71
72 72
73 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o .1.3.6.1.2.1.1.3.0 -w 1: -c 1:"); 73 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o .1.3.6.1.2.1.1.3.0 -w 1: -c 1:");
74 cmp_ok( $res->return_code, '==', 0, "Test with numeric OID (no mibs loaded)" ); 74 cmp_ok( $res->return_code, '==', 0, "Test with numeric OID (no mibs loaded)" );
75 like($res->output, '/^SNMP OK - \d+/', "String contains SNMP OK"); 75 like($res->output, '/^SNMP OK - \d+/', "String contains SNMP OK");
76 76
77 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0"); 77 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0");
78 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying sysDescr" ); 78 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying sysDescr" );
79 unlike($res->perf_output, '/sysDescr/', "Perfdata doesn't contain string values"); 79 unlike($res->perf_output, '/sysDescr/', "Perfdata doesn't contain string values");
80 80
81 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0,system.sysDescr.0"); 81 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0,system.sysDescr.0");
82 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, comma-separated" ); 82 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, comma-separated" );
83 like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); 83 like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
84 84
85 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysDescr.0 -o system.sysDescr.0"); 85 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0 -o system.sysDescr.0");
86 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, repeated option" ); 86 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, repeated option" );
87 like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); 87 like($res->output, '/^SNMP OK - /', "String contains SNMP OK");
88 88
89 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 1:1 -c 1:1"); 89 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 1:1 -c 1:1");
90 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrSWRunIndex.1" ); 90 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrSWRunIndex.1" );
91 like($res->output, '/^SNMP OK - 1\s.*$/', "String fits SNMP OK and output format"); 91 like($res->output, '/^SNMP OK - 1\s.*$/', "String fits SNMP OK and output format");
92 92
93 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 0 -c 1:"); 93 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 0 -c 1:");
94 cmp_ok( $res->return_code, '==', 1, "Exit WARNING when querying hrSWRunIndex.1 and warn-th doesn't apply " ); 94 cmp_ok( $res->return_code, '==', 1, "Exit WARNING when querying hrSWRunIndex.1 and warn-th doesn't apply " );
95 like($res->output, '/^SNMP WARNING - \*1\*\s.*$/', "String matches SNMP WARNING and output format"); 95 like($res->output, '/^SNMP WARNING - \*1\*\s.*$/', "String matches SNMP WARNING and output format");
96 96
97 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w :0 -c 0"); 97 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w :0 -c 0");
98 cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL when querying hrSWRunIndex.1 and crit-th doesn't apply" ); 98 cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL when querying hrSWRunIndex.1 and crit-th doesn't apply" );
99 like($res->output, '/^SNMP CRITICAL - \*1\*\s.*$/', "String matches SNMP CRITICAL and output format"); 99 like($res->output, '/^SNMP CRITICAL - \*1\*\s.*$/', "String matches SNMP CRITICAL and output format");
100 100
101 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2 -c 1:2"); 101 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2 -c 1:2");
102 cmp_ok( $res->return_code, '==', 0, "Checking two OIDs at once" ); 102 cmp_ok( $res->return_code, '==', 0, "Checking two OIDs at once" );
103 like($res->output, "/^SNMP OK - 2 1/", "Got two values back" ); 103 like($res->output, "/^SNMP OK - 2 1/", "Got two values back" );
104 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" ); 104 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
105 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" ); 105 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
106 106
107 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2,1:2 -c 2:2,2:2"); 107 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2,1:2 -c 2:2,2:2");
108 cmp_ok( $res->return_code, '==', 2, "Checking critical threshold is passed if any one value crosses" ); 108 cmp_ok( $res->return_code, '==', 2, "Checking critical threshold is passed if any one value crosses" );
109 like($res->output, "/^SNMP CRITICAL - 2 *1*/", "Got two values back" ); 109 like($res->output, "/^SNMP CRITICAL - 2 *1*/", "Got two values back" );
110 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" ); 110 like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" );
111 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" ); 111 like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" );
112 112
113 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w 1:,1: -c 1:,1:"); 113 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w 1:,1: -c 1:,1:");
114 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrMemorySize and hrSystemProcesses"); 114 cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrMemorySize and hrSystemProcesses");
115 like($res->output, '/^SNMP OK - \d+ \d+/', "String contains hrMemorySize and hrSystemProcesses"); 115 like($res->output, '/^SNMP OK - \d+ \d+/', "String contains hrMemorySize and hrSystemProcesses");
116 116
117 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w \@:0 -c \@0"); 117 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w \@:0 -c \@0");
118 cmp_ok( $res->return_code, '==', 0, "Exit OK with inside-range thresholds"); 118 cmp_ok( $res->return_code, '==', 0, "Exit OK with inside-range thresholds");
119 like($res->output, '/^SNMP OK - 1\s.*$/', "String matches SNMP OK and output format"); 119 like($res->output, '/^SNMP OK - 1\s.*$/', "String matches SNMP OK and output format");
120 120
121 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3"); 121 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3");
122 $res->output =~ m/^SNMP OK - (\d+\.\d{2})\s.*$/; 122 $res->output =~ m/^SNMP OK - (\d+\.\d{2})\s.*$/;
123 my $lower = $1 - 0.05; 123 my $lower = $1 - 0.05;
124 my $higher = $1 + 0.05; 124 my $higher = $1 + 0.05;
125 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3 -w $lower -c $higher"); 125 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3 -w $lower -c $higher");
126 cmp_ok( $res->return_code, '==', 1, "Exit WARNING with fractionnal arguments"); 126 cmp_ok( $res->return_code, '==', 1, "Exit WARNING with fractionnal arguments");
127 127
128 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0,host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w ,:0 -c ,:2"); 128 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0,host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w ,:0 -c ,:2");
129 cmp_ok( $res->return_code, '==', 1, "Exit WARNING on 2nd threshold"); 129 cmp_ok( $res->return_code, '==', 1, "Exit WARNING on 2nd threshold");
130 like($res->output, '/^SNMP WARNING - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s+\*1\*\s.*$/', "First OID returned as string, 2nd checked for thresholds"); 130 like($res->output, '/^SNMP WARNING - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s+\*1\*\s.*$/', "First OID returned as string, 2nd checked for thresholds");
131 131
132 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w '' -c ''"); 132 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w '' -c ''");
133 cmp_ok( $res->return_code, '==', 0, "Empty thresholds doesn't crash"); 133 cmp_ok( $res->return_code, '==', 0, "Empty thresholds doesn't crash");
134 134
135 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,,1 -c ,,2"); 135 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,,1 -c ,,2");
136 cmp_ok( $res->return_code, '==', 0, "Skipping first two thresholds on 2 OID check"); 136 cmp_ok( $res->return_code, '==', 0, "Skipping first two thresholds on 2 OID check");
137 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping first two thresholds, result printed rather than parsed"); 137 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping first two thresholds, result printed rather than parsed");
138 138
139 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,, -c ,,"); 139 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,, -c ,,");
140 cmp_ok( $res->return_code, '==', 0, "Skipping all thresholds"); 140 cmp_ok( $res->return_code, '==', 0, "Skipping all thresholds");
141 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping all thresholds, result printed rather than parsed"); 141 like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping all thresholds, result printed rather than parsed");
142 142
143 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0 -c 1000000000000: -u '1/100 sec'"); 143 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1000000000000: -u '1/100 sec'");
144 cmp_ok( $res->return_code, '==', 2, "Timetick used as a threshold"); 144 cmp_ok( $res->return_code, '==', 2, "Timetick used as a threshold");
145 like($res->output, '/^SNMP CRITICAL - \*\d+\* 1\/100 sec.*$/', "Timetick used as a threshold, parsed as numeric"); 145 like($res->output, '/^SNMP CRITICAL - \*\d+\* 1\/100 sec.*$/', "Timetick used as a threshold, parsed as numeric");
146 146
147 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o system.sysUpTime.0"); 147 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0");
148 cmp_ok( $res->return_code, '==', 0, "Timetick used as a string"); 148 cmp_ok( $res->return_code, '==', 0, "Timetick used as a string");
149 like($res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "Timetick used as a string, result printed rather than parsed"); 149 like($res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "Timetick used as a string, result printed rather than parsed");
150 150
151 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -C $snmp_community -o HOST-RESOURCES-MIB::hrSWRunName.1"); 151 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o HOST-RESOURCES-MIB::hrSWRunName.1");
152 cmp_ok( $res->return_code, '==', 0, "snmp response without datatype"); 152 cmp_ok( $res->return_code, '==', 0, "snmp response without datatype");
153 like( $res->output, '/^SNMP OK - "(systemd|init)" \| $/', "snmp response without datatype" ); 153 like( $res->output, '/^SNMP OK - "(systemd|init)" \| $/', "snmp response without datatype" );
154} 154}
155 155
156SKIP: { 156SKIP: {
157 skip "no SNMP user defined", 1 if ( ! $user_snmp ); 157 skip "no SNMP user defined", 1 if ( ! $user_snmp );
158 $res = NPTest->testCmd( "./check_snmp -H $host_snmp -o HOST-RESOURCES-MIB::hrSystemUptime.0 -P 3 -U $user_snmp -L noAuthNoPriv"); 158 $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -o HOST-RESOURCES-MIB::hrSystemUptime.0 -P 3 -U $user_snmp -L noAuthNoPriv");
159 like( $res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "noAuthNoPriv security level works properly" ); 159 like( $res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "noAuthNoPriv security level works properly" );
160} 160}
161 161
@@ -163,14 +163,14 @@ SKIP: {
163# the tests can run on hosts w/o snmp host/community in NPTest.cache. Execution will fail anyway 163# the tests can run on hosts w/o snmp host/community in NPTest.cache. Execution will fail anyway
164SKIP: { 164SKIP: {
165 skip "no non responsive host defined", 2 if ( ! $host_nonresponsive ); 165 skip "no non responsive host defined", 2 if ( ! $host_nonresponsive );
166 $res = NPTest->testCmd( "./check_snmp -H $host_nonresponsive -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:"); 166 $res = NPTest->testCmd( "./check_snmp -H $host_nonresponsive --ignore-mib-parsing-errors -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:");
167 cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL with non responsive host" ); 167 cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL with non responsive host" );
168 like($res->output, '/Plugin timed out while executing system call/', "String matches timeout problem"); 168 like($res->output, '/Plugin timed out while executing system call/', "String matches timeout problem");
169} 169}
170 170
171SKIP: { 171SKIP: {
172 skip "no non invalid host defined", 2 if ( ! $hostname_invalid ); 172 skip "no non invalid host defined", 2 if ( ! $hostname_invalid );
173 $res = NPTest->testCmd( "./check_snmp -H $hostname_invalid -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:"); 173 $res = NPTest->testCmd( "./check_snmp -H $hostname_invalid --ignore-mib-parsing-errors -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:");
174 cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" ); 174 cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" );
175 like($res->output, '/External command error: .*(nosuchhost|Name or service not known|Unknown host)/', "String matches invalid host"); 175 like($res->output, '/External command error: .*(nosuchhost|Name or service not known|Unknown host).*/s', "String matches invalid host");
176} 176}
diff --git a/plugins/t/negate.t b/plugins/t/negate.t
index d96a109..5ec1c84 100644
--- a/plugins/t/negate.t
+++ b/plugins/t/negate.t
@@ -84,7 +84,7 @@ foreach my $current_state (keys(%state)) {
84 foreach my $new_state (keys(%state)) { 84 foreach my $new_state (keys(%state)) {
85 $res = NPTest->testCmd( "./negate -s --$current_state=$new_state ./check_dummy ".$state{$current_state}." 'Fake $new_state'" ); 85 $res = NPTest->testCmd( "./negate -s --$current_state=$new_state ./check_dummy ".$state{$current_state}." 'Fake $new_state'" );
86 is( $res->return_code, $state{$new_state}, "Got fake $new_state (with substitute)" ); 86 is( $res->return_code, $state{$new_state}, "Got fake $new_state (with substitute)" );
87 is( $res->output, uc($new_state).": Fake $new_state", "Substitued fake $new_state output"); 87 is( $res->output, uc($new_state).": Fake $new_state", "Substituted fake $new_state output");
88 } 88 }
89} 89}
90 90
diff --git a/plugins/tests/certs/.gitignore b/plugins/tests/certs/.gitignore
new file mode 100644
index 0000000..79acaaa
--- /dev/null
+++ b/plugins/tests/certs/.gitignore
@@ -0,0 +1,2 @@
1/*.csr
2/*.srl
diff --git a/plugins/tests/certs/client-cert.pem b/plugins/tests/certs/client-cert.pem
new file mode 100644
index 0000000..5709750
--- /dev/null
+++ b/plugins/tests/certs/client-cert.pem
@@ -0,0 +1,22 @@
1-----BEGIN CERTIFICATE-----
2MIIDtDCCApwCAQIwDQYJKoZIhvcNAQELBQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYD
3VQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3Jp
4bmcgUGx1Z2luczEkMCIGA1UEAwwbTW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENB
5MSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMB4X
6DTIxMDIyODIxMDIxMloXDTMwMTEyODIxMDIxMlowgZ4xCzAJBgNVBAYTAkRFMRAw
7DgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0
8b3JpbmcgUGx1Z2luczEiMCAGA1UEAwwZTW9uaXRvcmluZyBQbHVnaW5zIENsaWVu
9dDErMCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9yZzCC
10ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM3EiqfFPomm5dZQPGYG5SrF
11rPvyqseXTzCkwUIUzGf+Sfm3s13zx7e3ije/04yKhTXgK59EQ793q7E2aWhSOz3s
12hwKKdylFkOIyc5jgbAfF1/pLZMK209rLt/mMRksXCRXYrHdTjRMx1ev4C2407+8Y
138qkf77DuYQmUqCQe7DPOvqLeagdw9JcLGmQNTKHg3fl6wyRl5K1Bsy+qXu2XvEjZ
140Ng7n8LHjOUkTqUEJndOxci9gL5cHU5ttul/GW34dKOtTuMU/pQX6/ywYusOGVOx
15RYI76OolRqj5BqbNctDIB/obe2RLo+UVx74/0jAxtH4XS23pYjO7NUpJcytsVG8C
16AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYfaY5n4pCq0NWPCdeVVRr4nr+GAfv1TC
17/PKcGuEoJZKt7TQT+OOA5yeZMZb53OvtA49D1r9aoJzWe946KElWOEBqxDRi5Cdr
18wkqpwGcPT2RfAqA3/cvQZ1XsquboXrCf7ajdl5OC64bs2jkqCFh9gnxuI140g8Ar
19Njol8BFxRPaYWOnwuQwmh/2t0FJqr3WSD85HrNqtxUSNGbTdSsvCfgF0v7QVkvLG
203/cbx6z5hxzj2JUjhMnCvn+EbasoJt4xyBFvg67Q2229SMwu9YNqS63GVoKUqhCB
214Gl5v31qx8dAFKuRvnez3ze/6oohwmakZkst4hcQdgZocHhzesvKlg==
22-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/client-key.pem b/plugins/tests/certs/client-key.pem
new file mode 100644
index 0000000..09b6761
--- /dev/null
+++ b/plugins/tests/certs/client-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDNxIqnxT6JpuXW
3UDxmBuUqxaz78qrHl08wpMFCFMxn/kn5t7Nd88e3t4o3v9OMioU14CufREO/d6ux
4NmloUjs97IcCincpRZDiMnOY4GwHxdf6S2TCttPay7f5jEZLFwkV2Kx3U40TMdXr
5+AtuNO/vGPKpH++w7mEJlKgkHuwzzr6i3moHcPSXCxpkDUyh4N35esMkZeStQbMv
6ql7tl7xI2dDYO5/Cx4zlJE6lBCZ3TsXIvYC+XB1Obbbpfxlt+HSjrU7jFP6UF+v8
7sGLrDhlTsUWCO+jqJUao+QamzXLQyAf6G3tkS6PlFce+P9IwMbR+F0tt6WIzuzVK
8SXMrbFRvAgMBAAECggEBALtc2pB3p0E6KpAiEU0pvCRdSO1FgsIpAd+eNadRPur2
9fi+XWQkUwGeGBaJL1npja3aqP65PP40pj7nWfNaUAgOZyznCEU0QXiPJor6yo0vU
10l5v+aKpwRao107i0RRF80TYGTMx+1LeEqnCqNOZN56gERHlBbkTiWpOZvBzf1143
11oegTcyM6+Ee6+FYNhHaDyIYD0md1S2wGR+IBPet6HwWiakLNKahFPa7lOLIKfmmD
12iTtifcbf4724wSe44a0uTeP4JrquZSeIKakm8MEmffmYqpycnaakYefd0Xc5UEsH
13+VbhKpOWGY3d8FKHqUsTa+6QyXb2uFPo6A+yWm0pdJECgYEA7Prd5sbWACvXOcHT
14ONDBAgyfAVDQwOXi3D4dk6D5mg+/jxl5ZQY5slszJrwsLFtoEzXtYpNfTy3cpNOp
15JLbBDZYnqty+5tD8t3/Zv2IBXCAgvuk5CgfJWP5FNAfiyUEE6Vbp6J/5/vAnODsa
16fxZryN5UsH0X8ew7AlbfcVNyj4kCgYEA3khetIgn+GR6sv9jFRdCT6aJbp0xMsms
176F4v3L5FG4Kp+SwDHL1bVOhieJ5g8odYp9hDbgTEEqbJfNmyCOu9+OQmZ/mztku7
186reU8HhYBIvi+hFeJmvqKpdIgU0Zveg4Bst5QordmhPk8AHjBC4xvQ++uh7rwYKd
19WVsS08bGDjcCgYEAlAuNARUKsASzakOqHv5a9VrJIttH7povBYRQmd+gzxwzgcRa
20UEB5XvEWnYZE2lkoRYgVCtYiXqa6BsasDmGVbVV25okNQckhd8mJUMR7MQBpNJsi
21pR+EK/J9bSnYBf52gQdpDYiTdy60ca6KuQZaw5wRsEgV426+1pFK+dM16HECgYBY
22cTsdYb9lmbUoW201CxgbUQwFsw3MQ2pE2pT4o8wjcg3nUpe6a61XT08+5uV0Gl4w
23CmBp+gN52Fr7DjNEUWg5C64sWLIkqmWOspTUSU3cITyiex6W8wEtCRyUNfU0Fp2U
24Nol87HvXvmqtBFMraqXnr8gXjg4H5MxurUoEcWaEaQKBgCT4iIGZwW0Qf2rkFC7B
25xObzVGefivVVbaf8/c/LRO8TMLdnExkShMOmCzHeHV4mMEZDLbMOusHCI7xm10EX
26l3L1I1Kyqnhm1RH3e7TVWgkTmIDW3V5Fgrhm1jx5Iz6et4sb4Uh+bZq9tTLyqfZY
278s0yJUrfpjRggfk7eUs5s7aY
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientca-cert.pem b/plugins/tests/certs/clientca-cert.pem
new file mode 100644
index 0000000..9ce7cd7
--- /dev/null
+++ b/plugins/tests/certs/clientca-cert.pem
@@ -0,0 +1,25 @@
1-----BEGIN CERTIFICATE-----
2MIIEIzCCAwugAwIBAgIUL9Jfp5zv5B29NgDsNEFU2OM/UHswDQYJKoZIhvcNAQEL
3BQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEkMCIGA1UEAwwbTW9u
5aXRvcmluZyBQbHVnaW5zIENsaWVudENBMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBt
6b25pdG9yaW5nLXBsdWdpbnMub3JnMB4XDTIxMDIyODIxMDIxMVoXDTMwMTEyODIx
7MDIxMVowgaAxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQH
8DAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEkMCIGA1UEAwwb
9TW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENBMSswKQYJKoZIhvcNAQkBFhxkZXZl
10bEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
11MIIBCgKCAQEAyxiWsGrsJFHw3VR0pqHviXUfbfKMw8LaCxI5EQZfInsMVkBIGWEW
12tFW6qDuAOsMdzsrKOnQRNNt852ts/0Uz++z8zysoauAGpc4JnCZuM5A1DU5CFXBx
13w6Ax+1ft3UsTt8C6kfLfs8mPCbtNVqAHrMrIqDxsNSRRxQSqkzp1vD8rwSKcbB1h
14u2+lut1bEqMe7dp89jKOtc6G/1tHUFQuLAGFoX/qk9yPscmQNzL6YbLP4m9r/416
15PsxWsAfyY97hmoYo6mSCue5LmeanOsjf4Kzq90hIJRwrpiUGmxGjW+tPLEhQBZw6
16C2wHyN74YIJYX2xREz2ijT0mgsqdhO5ZxwIDAQABo1MwUTAdBgNVHQ4EFgQUtsP9
17Z3fKkhmFp97Kh/cW/UqHMIMwHwYDVR0jBBgwFoAUtsP9Z3fKkhmFp97Kh/cW/UqH
18MIMwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEApO5o+YECwTEv
19s+elDJZQ20UYwDSiU9Lpf4EcdnRv6FAb5UlhfRTH3ZdKCc/HX7kcKuy3PsF+b8Pw
20EusoKito9OlNEOF5HYAI9/J54/qceqn+SC0INsISeE19PvT0dma7lBSj4OvBv0IS
21GYbdztVaKLWqYgYs0mcEzteUc4MZcy1/C+Ru1i1Kp2s9/vIeAw2PV2+kpWtw88Pb
22FRJomGngP/hQdwniayCltG/Q1smS4iFEHNI5ayLZj1qJGMHwzqGiRr4KknJKfHzv
23fl4NQaFyMY31s1FRIS6QVIRFHVzUAlKZTdzwqEJygg3fUS9n9uDBnyDI/sW7DQuj
24yjSmYRS1hw==
25-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientca-key.pem b/plugins/tests/certs/clientca-key.pem
new file mode 100644
index 0000000..a939f03
--- /dev/null
+++ b/plugins/tests/certs/clientca-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLGJawauwkUfDd
3VHSmoe+JdR9t8ozDwtoLEjkRBl8iewxWQEgZYRa0VbqoO4A6wx3Oyso6dBE023zn
4a2z/RTP77PzPKyhq4AalzgmcJm4zkDUNTkIVcHHDoDH7V+3dSxO3wLqR8t+zyY8J
5u01WoAesysioPGw1JFHFBKqTOnW8PyvBIpxsHWG7b6W63VsSox7t2nz2Mo61zob/
6W0dQVC4sAYWhf+qT3I+xyZA3Mvphss/ib2v/jXo+zFawB/Jj3uGahijqZIK57kuZ
75qc6yN/grOr3SEglHCumJQabEaNb608sSFAFnDoLbAfI3vhgglhfbFETPaKNPSaC
8yp2E7lnHAgMBAAECggEAJqAWiJbNMlsjI/Tb+pTxqYLM52wpuVFlhpWApOxBS517
9SywOikUcvE9RoI0wZfyVvq5yp4tLenID3z9fC21t5Yu8yOm8VhclLINy8G+epc/X
10RyCLEOjBuiLNXq/qXRvaNChDU16NjPPYcFFe9AqbaxFl+BkFu1Wc94tbpYSIv7Qt
11L6iBxUTXdgvLM5doa9AazIQzJx+jUsVCgRVQQf3zsLqtp9hH0Pfq+KWFIy5TA+bG
120NFmYyQndRjtT0ihWGuNU7D8AXa+z7abzk+HydIlx4D//vGgdNq92QYPdnu2BBya
135Fs6LkmkUonX/I8FbkLbRKkQWNPMt+Ks21t3xcVBgQKBgQDn4HuHVCPwxgU6Mv+5
140sHJXYBq1fDzrUt0+iTtYkRqViX+9Mp4sUpYgXext/wXFLcKzQQp5B0g1dLYLSRS
15KwhsdiN0J7ZcoP1GMStw8zsayRTf8C3WRU6aACqyFiylYbyh56XomfYgwhja/7l9
16pzpVJD9ecG+mLVAyAkJtK2JolQKBgQDgOZfvrQj0L4QG+9E5VmFc3PE+6k3g+zDO
17MWqTSh0fOHqdTEyet4bMC4DogXGVsvw0/UKwbrGHOk0+ltA5VyKUtK/whSutr/+S
18nhCHljhV0XUN/I3OFcvezFjM3g0oC4uy1cL30hoM4IfeHM1d3EYse9N1Y/Op+mR6
19Sx+fEku16wKBgQC0KQ7RjuZ95N2a4pUe5En9EtD8MU4Nhs/iC5k1d+yAUn8jIT9P
20lzCUo8NEKheMN2Qg2Dor8jlPkdNIc4qM7TKWUxQo49IlFlCzgPCnydRac3HsrMhw
21e1ke/pIt3FzEArR1d27I0xcRTL3TKm4M2ynPjWJPFj0peHue33KNL/A+IQKBgEpL
22awd0Sxo1wEZcG9gmwf32C01wbzuTn3lCsHB7Ryj4GtCR3nVclCJ50U24zjzu4Fhi
23bj1tgA8xhzSs3fOR5phlQkKsrWtQfJtFGm8CnEn7LBDlVMsrN7Dr/qRrEuro4HHy
24GDbq+8y2fO5glr955BqLMOadprf0imRnDeQ0OLffAoGBAJio+X+xpglgMOC4BeH9
259LcYi9nUEw8MDJNGo9/3e0XKA7spd3HShLDvt8YZhFJ2m168qBpGfezuw0+jpWxy
26PV9q0dokAgDx4pvCzIKaptZ1D30CWXJZHq25VK1tA41PCUIOh8JD5+R0MpxA5rn2
27DbqL4Vq7K7K0imGENYhHdyM+
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientchain-cert.pem b/plugins/tests/certs/clientchain-cert.pem
new file mode 100644
index 0000000..acd1e3e
--- /dev/null
+++ b/plugins/tests/certs/clientchain-cert.pem
@@ -0,0 +1,45 @@
1-----BEGIN CERTIFICATE-----
2MIIDuTCCAqECAQQwDQYJKoZIhvcNAQELBQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYD
3VQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3Jp
4bmcgUGx1Z2luczEkMCIGA1UEAwwbTW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENB
5MSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMB4X
6DTIxMDIyODIxMDIxMloXDTMwMTEyODIxMDIxMlowgaMxCzAJBgNVBAYTAkRFMRAw
7DgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0
8b3JpbmcgUGx1Z2luczEnMCUGA1UEAwweTW9uaXRvcmluZyBQbHVnaW5zIENsaWVu
9dENoYWluMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMu
10b3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAphvoJBbi/rDvm3+X
118xok0sLCJvCRuUpSbU5wEmREQlkoOGmWK4l6r1JyOphKRBo8+n2MxPiCMvAmTrqx
12VlBmkcmyrwWj392Nga+2SLWTziASk5nFrrhV6U79PkgXnETV2Wk1/FNVIFkB8N+B
13undsTce8LLiCs7hfA5CK7ctJg8fqsAsmgKBNGzBRWwkbvxZPd6xlY6foIJeD7PQ2
14elvTmrD6WXSZq7GshFpDEkL3AifqrPMdsTnbBpyGgJ/fBM1b2dx9k53e25mgEQmn
15iSuYQxn08BsUT0FOvav8ksZLBQz859fuqCtwhikpODO635fD9zK5YkBPlVl+/5xo
16SvKOywIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBh4zeSKjENfY+VDLtPssaNQz2a
17R1ioY40lZ0WoihDSrfG32dqTK/R2YsLKBABjJ7uRYS1NIBMrtS2OktK8BWD5IUTF
18FuGuWilu6IWiTKZrLiZh1rsilNDVqwhorRPxDnbF+qVt9EMIvzKnKdJLGF+CWHN9
19yYJDeTD8MK5uR7zUJR3PsgW4ve5pFTi7z2UJ/xRvgOds6bmeeQnvaWDEL7k2+hrr
200G899A086NL3htzaOnIllg0xo2D1o4ToncAJn+cUQVJmHZSg9HYiD4Lg3z8uXPAl
21rt/MX7dBm4dnImLXbSg7N3e8FdUtz+kZT9z+beKAeIe9JTbpxtsVUTzUZBBA
22-----END CERTIFICATE-----
23-----BEGIN CERTIFICATE-----
24MIID2jCCAsKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBoDELMAkGA1UEBhMCREUx
25EDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwSTW9u
26aXRvcmluZyBQbHVnaW5zMSQwIgYDVQQDDBtNb25pdG9yaW5nIFBsdWdpbnMgQ2xp
27ZW50Q0ExKzApBgkqhkiG9w0BCQEWHGRldmVsQG1vbml0b3JpbmctcGx1Z2lucy5v
28cmcwHhcNMjEwMjI4MjEwMjEyWhcNMzAxMTI4MjEwMjEyWjCBqjELMAkGA1UEBhMC
29REUxEDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwS
30TW9uaXRvcmluZyBQbHVnaW5zMS4wLAYDVQQDDCVNb25pdG9yaW5nIFBsdWdpbnMg
31Q2xpZW50SW50ZXJtZWRpYXRlMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9y
32aW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
336rUgOZ9pAOxrcgeeOT3Vmu1YmY2O/C9tXhpKzDzjTaWUzcdDg00KdsjXfgbDzSiV
34uvMzjX63aKpmqeFG+05D2VzQGit3knqerUgl10FnTotiJGF5CU5/gY1aPxTJ7rj2
35tD6LINBkJcPTyQ4MoJT19pssvCax9erY1RxoXxLblJ+31C+VvrftdmBP4nVKXK26
364anb1oUQhkgpXpJimJBmF+v7NbDs1Wh21Be80KXUh9SKgePhSQblr2QlRcA7jLgJ
374PMjZ+KYF+da+4RB7s+DvTXVDMn9AL84E1w5Ut1E8XZV+u4RjWPvNdhK/7GnuxOR
38C9SdxonqkPQ8hiI7thP9bQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
39SIb3DQEBCwUAA4IBAQDKQeiDbyr0/7sEhX33MmTDv84GeWgKl9qqHecx+d/0vImb
40c8XHK0PDa4lVqo/BW4P1hjKzpt2DW35kbOhuqGqM0lasIczef43aCDDEBLwstAe6
41qMoyWGVGoAQbpwT3li2pMrsIYoPwMvoSGNUphjrkdpviff2POkLly7a5RrR1X3qt
42Dai6eYbeMCr9NdgW7AZ5++/sKlFoe+zVk/Ed31s4D2lh3awrApZhVgcoquPmEwpt
43gm+OgRmHw50U4SF3ZaJPwDyLMbx+clH/bgUg0+Za9e53Br1NtGKmw7hh/7CG/hy0
44yxeLd930pH4vZu7s0XM56N/ckkfUzRkAH8dSmhH4
45-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientchain-key.pem b/plugins/tests/certs/clientchain-key.pem
new file mode 100644
index 0000000..0263604
--- /dev/null
+++ b/plugins/tests/certs/clientchain-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmG+gkFuL+sO+b
3f5fzGiTSwsIm8JG5SlJtTnASZERCWSg4aZYriXqvUnI6mEpEGjz6fYzE+IIy8CZO
4urFWUGaRybKvBaPf3Y2Br7ZItZPOIBKTmcWuuFXpTv0+SBecRNXZaTX8U1UgWQHw
534G6d2xNx7wsuIKzuF8DkIrty0mDx+qwCyaAoE0bMFFbCRu/Fk93rGVjp+ggl4Ps
69DZ6W9OasPpZdJmrsayEWkMSQvcCJ+qs8x2xOdsGnIaAn98EzVvZ3H2Tnd7bmaAR
7CaeJK5hDGfTwGxRPQU69q/ySxksFDPzn1+6oK3CGKSk4M7rfl8P3MrliQE+VWX7/
8nGhK8o7LAgMBAAECggEAAfTqMyKh4eYrrGVAYPi53lG0/8htrwUVG3yFDXJo628p
9biCwSCsCavZJqi8JEOxOM5UvB1L2FauGh/7i/+VKkAUUOcOTPpvZguGTACBDcXYn
10Qd3Z2kkJmgn4Kbenr4uQCVOX8zT4F710rGW1nYCyoefsa4pw37UYSW52dH6kiwzW
119k4X251nDMl/twBdOcjZbL768IEa5l4nySLpUNwfrVbSb1NzBoH0dVioh3DTLjt6
12gaShW4eIpaKczht1U97n6/7WNLl6vHX/mR99k/py8OhzhR1ccYpd2IfSHAWyQT0M
13K8BoNnkjICrr9oc0FCr2BVJa3IzKHlhukF4GTZiGYQKBgQDWCHTwAmwL4FFEBVhj
14pZne/sjaZc8TzPPxA8SkmxwDIZrM7tSu7qUuYgWTM432jZbLILWTyGfXf2PpqyF6
15wOpoBJj1ETkre8ZfRmYvsSvS5vtjF3Drszol+XvZnOclfB5VG3m5P2vYkQ8wI9OE
16Y5jUBgDj0RsCNd8QnrC1u54U/wKBgQDGrd5y8S9kUT0P0lkZit7bYjSPJExtClXt
17V7YNTjELrVCdc0jranxBWaub8NP3e6TGTi9HiQWvk2eOAS2qyccqlK4+YAK5XO3D
18EpFUNNcClq8CErw2POuCAKajrPuSp6vd6q8h4lTzDExVctQS4R9fRKKFBKkPUV5G
19UiKFllnKNQKBgQDBGIQXfLfpxwjKK2BhFihKDOc8UhmOrZtvV4zzTJTrJkg4l0f+
20QoN34ytQcHSleXwP6oSmvWkh/GYxjBj6XE2eZndwsYc4ecSwdB0A7gCxl345Gg7g
21NqRBWmGoJGxNXzsmYVFiFZvAmK5xKgFMMWbR8lCfOCn7xopmviSC8K9gFQKBgFRb
22KmH/SbH8VELNews/TVQ0pEBKlzCM/OLjJOcNVgGxOtM/Say677sHibeST0168AFK
233QQwh3t+yK8gjPVA6xGHQ1w0g7OUY1c6IP5x2QC+XdwxfDxDLXNrN1WzcrVX/78f
24j/CBGrR/ekGlmanSb/GRQLfdvLJGSBLveLzjk4gpAoGBANN9RUm/aRz3dDBWex46
25kJ15xKJfLZiUeyDvY5+5d7YF4/tw5LU4XmKQNhiojHecykrTzPUMaGyMrbMPNn32
26WFW9CKMjuBEwWpMDJJb1/5NLEvpwu++sr7bUPZkQl76ot6OqgNHodbP8ATqrNr80
275b8FrEN1LyfkTbabxNyAWcA0
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientintermediate-cert.pem b/plugins/tests/certs/clientintermediate-cert.pem
new file mode 100644
index 0000000..608a8fa
--- /dev/null
+++ b/plugins/tests/certs/clientintermediate-cert.pem
@@ -0,0 +1,23 @@
1-----BEGIN CERTIFICATE-----
2MIID2jCCAsKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBoDELMAkGA1UEBhMCREUx
3EDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwSTW9u
4aXRvcmluZyBQbHVnaW5zMSQwIgYDVQQDDBtNb25pdG9yaW5nIFBsdWdpbnMgQ2xp
5ZW50Q0ExKzApBgkqhkiG9w0BCQEWHGRldmVsQG1vbml0b3JpbmctcGx1Z2lucy5v
6cmcwHhcNMjEwMjI4MjEwMjEyWhcNMzAxMTI4MjEwMjEyWjCBqjELMAkGA1UEBhMC
7REUxEDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwS
8TW9uaXRvcmluZyBQbHVnaW5zMS4wLAYDVQQDDCVNb25pdG9yaW5nIFBsdWdpbnMg
9Q2xpZW50SW50ZXJtZWRpYXRlMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9y
10aW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
116rUgOZ9pAOxrcgeeOT3Vmu1YmY2O/C9tXhpKzDzjTaWUzcdDg00KdsjXfgbDzSiV
12uvMzjX63aKpmqeFG+05D2VzQGit3knqerUgl10FnTotiJGF5CU5/gY1aPxTJ7rj2
13tD6LINBkJcPTyQ4MoJT19pssvCax9erY1RxoXxLblJ+31C+VvrftdmBP4nVKXK26
144anb1oUQhkgpXpJimJBmF+v7NbDs1Wh21Be80KXUh9SKgePhSQblr2QlRcA7jLgJ
154PMjZ+KYF+da+4RB7s+DvTXVDMn9AL84E1w5Ut1E8XZV+u4RjWPvNdhK/7GnuxOR
16C9SdxonqkPQ8hiI7thP9bQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
17SIb3DQEBCwUAA4IBAQDKQeiDbyr0/7sEhX33MmTDv84GeWgKl9qqHecx+d/0vImb
18c8XHK0PDa4lVqo/BW4P1hjKzpt2DW35kbOhuqGqM0lasIczef43aCDDEBLwstAe6
19qMoyWGVGoAQbpwT3li2pMrsIYoPwMvoSGNUphjrkdpviff2POkLly7a5RrR1X3qt
20Dai6eYbeMCr9NdgW7AZ5++/sKlFoe+zVk/Ed31s4D2lh3awrApZhVgcoquPmEwpt
21gm+OgRmHw50U4SF3ZaJPwDyLMbx+clH/bgUg0+Za9e53Br1NtGKmw7hh/7CG/hy0
22yxeLd930pH4vZu7s0XM56N/ckkfUzRkAH8dSmhH4
23-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientintermediate-key.pem b/plugins/tests/certs/clientintermediate-key.pem
new file mode 100644
index 0000000..13f6887
--- /dev/null
+++ b/plugins/tests/certs/clientintermediate-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDqtSA5n2kA7Gty
3B545PdWa7ViZjY78L21eGkrMPONNpZTNx0ODTQp2yNd+BsPNKJW68zONfrdoqmap
44Ub7TkPZXNAaK3eSep6tSCXXQWdOi2IkYXkJTn+BjVo/FMnuuPa0Posg0GQlw9PJ
5DgyglPX2myy8JrH16tjVHGhfEtuUn7fUL5W+t+12YE/idUpcrbrhqdvWhRCGSCle
6kmKYkGYX6/s1sOzVaHbUF7zQpdSH1IqB4+FJBuWvZCVFwDuMuAng8yNn4pgX51r7
7hEHuz4O9NdUMyf0AvzgTXDlS3UTxdlX67hGNY+812Er/sae7E5EL1J3GieqQ9DyG
8Iju2E/1tAgMBAAECggEACyYJXtNUoIeaXvM/r8ZhJBfMEpcnyJDUKBklnmfyABky
9ZUfmzBDXw2as3b6ihFc+LYAp3bm8KouVjtI1lfBUxrli5StVZa7PZLm9mmjv6Eo0
10ojfDEQ8afWPieoaZRO6iQVOLNkbPyv9vSuiQ7vvEZy9dw54u69h47j6IMqPprDiG
11ropUNeGAvTnh1Vf9/8aCHEvHUNHcc4zjzGiQ+E60JgnbpGVeJKoeiMgrQE0yjweo
12KyKA47Y6vqP6+AxAaPplXtmrx2UCbMjktHNvLvg42+2UlLS5roiwmJYEN9c6iT6t
13y82MJrjEFGZyLG2u6ZQANSJiIWaCnOyT1o2deJ8NoQKBgQD7UxivDTuljQD0so+E
14JX9UaFZ9PgS+8LC9v56PciL4XQ7bcCVP5vVgZZPABiQ9i989Wq7qI042Jrfu5qtE
15SthlOAu80GvAQV+Oujwo7ZzM6ciQtjMsj63r2uayWXnmQ07QcIg7x7y161Pt9Bqr
16LIDrqHziIj/lzT7+6QKZaQwFaQKBgQDvEuSC14CBlMhy2jji71kB/3Ya3c+8dP+A
17kQZL9wEWK4a4dm8IaTS8jl1/luhQUzFRMyh2rWaTqqigSe3dvs5DRblhE5NPwTSI
189TO7t1EnzjW3R8LxZZsySyiSFnZ/8mR0empxq0Mov37OdXBj0tXuuzREf/hwijWh
19WuLxJUSjZQKBgAIDZ2Y3l+u6lnBfYdDwL/XwJAk6zvTsnq3WdCG4C1mr/St62YGr
20WvnbtnRKWE356d7m9BHCGKVMaBrM1EBmzRb6fPWVQde3blmJWmQFi0UE9mtaWkyY
21Fg+WoFR7bQOQNHhs/lpkPjnC2dhFJVWLtLiuj9mL5rEjlMab/T5XXhZJAoGBAMEP
22FZ8fXbPGrTQqSwPfWpZFcF9zvbynEmkFM/uGRMddcNZnNXSqWJ7nrFNLTuEGvW2g
23DU4A6zPV/YQrDz4hRjmHBZOCFlSyZbUvpY4yFAQ7/p66AY+kiHZNwT5vi1P5Luvs
24qyaNsZcnRMR+i7rg2EeHv0aNvNdMlNBvL5KikNINAoGAU2P/phdwJOUcqgHavQcQ
25ureTEyZ5i5AeNomNeHSj0slG24V9nxOqEL7D00JKln7oAPovYBUWocEnF39uBJe0
26p0Hy7fCCK6EI8/0QyiQuuZmJfDEEvjQqE6irONNH63r2UwDEpDNGFvGsZNuWHLZc
27SXADu5oSNu6o6IydiyOx528=
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/expired-cert.pem b/plugins/tests/certs/expired-cert.pem
index 77a9166..87fc8e4 100644
--- a/plugins/tests/certs/expired-cert.pem
+++ b/plugins/tests/certs/expired-cert.pem
@@ -1,24 +1,24 @@
1-----BEGIN CERTIFICATE----- 1-----BEGIN CERTIFICATE-----
2MIIEETCCAvmgAwIBAgIUFDsP6WnV/uqeQMpD/DYSqouE13kwDQYJKoZIhvcNAQEL 2MIIEETCCAvmgAwIBAgIUVDKkhcUoYFnjYCw12tScPIqQzqIwDQYJKoZIhvcNAQEL
3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN 3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u 4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u
5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n 5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n
6LXBsdWdpbnMub3JnMB4XDTA4MDEwMTExMDAyNloXDTA4MDEwMjExMDAyNlowgZcx 6LXBsdWdpbnMub3JnMB4XDTA4MDEwMTEyMDAwMFoXDTA4MDEwMjEyMDAwMFowgZcx
7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx 7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx
8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu 8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu
9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp 9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp
10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyeHKwKFjJWUX 10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwg1dmGT3rVqM
11YHKsisypUf9dHlIPQAISyGP1BX6UL26ZLvE6kKbx3LFQ9W2POGoQWlzFiB1soGeV 11beVWWLy8EAiq9re07AF8sTERy9oIYF5EUq9f0xO53mwwqIWV77O9mF99/kDFGQuQ
12WDd0U0JtWdCKmOXWdcXpupQlTSUtRCMDQkfqLN8GR5TBTd73rezp5mz08nMfLwu0 12NOnICMSHXNtMXEXzfBaMighw0uyCh1o/VCejNQ5x/HU8aLh930g5DIcOJQ3fZ4v9
13p5VQ191Ui8JHFgrAOalAn8Uw5De8vj4VmTXmU5NJ2UFoC0ddU/Th/lwRCayHc1cn 138kBaie7+aPgRMVDM1vIrILfedq9Kt56zvPizkXhDeqxjKyIZdrdoBlX5zAfftWtY
14MVq2F7c/uhMUUQYNBmJy0pxoHawp+j9NKl/xIYsjgQNgahQyNuswuGHjaEwhPu+7 14HpQ+lkThSSXqQnchN6S2JFejmRtsNnceDVOBBdvlzmH0NlfwjynLK3/EJooTsINy
15G03XsW4ehu+H1898M/MkSln6LQAU1syoJ8ypPM8tV+zgx4uwj7udnZ2hceN95uW7 15i9dXD8/Oe8r+UA+nokWvnWC2IAUJjpxW+XAyTG/NofGwX+PwquT0YD5cSlODIwZA
160PWg5DQyUwIDAQABo1MwUTAdBgNVHQ4EFgQUt9ps3KJ1XiMuy/ijFBjMzf6jgwkw 16WAimygWLqQIDAQABo1MwUTAdBgNVHQ4EFgQUsKyJAwR9OXWEcSZMQz73GfpxCJIw
17HwYDVR0jBBgwFoAUt9ps3KJ1XiMuy/ijFBjMzf6jgwkwDwYDVR0TAQH/BAUwAwEB 17HwYDVR0jBBgwFoAUsKyJAwR9OXWEcSZMQz73GfpxCJIwDwYDVR0TAQH/BAUwAwEB
18/zANBgkqhkiG9w0BAQsFAAOCAQEAVPBZwMHbrnHFbmhbcPuvYd5cxk0uSVNAUzsl 18/zANBgkqhkiG9w0BAQsFAAOCAQEAYKFGX7J3Fc/T9s278w61E2dSsY4DS/mjSDik
192biCq5P+ZHo10VHGygXtdV4utqk/IrAt2u5qSxycWPStCtAgTd3Q8ncfjOkaHM4z 19fMWvod6eKw0fE3wJOnkWxjEH3VywTY6CmHd/oiJOaD8lr/Vk+BJfYNVBaVNmguyg
202bxTkhLyQeU8NWPuDBqDszo2GOaFTv+lm36LEKiAfqB1tjQVePSkycdrWIhkamBV 204LXoWz9Benx0bAIeuDbNAhOvA4H4aIz8UrD9lKFvKdRp42gPMLtMEbzbLcBdT95D
21EgMe6uHLdU7QQk1ajQfrBdakN1beqki/dKieA6gm+XF/QS4SSYINmsHB/2X5cT9U 216BX7EhYm7vTnpitLPgFxVCsJ1JFqv2AQfUm+IkqQkezPs5x0tWLyrvCDNRGJ0kfv
22b/KMB8xurCnuJQuk1P4VsSkJCOSeHjWZgK9pKNdsIJZr4wDVfhjQgU0XT6xakSf7 22UuowpUZXDOh3k1vB+xaSOFviieLaCW8TSdd5FZgI2HQj4e6vCKsMGuKKZXrMUTI/
23eCaHtO0VKsbLZoiTmpxidjsdYiXyeKYIQNtUpTjyJ5V/cZsq9w== 23qtrFlUfsOuwourfC5LMHtCyYo5B3uvAWT1eTXxhrGqyleSlxJQ==
24-----END CERTIFICATE----- 24-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/expired-key.pem b/plugins/tests/certs/expired-key.pem
index c1510b2..c5bba56 100644
--- a/plugins/tests/certs/expired-key.pem
+++ b/plugins/tests/certs/expired-key.pem
@@ -1,28 +1,28 @@
1-----BEGIN PRIVATE KEY----- 1-----BEGIN PRIVATE KEY-----
2MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDJ4crAoWMlZRdg 2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCDV2YZPetWoxt
3cqyKzKlR/10eUg9AAhLIY/UFfpQvbpku8TqQpvHcsVD1bY84ahBaXMWIHWygZ5VY 35VZYvLwQCKr2t7TsAXyxMRHL2ghgXkRSr1/TE7nebDCohZXvs72YX33+QMUZC5A0
4N3RTQm1Z0IqY5dZ1xem6lCVNJS1EIwNCR+os3wZHlMFN3vet7OnmbPTycx8vC7Sn 46cgIxIdc20xcRfN8FoyKCHDS7IKHWj9UJ6M1DnH8dTxouH3fSDkMhw4lDd9ni/3y
5lVDX3VSLwkcWCsA5qUCfxTDkN7y+PhWZNeZTk0nZQWgLR11T9OH+XBEJrIdzVycx 5QFqJ7v5o+BExUMzW8isgt952r0q3nrO8+LOReEN6rGMrIhl2t2gGVfnMB9+1a1ge
6WrYXtz+6ExRRBg0GYnLSnGgdrCn6P00qX/EhiyOBA2BqFDI26zC4YeNoTCE+77sb 6lD6WROFJJepCdyE3pLYkV6OZG2w2dx4NU4EF2+XOYfQ2V/CPKcsrf8QmihOwg3KL
7Tdexbh6G74fXz3wz8yRKWfotABTWzKgnzKk8zy1X7ODHi7CPu52dnaFx433m5bvQ 711cPz857yv5QD6eiRa+dYLYgBQmOnFb5cDJMb82h8bBf4/Cq5PRgPlxKU4MjBkBY
89aDkNDJTAgMBAAECggEACrLFfNnQmD24NGs/S4e2/VpsA9xTZI/3kNkDNgxULANP 8CKbKBYupAgMBAAECggEBAJ2mdCKJ7LoWdT4W8pZ3BqZUFGkKCF8wOhhOUDH3+ZQp
9aNZtxRajwI9A/BCXQ2UTgsZhzWnJxOJYXrlpl7PweY78mUesysb3MOUC6QisUm0M 9IYK3XbdDMF7mMIXIuW4a7W4sLlTwU/Ar98U1JMESwRIMS7YvUke+ngDKKLcDVGwY
10kimfdktHWOnAKLFFLNleN9DUVjjVkTeslijqhNX80f80py1grG2UuCLKCX4OqYIm 10Qpjg9vP0v2Al8qT1NbW/nDF0S2aJJbWfAvnblHK5ClFHL9iL107NQYJ8PqzXbnFL
11qACE8TMmSZLz42AO96TndNtKplQ8LuGLEmByW95wEfhx3Gm4ckkL7qII/U3DnQXr 11gCQRiZxVHlrbn/73ZUMHPGEoU0711U9hSjrsqrRuSAMC+V38s4HxOomZWutlVAHF
120T+3xLaj+eNJzYDpIFZiw4sNzOuAyCz+4Cc4sPDuMnzquXF+enpkemoycC1RmEpG 12HwClNZBqRO+a2njPyUuV9DM/rl5Tm9IQ89iFo3/QEORICK77HjJYhi+UzdfI5F35
13KIDTwmFsc8TrbGV0qifC6fsCrDivdYLqL7R/q3IBQQKBgQDmfvO3VYTEKY8NA+AT 13UntRJt+WLaiAP+K6Vt6oxHSm58qXnOkeLzaAunTTie0CgYEA6OLYfme8xe5zYXWX
145s6+7NTxRsXxJUCEhCNBWimSH3EzmBAvrodLY6A0oYg8i81bgNX1I9GPVXJZ/QA7 14rqmKNYdcVfMkvL+vUfVT475o/piRtE54JC1LYWEFAN8paxEWHD5HZMy0+ONNXfGm
15ukd84HUIQoGS5Usmo4rp+kz4P6KkLXDemZtWPU5GXxicfajHRQlkbW6St6SpV7IS 15zyNNTN/Lagz4WcpdFzKQmhfdro7DzRiDfdvwSLmaZDyE41PPPVVvfrI9IeDiUNY4
16ibJcDADeoiaPL1xvue1ToP/LoQKBgQDgOFHjYpep00gabvjXfYW7vhrg1vVwaKUM 16nWLSb3sWo96Iuns+RoMqeA9wkqsCgYEA1U/UqeVQVTPlrWyiB2VXoI1xvFCCJTf8
17rf0+UW8Exk4nbBw0eEC2YjxIwzdktlkdbzGaXYULnhg8GnfxYesMOpCLPw1JdB8o 174NC0gcisxLRrtINk0BwrUJrRy0x1OLpJWiKwUl/W1GgvPPfhbYcUOb669JNtTIjY
18ixETAFpW5bKrUsjEFRUGhzWnsCSFIQ4smpmtGLTxOQ8AkoDdORY5Z+Wv7JtFF6Do 18FeIZblCTjz9GzKKmXeDciXvccyEdCJVUlPO3/e2JiJ4mCDjULprifq0a2gcQevFS
19PSoblckZcwKBgB3TD3YJesRnHDty5OuuUdIikuslXTd2uoJrFqS+JeLibqNeabnB 19PfqVULhBOvsCgYB5KfS7J1vGmv36ucSWAe0/VlKLATqe3RfpCzt/JQTZWSWNaroF
20u3/lxDULMbWj4U6VvRmbKOKDC+jY887Gq7lc0cff0yROxwqY3sCnwo3crg7QUmp7 20EG/ElUaWIoUZCEW5oglg/0Q0rYYGF4DTCingkhrx7ReVF70BIbSsBzi15d8nKNbY
21Nb5S8G3qoCSfndcq96wm/Me/O28uCbycVJfUdchY8uRUHIHYbP0FOBQBAoGBAMgh 21t4I3RCF4fyggYe1TmsysXS2DH85/gkToVY7oo2CvF0uJwi8vXnTNDDNkiwKBgHKs
22fPX4imaKr1DovDObVkK87EDDnU84GBm5MtDs3qrkVd3aIVK0Aw7HoAdSN58tI12i 22mAc94BHt9GtnGzQepx0I7TvvjAe2MZwqlt+uojKdS8mfWXMHscGDeYVxdRMqEoUC
23YiPmVVqJQhhjh6tsOuAvZdTj8ngdrbICbrsHFZt6an+A5LIgHyQ0iy+hiPdLCdvG 23YQfnvfYyjDKaj/XxyE3C237gQsICTyh0hHdpmepIeidIyWdumyDOFZVPF+ylWvM4
24ImTeKKMmyr04Bs1upueWVO0xw2VoMbcY4Py+NUEBAoGASQqedfCSKGLT+5lLZrhP 24kpFQQb/QRWHmKyti2KCBLw5G/fUaBryLGfprE6ZBAoGBANy5rr41A679UQZ0abev
25CbFVMmswEPjBcRb1trcuA09vfExn9FfUNFnnw3i9miprED5kufvAjb+6nduXizKg 25bOZb7YWOHYp/wReJaQbvLAyR30os3aEY/0ht9S+OWdrgGMezPKvsx2Sqr/CwoFXI
267HQYHCwVvakgtXgbiDMaNgYZcjWm+MdnfiwLJjJTO3DfI1JF2PJ8y9R95DPlAkDm 26esiklpknr11maEPxnQJYi4FYiXS1a3NCg7yBvKzFEgx2XnMAC3s6zhuZXaFq4zNu
27xH3OV8KV4UiTEVxS7ksmGzY= 27pm5Btrq/NZqtVXovS+UhGLvJ
28-----END PRIVATE KEY----- 28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/ext.cnf b/plugins/tests/certs/ext.cnf
new file mode 100644
index 0000000..d09cee1
--- /dev/null
+++ b/plugins/tests/certs/ext.cnf
@@ -0,0 +1,2 @@
1[ client_ca ]
2basicConstraints = critical, CA:true
diff --git a/plugins/tests/certs/generate-certs.sh b/plugins/tests/certs/generate-certs.sh
new file mode 100755
index 0000000..78660a2
--- /dev/null
+++ b/plugins/tests/certs/generate-certs.sh
@@ -0,0 +1,63 @@
1#!/bin/sh -e
2#
3# Recreates the https server certificates
4#
5# Set the GEN_EXPIRED environment variable to also regenerate
6# the expired certificate.
7
8cd "$(dirname "$0")"
9trap 'rm -f *.csr; rm -f clientca-cert.srl' EXIT
10
11subj() {
12 c="DE"
13 st="Bavaria"
14 l="Munich"
15 o="Monitoring Plugins"
16 cn="Monitoring Plugins"
17 emailAddress="devel@monitoring-plugins.org"
18
19 if [ -n "$1" ]; then
20 # Add to CN
21 cn="$cn $1"
22 fi
23
24 printf "/C=%s/ST=%s/L=%s/O=%s/CN=%s/emailAddress=%s" \
25 "$c" "$st" "$l" "$o" "$cn" "$emailAddress"
26}
27
28# server
29openssl req -new -x509 -days 3560 -nodes \
30 -keyout server-key.pem -out server-cert.pem \
31 -subj "$(subj)"
32# server, expired
33# there is generally no need to regenerate this, as it will stay epxired
34[ -n "$GEN_EXPIRED" ] && TZ=UTC faketime -f '2008-01-01 12:00:00' \
35 openssl req -new -x509 -days 1 -nodes \
36 -keyout expired-key.pem -out expired-cert.pem \
37 -subj "$(subj)"
38
39# client, ca
40openssl req -new -x509 -days 3560 -nodes \
41 -keyout clientca-key.pem -out clientca-cert.pem \
42 -subj "$(subj ClientCA)"
43echo "01" >clientca-cert.srl
44# client
45openssl req -new -nodes \
46 -keyout client-key.pem -out client-cert.csr \
47 -subj "$(subj Client)"
48openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
49 -in client-cert.csr -out client-cert.pem
50# client, intermediate
51openssl req -new -nodes \
52 -keyout clientintermediate-key.pem -out clientintermediate-cert.csr \
53 -subj "$(subj ClientIntermediate)"
54openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
55 -extfile ext.cnf -extensions client_ca \
56 -in clientintermediate-cert.csr -out clientintermediate-cert.pem
57# client, chain
58openssl req -new -nodes \
59 -keyout clientchain-key.pem -out clientchain-cert.csr \
60 -subj "$(subj ClientChain)"
61openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
62 -in clientchain-cert.csr -out clientchain-cert.pem
63cat clientintermediate-cert.pem >>clientchain-cert.pem
diff --git a/plugins/tests/certs/server-cert.pem b/plugins/tests/certs/server-cert.pem
index b84b91d..d1249ef 100644
--- a/plugins/tests/certs/server-cert.pem
+++ b/plugins/tests/certs/server-cert.pem
@@ -1,24 +1,24 @@
1-----BEGIN CERTIFICATE----- 1-----BEGIN CERTIFICATE-----
2MIIEBjCCAu6gAwIBAgIJANbQ5QQrKhUGMA0GCSqGSIb3DQEBCwUAMIGXMQswCQYD 2MIIEETCCAvmgAwIBAgIUZwOhY4myaCUaPek3NM+MxbLG9vwwDQYJKoZIhvcNAQEL
3VQQGEwJERTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYD 3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4VQQKDBJNb25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1 4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u
5Z2luczErMCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9y 5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n
6ZzAeFw0xOTAyMTkxNTMxNDRaFw0yOTAyMTYxNTMxNDRaMIGXMQswCQYDVQQGEwJE 6LXBsdWdpbnMub3JnMB4XDTIxMDIyODIxMDIxMVoXDTMwMTEyODIxMDIxMVowgZcx
7RTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYDVQQKDBJN 7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx
8b25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1Z2luczEr 8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu
9MCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9yZzCCASIw 9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp
10DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgV2yp8pQvJuN+aJGdAe6Hd0tja 10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/3eBA4WG6xz
11uteCPcNIcM92WLOF69TLTSYon1XDon4tHTh4Z5d4lD8bfsGzFVBmDSgWidhAUf+v 11LfM6xcWywxThb1Rp7XAW3ewQd9/PdoWXEe8BJWlLfyYi1drLMcsDywhLkKmW4Vp9
12EqEXwbp293ej/Frc0pXCvmrz6kI1tWrLtQhL/VdbxFYxhV7JjKb+PY3SxGFpSLPe 121R4PAkiljjrB/ZaUMDLJ1ri3dwX4RvXG7crsU3QWFWCBOrf5V2FTRQ2m/H/KyB/6
13PQ/5SwVndv7rZIwcjseL22K5Uy2TIrkgzzm2pRs/IvoxRybYr/+LGoHyrtJC6AO8 13rVZANsU47HqTFSPiUm2j7P3wx/wtHeYC+qmNG7zZTjAYPYxfKiod0lytTSmb+h54
14ylp8A/etL0gwtUvRnrnZeTQ2pA1uZ5QN3anTL8JP/ZRZYNegIkaawqMtTKbhM6pi 146lxn3+VPEXZAQZlLvPnm/58JnXGrUv7B2yocf5MhKkLJOrGxH2hfwKISfaj2gpOV
15u3/4a3Uppvt0y7vmGfQlYejxCpICnMrvHMpw8L58zv/98AbCGjDU3UwCt6MCAwEA 15m4PUVYiDzCSpq1fPvwbUxIvdO27xprx+mrGOFM6f2UCEOc35w8FSmYiR2yQTnEJK
16AaNTMFEwHQYDVR0OBBYEFG/UH6nGYPlVcM75UXzXBF5GZyrcMB8GA1UdIwQYMBaA 16pbSQD6t1jQIDAQABo1MwUTAdBgNVHQ4EFgQUMeYgglT2aWDlF8KEeF2376AlTGYw
17FG/UH6nGYPlVcM75UXzXBF5GZyrcMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN 17HwYDVR0jBBgwFoAUMeYgglT2aWDlF8KEeF2376AlTGYwDwYDVR0TAQH/BAUwAwEB
18AQELBQADggEBAGwitJPOnlIKLndNf+iCLMIs0dxsl8kAaejFcjoT0n4ja7Y6Zrqz 18/zANBgkqhkiG9w0BAQsFAAOCAQEAFcEg83rTJdgkp7JLYqK0j8JogSHNlDYchr/r
19VSIidzz9vQWvy24xKJpAOdj/iLRHCUOG+Pf5fA6+/FiuqXr6gE2/lm0eC58BNONr 19VxKBgQwfnjSp5A8d5+uTQ9s3QDabw8v7YeSrzYXbbjuWZ61mnl84tzOQ8LMeESnC
20E5OzjQ/VoQ8RX4hDntgu6FYbaVa/vhwn16igt9qmdNGGZXf2/+DM3JADwyaA4EK8 20CBXRCxB8Ow22WsVTVJq279SGYT+cZrdsmqGVWDi1A0C5kH+XTLAioG5CZmmxemD/
21vm7KdofX9zkxXecHPNvf3jiVLPiDDt6tkGpHPEsyP/yc+RUdltUeZvHfliV0cCuC 21S92ZoRxGyYfg33r+3X6EMcEYtHKGxCUa3EPcPOL4dq2F3nOnyjiWPZm3786H3NY2
22jJX+Fm9ysjSpHIFFr+jUMuMHibWoOD8iy3eYxfCDoWsH488pCbj8MNuAq6vd6DBk 22nsYwrEhAdUFtbYSsV5O0c/Zlc33fmTfh654ab35io1DtwmFo7q8J532dUE007EN0
23bOZxDz43vjWuYMkwXJTxJQh7Pne6kK0vE1g= 23mIQmhdrjNJJHIftgSt0fuN5m48oLOnX7vvkz+X0WLWfVTtMr0w==
24-----END CERTIFICATE----- 24-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/server-key.pem b/plugins/tests/certs/server-key.pem
index 1194755..0de63f8 100644
--- a/plugins/tests/certs/server-key.pem
+++ b/plugins/tests/certs/server-key.pem
@@ -1,28 +1,28 @@
1-----BEGIN PRIVATE KEY----- 1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCoFdsqfKULybjf 2MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDb/d4EDhYbrHMt
3miRnQHuh3dLY2rrXgj3DSHDPdlizhevUy00mKJ9Vw6J+LR04eGeXeJQ/G37BsxVQ 38zrFxbLDFOFvVGntcBbd7BB33892hZcR7wElaUt/JiLV2ssxywPLCEuQqZbhWn3V
4Zg0oFonYQFH/rxKhF8G6dvd3o/xa3NKVwr5q8+pCNbVqy7UIS/1XW8RWMYVeyYym 4Hg8CSKWOOsH9lpQwMsnWuLd3BfhG9cbtyuxTdBYVYIE6t/lXYVNFDab8f8rIH/qt
5/j2N0sRhaUiz3j0P+UsFZ3b+62SMHI7Hi9tiuVMtkyK5IM85tqUbPyL6MUcm2K// 5VkA2xTjsepMVI+JSbaPs/fDH/C0d5gL6qY0bvNlOMBg9jF8qKh3SXK1NKZv6Hnjq
6ixqB8q7SQugDvMpafAP3rS9IMLVL0Z652Xk0NqQNbmeUDd2p0y/CT/2UWWDXoCJG 6XGff5U8RdkBBmUu8+eb/nwmdcatS/sHbKhx/kyEqQsk6sbEfaF/AohJ9qPaCk5Wb
7msKjLUym4TOqYrt/+Gt1Kab7dMu75hn0JWHo8QqSApzK7xzKcPC+fM7//fAGwhow 7g9RViIPMJKmrV8+/BtTEi907bvGmvH6asY4Uzp/ZQIQ5zfnDwVKZiJHbJBOcQkql
81N1MArejAgMBAAECggEANuvdTwanTzC8jaNqHaq+OuemS2E9B8nwsGxtH/zFgvNR 8tJAPq3WNAgMBAAECggEBAIvJDUjQVpXxByL8eazviT5SR0jBf6mC3tTWykQRb7ck
9WZiMPtmrJnTkFWJcV+VPw/iMSAqN4nDHmBugVOb4Z4asxGTKK4T9shXJSnh0rqPU 9/bBEiRrnhDRf3CS9KP4TvO5G8BUU3a2GHYzM08akuKXeiiODidfyfbQ1nUZBAdi9
1000ZsvbmxY6z0+E5TesCJqQ+9GYTY1V357V7JchvaOxIRxWPqg9urHbru8OCtW/I5 10FVFF7tK8YcflkVfpTMOMMSggm6m33fc58sQvmQ/0U85XuJvnOEkeJ9pQJa49e8GR
11Fh5HPUZlgCvlMpjlhyjydIf/oXyVA3RNsXlwe8+2cKuGIrjEzm2j9o3VF0sctTX0 11lpCQImF7ygltHPEz4o8qOtNMuPxiHOxpc517+ozQULZk153NTfGok1XctDFFZ3YX
12ItP8A9qDmDQN7GIWX0MW6gncojpS1omC2wcFsdjj/xfPyiDal1X4aq/2YqG8351c 128okLSfcqZ28mdHYSvI9xf60Cm7cT9tunXHwZ0f1esTFiVYpAp+oTJqtdYxr/fYlL
13YlM/+6Va0u9WWE/i64gASTAVqpMV4Yg8y0gGycuA0QKBgQDbgI2QeLd3FvMcURiU 13oO8G8iIQ7LjdJfgo84PscpKdSRCq3BfnmER1Eyg6hrUCgYEA/0hL5Y/haz/2jYGy
14l3w9qJgw/Jp3jaNC/9LkVGGz4f4lKKB67lPZvI4noMK8GqO/LcXgqP/RY1oJojoA 14aa8yZSuD1ZcWtj7pLKrBQnHPHIHsjSBggWhopvonCFvCjgSS1pOFOUAwMGc0T+Dw
15/6JKVvzYGASZ7VgMoG9bk1AneP1PGdibuTUEwimGlcObxnDFIC/yjwPFu3jIdqdS 15rWo3w8cEUyECl3Bw8gbCWtRXaigzU9TPgCWyx1j5dTopQhLObzS/m7fJFElnYNru
16zZi1RZzyqAogN5y3SBEypSmn9wKBgQDECKsqqlcizmCl8v5aVk875AzGN+DOHZqx 16jqhsUfWS+NKk8a5+A7i9lv4iBLMCgYEA3Jws3Lfj/Xs7LljrvryTMpPthvUGBcyt
17bkmztlnLO/2e2Fmk3G5Vvnui0FYisf8Eq19tUTQCF6lSfJlGQeFAT119wkFZhLu+ 17U9Qmf1Hmur90RP5V1rx4FqPQzIeaGQyZDNIUnkhBSqQZNCts3Rzay7N4uQzk8OEg
18FfLGqoEMH0ijJg/8PpdpFRK3I94YcISoTNN6yxMvE6xdDGfKCt5a+IX5bwQi9Zdc 18S8Llnw76wLwi0SJ4okDtT5tpTR6fcS0M9lGN+zvvfUB4+ul8oub0pMcyme/pywEz
19B242gEc6tQKBgA6tM8n7KFlAIZU9HuWgk2AUC8kKutFPmSD7tgAqXDYI4FNfugs+ 19ap+x3xAQPL8CgYEAiYOBVtTNof9fqdRurh1w8SyipKDx3BRBeQ02c7tozLt0GIWT
20MEEYyHCB4UNujJBV4Ss6YZCAkh6eyD4U2aca1eElCfm40vBVMdzvpqZdAqLtWXxg 20VsJOdXwVIJyFTglKrAnlXvSjwL8nX8wU+eVYyr5fJwSGJ9urC8T2VwVBXW7wTz04
21D9l3mgszrFaYGCY2Fr6jLV9lP5g3xsxUjudf9jSLY9HvpfzjRrMaNATVAoGBALTl 211Zf5GQdlwW8mIHCPATqR6Kj0yVfNN1BX50L0rqWxmRWnQoUzXn/aqQaWfp8CgYAW
22/vYfPMucwKlC5B7++J0e4/7iv6vUu9SyHocdZh1anb9AjPDKjXLIlZT4RhQ8R0XK 229693/zEeR8EejyVkAy/z+RCml0XcPrXg31pusPErihkpwazgIVkDSmTHlmqFpxkc
230wOw5JpttU2uN08TKkbLNk3/vYhbKVjPLjrQSseh8sjDLgsqw1QwIxYnniLVakVY 23C5cX73/UrIbvNoIr9wAUawfrhBsltNpu6MiNKbsTa8LYMRWMFuReAFkTLVf+KWmL
24p+rvjSNrNyqicQCMKQavwgocvSd5lJRTMwxOMezlAoGBAKWj71BX+0CK00/2S6lC 24D2yPtmq1iIvP25UdRJw9t3teKWsWtnZK6HtVNM/r8wKBgQDKlqUpy8r4KK+S2w80
25TcNcuUPG0d8y1czZ4q6tUlG4htwq1FMOpaghATXjkdsOGTLS+H1aA0Kt7Ai9zDhc 25H7rAQJo1DgXsYrgSa2gfppSKro4lm3ltyAfVIrKQKP7uCo9xTGKVQAUPttMs2+17
26/bzOJEJ+jvBXV4Gcs7jl1r/HTKv0tT9ZSI5Vzkida0rfqxDGzcMVlLuCdH0cb8Iu 26nwbwvt7/nG7G1Dk/C/t6b7SJ80VY5b9ZZKIJ0wOjajLufSjPNCe0ZTRn32XusZUn
27N0wdmCAqlQwHR13+F1zrAD7V 27nYGB5/QXYr5WGV9YhAkRsFJYgA==
28-----END PRIVATE KEY----- 28-----END PRIVATE KEY-----
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t
index 29cb03f..72f2b7c 100755
--- a/plugins/tests/check_curl.t
+++ b/plugins/tests/check_curl.t
@@ -21,7 +21,7 @@ use FindBin qw($Bin);
21 21
22$ENV{'LC_TIME'} = "C"; 22$ENV{'LC_TIME'} = "C";
23 23
24my $common_tests = 72; 24my $common_tests = 73;
25my $ssl_only_tests = 8; 25my $ssl_only_tests = 8;
26# Check that all dependent modules are available 26# Check that all dependent modules are available
27eval "use HTTP::Daemon 6.01;"; 27eval "use HTTP::Daemon 6.01;";
@@ -200,6 +200,14 @@ sub run_server {
200 $c->send_basic_header; 200 $c->send_basic_header;
201 $c->send_crlf; 201 $c->send_crlf;
202 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host'))); 202 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
203 } elsif ($r->url->path eq "/chunked") {
204 my $chunks = ["chunked", "encoding", "test\n"];
205 $c->send_response(HTTP::Response->new( 200, 'OK', undef, sub {
206 my $chunk = shift @{$chunks};
207 return unless $chunk;
208 sleep(1);
209 return($chunk);
210 }));
203 } else { 211 } else {
204 $c->send_error(HTTP::Status->RC_FORBIDDEN); 212 $c->send_error(HTTP::Status->RC_FORBIDDEN);
205 } 213 }
@@ -228,23 +236,25 @@ SKIP: {
228 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; 236 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https};
229 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 237 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
230 238
239 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
240
231 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 241 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
232 is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); 242 is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
233 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" ); 243 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" );
234 244
235 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 245 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
236 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); 246 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
237 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 247 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
238 248
239 # Expired cert tests 249 # Expired cert tests
240 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 250 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
241 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); 251 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
242 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 252 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
243 253
244 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 254 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
245 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); 255 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
246 is( $result->output, 256 is( $result->output,
247 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 11:00:26 2008 +0000.', 257 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.',
248 "output ok" ); 258 "output ok" );
249 259
250} 260}
@@ -470,7 +480,8 @@ sub run_common_tests {
470 local $SIG{ALRM} = sub { die "alarm\n" }; 480 local $SIG{ALRM} = sub { die "alarm\n" };
471 alarm(2); 481 alarm(2);
472 $result = NPTest->testCmd( $cmd ); 482 $result = NPTest->testCmd( $cmd );
473 alarm(0); }; 483 };
484 alarm(0);
474 isnt( $@, "alarm\n", $cmd ); 485 isnt( $@, "alarm\n", $cmd );
475 is( $result->return_code, 0, $cmd ); 486 is( $result->return_code, 0, $cmd );
476 487
@@ -480,7 +491,8 @@ sub run_common_tests {
480 local $SIG{ALRM} = sub { die "alarm\n" }; 491 local $SIG{ALRM} = sub { die "alarm\n" };
481 alarm(2); 492 alarm(2);
482 $result = NPTest->testCmd( $cmd ); 493 $result = NPTest->testCmd( $cmd );
483 alarm(0); }; 494 };
495 alarm(0);
484 isnt( $@, "alarm\n", $cmd ); 496 isnt( $@, "alarm\n", $cmd );
485 isnt( $result->return_code, 0, $cmd ); 497 isnt( $result->return_code, 0, $cmd );
486 498
@@ -506,4 +518,9 @@ sub run_common_tests {
506 }; 518 };
507 is( $@, "", $cmd ); 519 is( $@, "", $cmd );
508 520
521 $cmd = "$command -u /chunked -s 'chunkedencodingtest' -d 'Transfer-Encoding: chunked'";
522 eval {
523 $result = NPTest->testCmd( $cmd, 5 );
524 };
525 is( $@, "", $cmd );
509} 526}
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 188f5e7..6078b27 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -3,27 +3,20 @@
3# Test check_http by having an actual HTTP server running 3# Test check_http by having an actual HTTP server running
4# 4#
5# To create the https server certificate: 5# To create the https server certificate:
6# openssl req -new -x509 -keyout server-key.pem -out server-cert.pem -days 3650 -nodes 6# ./certs/generate-certs.sh
7# to create a new expired certificate:
8# faketime '2008-01-01 12:00:00' openssl req -new -x509 -keyout expired-key.pem -out expired-cert.pem -days 1 -nodes
9# Country Name (2 letter code) [AU]:DE
10# State or Province Name (full name) [Some-State]:Bavaria
11# Locality Name (eg, city) []:Munich
12# Organization Name (eg, company) [Internet Widgits Pty Ltd]:Monitoring Plugins
13# Organizational Unit Name (eg, section) []:
14# Common Name (e.g. server FQDN or YOUR name) []:Monitoring Plugins
15# Email Address []:devel@monitoring-plugins.org
16 7
17use strict; 8use strict;
18use Test::More; 9use Test::More;
19use NPTest; 10use NPTest;
20use FindBin qw($Bin); 11use FindBin qw($Bin);
12use IO::Socket::INET;
21 13
22$ENV{'LC_TIME'} = "C"; 14$ENV{'LC_TIME'} = "C";
23 15
24my $common_tests = 70; 16my $common_tests = 71;
25my $virtual_port_tests = 8; 17my $virtual_port_tests = 8;
26my $ssl_only_tests = 8; 18my $ssl_only_tests = 12;
19my $chunked_encoding_special_tests = 1;
27# Check that all dependent modules are available 20# Check that all dependent modules are available
28eval "use HTTP::Daemon 6.01;"; 21eval "use HTTP::Daemon 6.01;";
29plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; 22plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@;
@@ -39,7 +32,7 @@ if ($@) {
39 plan skip_all => "Missing required module for test: $@"; 32 plan skip_all => "Missing required module for test: $@";
40} else { 33} else {
41 if (-x "./$plugin") { 34 if (-x "./$plugin") {
42 plan tests => $common_tests * 2 + $ssl_only_tests + $virtual_port_tests; 35 plan tests => $common_tests * 2 + $ssl_only_tests + $virtual_port_tests + $chunked_encoding_special_tests;
43 } else { 36 } else {
44 plan skip_all => "No $plugin compiled"; 37 plan skip_all => "No $plugin compiled";
45 } 38 }
@@ -59,61 +52,110 @@ $HTTP::Daemon::VERSION = "1.00";
59my $port_http = 50000 + int(rand(1000)); 52my $port_http = 50000 + int(rand(1000));
60my $port_https = $port_http + 1; 53my $port_https = $port_http + 1;
61my $port_https_expired = $port_http + 2; 54my $port_https_expired = $port_http + 2;
55my $port_https_clientcert = $port_http + 3;
56my $port_hacked_http = $port_http + 4;
62 57
63# This array keeps sockets around for implementing timeouts 58# This array keeps sockets around for implementing timeouts
64my @persist; 59my @persist;
65 60
66# Start up all servers 61# Start up all servers
67my @pids; 62my @pids;
68my $pid = fork(); 63# Fork a HTTP server
69if ($pid) { 64my $pid = fork;
70 # Parent 65defined $pid or die "Failed to fork";
71 push @pids, $pid; 66if (!$pid) {
72 if (exists $servers->{https}) { 67 undef @pids;
73 # Fork a normal HTTPS server
74 $pid = fork();
75 if ($pid) {
76 # Parent
77 push @pids, $pid;
78 # Fork an expired cert server
79 $pid = fork();
80 if ($pid) {
81 push @pids, $pid;
82 } else {
83 my $d = HTTP::Daemon::SSL->new(
84 LocalPort => $port_https_expired,
85 LocalAddr => "127.0.0.1",
86 SSL_cert_file => "$Bin/certs/expired-cert.pem",
87 SSL_key_file => "$Bin/certs/expired-key.pem",
88 ) || die;
89 print "Please contact https expired at: <URL:", $d->url, ">\n";
90 run_server( $d );
91 exit;
92 }
93 } else {
94 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
95 local $SIG{'PIPE'} = 'IGNORE';
96 my $d = HTTP::Daemon::SSL->new(
97 LocalPort => $port_https,
98 LocalAddr => "127.0.0.1",
99 SSL_cert_file => "$Bin/certs/server-cert.pem",
100 SSL_key_file => "$Bin/certs/server-key.pem",
101 ) || die;
102 print "Please contact https at: <URL:", $d->url, ">\n";
103 run_server( $d );
104 exit;
105 }
106 }
107} else {
108 # Child
109 #print "child\n";
110 my $d = HTTP::Daemon->new( 68 my $d = HTTP::Daemon->new(
111 LocalPort => $port_http, 69 LocalPort => $port_http,
112 LocalAddr => "127.0.0.1", 70 LocalAddr => "127.0.0.1",
113 ) || die; 71 ) || die;
114 print "Please contact http at: <URL:", $d->url, ">\n"; 72 print "Please contact http at: <URL:", $d->url, ">\n";
115 run_server( $d ); 73 run_server( $d );
116 exit; 74 die "webserver stopped";
75}
76push @pids, $pid;
77
78# Fork the hacked HTTP server
79undef $pid;
80$pid = fork;
81defined $pid or die "Failed to fork";
82if (!$pid) {
83 # this is the fork
84 undef @pids;
85 my $socket = new IO::Socket::INET (
86 LocalHost => '0.0.0.0',
87 LocalPort => $port_hacked_http,
88 Proto => 'tcp',
89 Listen => 5,
90 Reuse => 1
91 );
92 die "cannot create socket $!n" unless $socket;
93 my $local_sock = $socket->sockport();
94 print "server waiting for client connection on port $local_sock\n";
95 run_hacked_http_server ( $socket );
96 die "hacked http server stopped";
97}
98push @pids, $pid;
99
100if (exists $servers->{https}) {
101 # Fork a normal HTTPS server
102 $pid = fork;
103 defined $pid or die "Failed to fork";
104 if (!$pid) {
105 undef @pids;
106 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
107 local $SIG{'PIPE'} = 'IGNORE';
108 my $d = HTTP::Daemon::SSL->new(
109 LocalPort => $port_https,
110 LocalAddr => "127.0.0.1",
111 SSL_cert_file => "$Bin/certs/server-cert.pem",
112 SSL_key_file => "$Bin/certs/server-key.pem",
113 ) || die;
114 print "Please contact https at: <URL:", $d->url, ">\n";
115 run_server( $d );
116 die "webserver stopped";
117 }
118 push @pids, $pid;
119
120 # Fork an expired cert server
121 $pid = fork;
122 defined $pid or die "Failed to fork";
123 if (!$pid) {
124 undef @pids;
125 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
126 local $SIG{'PIPE'} = 'IGNORE';
127 my $d = HTTP::Daemon::SSL->new(
128 LocalPort => $port_https_expired,
129 LocalAddr => "127.0.0.1",
130 SSL_cert_file => "$Bin/certs/expired-cert.pem",
131 SSL_key_file => "$Bin/certs/expired-key.pem",
132 ) || die;
133 print "Please contact https expired at: <URL:", $d->url, ">\n";
134 run_server( $d );
135 die "webserver stopped";
136 }
137 push @pids, $pid;
138
139 # Fork an client cert expecting server
140 $pid = fork;
141 defined $pid or die "Failed to fork";
142 if (!$pid) {
143 undef @pids;
144 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
145 local $SIG{'PIPE'} = 'IGNORE';
146 my $d = HTTP::Daemon::SSL->new(
147 LocalPort => $port_https_clientcert,
148 LocalAddr => "127.0.0.1",
149 SSL_cert_file => "$Bin/certs/server-cert.pem",
150 SSL_key_file => "$Bin/certs/server-key.pem",
151 SSL_verify_mode => IO::Socket::SSL->SSL_VERIFY_PEER | IO::Socket::SSL->SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
152 SSL_ca_file => "$Bin/certs/clientca-cert.pem",
153 ) || die;
154 print "Please contact https client cert at: <URL:", $d->url, ">\n";
155 run_server( $d );
156 die "webserver stopped";
157 }
158 push @pids, $pid;
117} 159}
118 160
119# give our webservers some time to startup 161# give our webservers some time to startup
@@ -122,64 +164,105 @@ sleep(3);
122# Run the same server on http and https 164# Run the same server on http and https
123sub run_server { 165sub run_server {
124 my $d = shift; 166 my $d = shift;
125 MAINLOOP: while (my $c = $d->accept ) { 167 while (1) {
126 while (my $r = $c->get_request) { 168 MAINLOOP: while (my $c = $d->accept) {
127 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) { 169 while (my $r = $c->get_request) {
128 $c->send_basic_header($1); 170 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) {
129 $c->send_crlf; 171 $c->send_basic_header($1);
130 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) { 172 $c->send_crlf;
131 $c->send_basic_header; 173 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) {
132 $c->send_crlf; 174 $c->send_basic_header;
133 $c->send_file_response("$Bin/var/$1"); 175 $c->send_crlf;
134 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") { 176 $c->send_file_response("$Bin/var/$1");
135 $c->send_basic_header; 177 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") {
136 $c->send_crlf; 178 $c->send_basic_header;
137 sleep 1; 179 $c->send_crlf;
138 $c->send_response("slow"); 180 sleep 1;
139 } elsif ($r->url->path eq "/method") { 181 $c->send_response("slow");
140 if ($r->method eq "DELETE") { 182 } elsif ($r->url->path eq "/method") {
141 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED); 183 if ($r->method eq "DELETE") {
142 } elsif ($r->method eq "foo") { 184 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED);
143 $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED); 185 } elsif ($r->method eq "foo") {
186 $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED);
187 } else {
188 $c->send_status_line(200, $r->method);
189 }
190 } elsif ($r->url->path eq "/postdata") {
191 $c->send_basic_header;
192 $c->send_crlf;
193 $c->send_response($r->method.":".$r->content);
194 } elsif ($r->url->path eq "/redirect") {
195 $c->send_redirect( "/redirect2" );
196 } elsif ($r->url->path eq "/redir_external") {
197 $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" );
198 } elsif ($r->url->path eq "/redirect2") {
199 $c->send_basic_header;
200 $c->send_crlf;
201 $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' ));
202 } elsif ($r->url->path eq "/redir_timeout") {
203 $c->send_redirect( "/timeout" );
204 } elsif ($r->url->path eq "/timeout") {
205 # Keep $c from being destroyed, but prevent severe leaks
206 unshift @persist, $c;
207 delete($persist[1000]);
208 next MAINLOOP;
209 } elsif ($r->url->path eq "/header_check") {
210 $c->send_basic_header;
211 $c->send_header('foo');
212 $c->send_crlf;
213 } elsif ($r->url->path eq "/virtual_port") {
214 # return sent Host header
215 $c->send_basic_header;
216 $c->send_crlf;
217 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
218 } elsif ($r->url->path eq "/chunked") {
219 my $chunks = ["chunked", "encoding", "test\n"];
220 $c->send_response(HTTP::Response->new( 200, 'OK', undef, sub {
221 my $chunk = shift @{$chunks};
222 return unless $chunk;
223 sleep(1);
224 return($chunk);
225 }));
144 } else { 226 } else {
145 $c->send_status_line(200, $r->method); 227 $c->send_error(HTTP::Status->RC_FORBIDDEN);
146 } 228 }
147 } elsif ($r->url->path eq "/postdata") { 229 $c->close;
148 $c->send_basic_header;
149 $c->send_crlf;
150 $c->send_response($r->method.":".$r->content);
151 } elsif ($r->url->path eq "/redirect") {
152 $c->send_redirect( "/redirect2" );
153 } elsif ($r->url->path eq "/redir_external") {
154 $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" );
155 } elsif ($r->url->path eq "/redirect2") {
156 $c->send_basic_header;
157 $c->send_crlf;
158 $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' ));
159 } elsif ($r->url->path eq "/redir_timeout") {
160 $c->send_redirect( "/timeout" );
161 } elsif ($r->url->path eq "/timeout") {
162 # Keep $c from being destroyed, but prevent severe leaks
163 unshift @persist, $c;
164 delete($persist[1000]);
165 next MAINLOOP;
166 } elsif ($r->url->path eq "/header_check") {
167 $c->send_basic_header;
168 $c->send_header('foo');
169 $c->send_crlf;
170 } elsif ($r->url->path eq "/virtual_port") {
171 # return sent Host header
172 $c->send_basic_header;
173 $c->send_crlf;
174 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
175 } else {
176 $c->send_error(HTTP::Status->RC_FORBIDDEN);
177 } 230 }
178 $c->close;
179 } 231 }
180 } 232 }
181} 233}
182 234
235sub run_hacked_http_server {
236 my $socket = shift;
237
238 # auto-flush on socket
239 $| = 1;
240
241
242 while(1)
243 {
244 # waiting for a new client connection
245 my $client_socket = $socket->accept();
246
247 # get information about a newly connected client
248 my $client_address = $client_socket->peerhost();
249 my $client_portn = $client_socket->peerport();
250 print "connection from $client_address:$client_portn";
251
252 # read up to 1024 characters from the connected client
253 my $data = "";
254 $client_socket->recv($data, 1024);
255 print "received data: $data";
256
257 # write response data to the connected client
258 $data = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n";
259 $client_socket->send($data);
260
261 # notify client that response has been sent
262 shutdown($client_socket, 1);
263 }
264}
265
183END { 266END {
184 foreach my $pid (@pids) { 267 foreach my $pid (@pids) {
185 if ($pid) { print "Killing $pid\n"; kill "INT", $pid } 268 if ($pid) { print "Killing $pid\n"; kill "INT", $pid }
@@ -195,30 +278,50 @@ if ($ARGV[0] && $ARGV[0] eq "-d") {
195my $result; 278my $result;
196my $command = "./$plugin -H 127.0.0.1"; 279my $command = "./$plugin -H 127.0.0.1";
197 280
281run_chunked_encoding_special_test( {command => "$command -p $port_hacked_http"});
198run_common_tests( { command => "$command -p $port_http" } ); 282run_common_tests( { command => "$command -p $port_http" } );
199SKIP: { 283SKIP: {
200 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; 284 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https};
201 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 285 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
202 286
287 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
288
203 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 289 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
204 is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); 290 is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
205 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" ); 291 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" );
206 292
207 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 293 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
208 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); 294 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
209 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 295 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
210 296
211 # Expired cert tests 297 # Expired cert tests
212 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 298 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
213 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); 299 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
214 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 300 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
215 301
216 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 302 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
217 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); 303 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
218 is( $result->output, 304 is( $result->output,
219 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 11:00:26 2008 +0000.', 305 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.',
220 "output ok" ); 306 "output ok" );
221 307
308 # client cert tests
309 my $cmd;
310 $cmd = "$command -p $port_https_clientcert"
311 . " -J \"$Bin/certs/client-cert.pem\""
312 . " -K \"$Bin/certs/client-key.pem\""
313 . " -u /statuscode/200";
314 $result = NPTest->testCmd($cmd);
315 is( $result->return_code, 0, $cmd);
316 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
317
318 $cmd = "$command -p $port_https_clientcert"
319 . " -J \"$Bin/certs/clientchain-cert.pem\""
320 . " -K \"$Bin/certs/clientchain-key.pem\""
321 . " -u /statuscode/200";
322 $result = NPTest->testCmd($cmd);
323 is( $result->return_code, 0, $cmd);
324 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
222} 325}
223 326
224my $cmd; 327my $cmd;
@@ -459,4 +562,20 @@ sub run_common_tests {
459 }; 562 };
460 is( $@, "", $cmd ); 563 is( $@, "", $cmd );
461 564
565 $cmd = "$command -u /chunked -s 'chunkedencodingtest' -d 'Transfer-Encoding: chunked'";
566 eval {
567 $result = NPTest->testCmd( $cmd, 5 );
568 };
569 is( $@, "", $cmd );
570}
571
572sub run_chunked_encoding_special_test {
573 my ($opts) = @_;
574 my $command = $opts->{command};
575
576 $cmd = "$command -u / -s 'ChunkedEncodingSpecialTest'";
577 eval {
578 $result = NPTest->testCmd( $cmd, 5 );
579 };
580 is( $@, "", $cmd );
462} 581}
diff --git a/plugins/tests/check_procs.t b/plugins/tests/check_procs.t
index 54d43d9..b3a0a30 100755
--- a/plugins/tests/check_procs.t
+++ b/plugins/tests/check_procs.t
@@ -8,13 +8,14 @@ use Test::More;
8use NPTest; 8use NPTest;
9 9
10if (-x "./check_procs") { 10if (-x "./check_procs") {
11 plan tests => 50; 11 plan tests => 54;
12} else { 12} else {
13 plan skip_all => "No check_procs compiled"; 13 plan skip_all => "No check_procs compiled";
14} 14}
15 15
16my $result; 16my $result;
17my $command = "./check_procs --input-file=tests/var/ps-axwo.darwin"; 17my $command = "./check_procs --input-file=tests/var/ps-axwo.darwin";
18my $cmd_etime = "./check_procs --input-file=tests/var/ps-axwo.debian";
18 19
19$result = NPTest->testCmd( "$command" ); 20$result = NPTest->testCmd( "$command" );
20is( $result->return_code, 0, "Run with no options" ); 21is( $result->return_code, 0, "Run with no options" );
@@ -33,9 +34,13 @@ is( $result->return_code, 0, "Checking no threshold breeched" );
33is( $result->output, "PROCS OK: 95 processes | procs=95;100;200;0;", "Output correct" ); 34is( $result->output, "PROCS OK: 95 processes | procs=95;100;200;0;", "Output correct" );
34 35
35$result = NPTest->testCmd( "$command -C launchd -c 5" ); 36$result = NPTest->testCmd( "$command -C launchd -c 5" );
36is( $result->return_code, 2, "Checking processes filtered by command name" ); 37is( $result->return_code, 2, "Checking processes matched by command name" );
37is( $result->output, "PROCS CRITICAL: 6 processes with command name 'launchd' | procs=6;;5;0;", "Output correct" ); 38is( $result->output, "PROCS CRITICAL: 6 processes with command name 'launchd' | procs=6;;5;0;", "Output correct" );
38 39
40$result = NPTest->testCmd( "$command -X bash -c 5" );
41is( $result->return_code, 2, "Checking processes excluded by command name" );
42is( $result->output, "PROCS CRITICAL: 95 processes with exclude progs 'bash' | procs=95;;5;0;", "Output correct" );
43
39SKIP: { 44SKIP: {
40 skip 'user with uid 501 required', 4 unless getpwuid(501); 45 skip 'user with uid 501 required', 4 unless getpwuid(501);
41 46
@@ -69,9 +74,21 @@ SKIP: {
69 like( $result->output, '/^PROCS OK: 0 processes with UID = -2 \(nobody\), args \'UsB\'/', "Output correct" ); 74 like( $result->output, '/^PROCS OK: 0 processes with UID = -2 \(nobody\), args \'UsB\'/', "Output correct" );
70}; 75};
71 76
72$result = NPTest->testCmd( "$command --ereg-argument-array='mdworker.*501'" ); 77SKIP: {
73is( $result->return_code, 0, "Checking regexp search of arguments" ); 78 skip 'check_procs is compiled with etime format support', 2 if `$command -vvv` =~ m/etime/mx;
74is( $result->output, "PROCS OK: 1 process with regex args 'mdworker.*501' | procs=1;;;0;", "Output correct" ); 79
80 $result = NPTest->testCmd( "$command --ereg-argument-array='mdworker.*501'" );
81 is( $result->return_code, 0, "Checking regexp search of arguments" );
82 is( $result->output, "PROCS OK: 1 process with regex args 'mdworker.*501' | procs=1;;;0;", "Output correct" );
83}
84
85SKIP: {
86 skip 'check_procs is compiled without etime format support', 2 if `$cmd_etime -vvv` !~ m/etime/mx;
87
88 $result = NPTest->testCmd( "$cmd_etime -m ELAPSED -C apache2 -w 1000 -c 2000" );
89 is( $result->return_code, 2, "Checking elapsed time threshold" );
90 is( $result->output, "ELAPSED CRITICAL: 10 crit, 0 warn out of 10 processes with command name 'apache2' | procs=10;;;0; procs_warn=0;;;0; procs_crit=10;;;0;", "Output correct" );
91}
75 92
76$result = NPTest->testCmd( "$command --vsz 1000000" ); 93$result = NPTest->testCmd( "$command --vsz 1000000" );
77is( $result->return_code, 0, "Checking filter by VSZ" ); 94is( $result->return_code, 0, "Checking filter by VSZ" );
@@ -83,7 +100,7 @@ is( $result->output, 'PROCS OK: 3 processes with RSS >= 100000 | procs=3;;;0;',
83 100
84$result = NPTest->testCmd( "$command -s S" ); 101$result = NPTest->testCmd( "$command -s S" );
85is( $result->return_code, 0, "Checking filter for sleeping processes" ); 102is( $result->return_code, 0, "Checking filter for sleeping processes" );
86like( $result->output, '/^PROCS OK: 44 processes with STATE = S/', "Output correct" ); 103like( $result->output, '/^PROCS OK: 88 processes with STATE = S/', "Output correct" );
87 104
88$result = NPTest->testCmd( "$command -s Z" ); 105$result = NPTest->testCmd( "$command -s Z" );
89is( $result->return_code, 0, "Checking filter for zombies" ); 106is( $result->return_code, 0, "Checking filter for zombies" );
@@ -129,4 +146,3 @@ is( $result->output, 'RSS CRITICAL: 5 crit, 0 warn out of 95 processes [WindowSe
129$result = NPTest->testCmd( "$command --ereg-argument-array='(nosuchname|nosuch2name)'" ); 146$result = NPTest->testCmd( "$command --ereg-argument-array='(nosuchname|nosuch2name)'" );
130is( $result->return_code, 0, "Checking no pipe symbol in output" ); 147is( $result->return_code, 0, "Checking no pipe symbol in output" );
131is( $result->output, "PROCS OK: 0 processes with regex args '(nosuchname,nosuch2name)' | procs=0;;;0;", "Output correct" ); 148is( $result->output, "PROCS OK: 0 processes with regex args '(nosuchname,nosuch2name)' | procs=0;;;0;", "Output correct" );
132
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t
index 85d6bf5..bfe42e1 100755
--- a/plugins/tests/check_snmp.t
+++ b/plugins/tests/check_snmp.t
@@ -9,7 +9,7 @@ use NPTest;
9use FindBin qw($Bin); 9use FindBin qw($Bin);
10use POSIX qw/strftime/; 10use POSIX qw/strftime/;
11 11
12my $tests = 67; 12my $tests = 81;
13# Check that all dependent modules are available 13# Check that all dependent modules are available
14eval { 14eval {
15 require NetSNMP::OID; 15 require NetSNMP::OID;
@@ -53,13 +53,13 @@ if ($pid) {
53 #print "child\n"; 53 #print "child\n";
54 54
55 print "Please contact SNMP at: $port_snmp\n"; 55 print "Please contact SNMP at: $port_snmp\n";
56 close(STDERR); # Coment out to debug snmpd problems (most errors sent there are OK) 56 close(STDERR); # Comment out to debug snmpd problems (most errors sent there are OK)
57 exec("snmpd -c tests/conf/snmpd.conf -C -f -r udp:$port_snmp"); 57 exec("snmpd -c tests/conf/snmpd.conf -C -f -r udp:$port_snmp");
58} 58}
59 59
60END { 60END {
61 foreach my $pid (@pids) { 61 foreach my $pid (@pids) {
62 if ($pid) { print "Killing $pid\n"; kill "INT", $pid } 62 if ($pid) { print "Killing $pid\n"; kill "INT", $pid }
63 } 63 }
64}; 64};
65 65
@@ -227,7 +227,7 @@ is($res->output, 'SNMP OK - "555\"I said\"" | ', "Check string with a double quo
227 227
228$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.15 -r 'CUSTOM CHECK OK'" ); 228$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.15 -r 'CUSTOM CHECK OK'" );
229is($res->return_code, 0, "String check should check whole string, not a parsed number" ); 229is($res->return_code, 0, "String check should check whole string, not a parsed number" );
230is($res->output, 'SNMP OK - "CUSTOM CHECK OK: foo is 12345" | ', "String check witn numbers returns whole string"); 230is($res->output, 'SNMP OK - "CUSTOM CHECK OK: foo is 12345" | ', "String check with numbers returns whole string");
231 231
232$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); 232$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" );
233is($res->return_code, 0, "Negative integer check OK" ); 233is($res->return_code, 0, "Negative integer check OK" );
@@ -251,9 +251,36 @@ is($res->output, 'SNMP CRITICAL - *-4* | iso.3.6.1.4.1.8072.3.2.67.17=-4;-2:;-3:
251 251
252$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" ); 252$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" );
253is($res->return_code, 0, "Negative float OK" ); 253is($res->return_code, 0, "Negative float OK" );
254is($res->output, 'SNMP OK - -6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;~:-6.5 ', "Negative float OK output" ); 254is($res->output, 'SNMP OK - -6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;@-6.5:~ ', "Negative float OK output" );
255 255
256$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" ); 256$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" );
257is($res->return_code, 1, "Negative float WARNING" ); 257is($res->return_code, 1, "Negative float WARNING" );
258is($res->output, 'SNMP WARNING - *-6.6* | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;~:-6.65;~:-6.55 ', "Negative float WARNING output" ); 258is($res->output, 'SNMP WARNING - *-6.6* | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;@-6.65:~;@-6.55:~ ', "Negative float WARNING output" );
259 259
260$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-10:20' -c '2:200000,-20:30'" );
261is($res->return_code, 0, "Multiple OIDs with thresholds" );
262like($res->output, '/SNMP OK - \d+ -4 | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" );
263
264$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-1:2' -c '2:200000,-20:30'" );
265is($res->return_code, 1, "Multiple OIDs with thresholds" );
266like($res->output, '/SNMP WARNING - \d+ \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" );
267
268$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" );
269is($res->return_code, 2, "Multiple OIDs with some thresholds" );
270like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" );
271
272$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19");
273is($res->return_code, 0, "Test plain .1.3.6.1.4.1.8072.3.2.67.6 RC" );
274is($res->output,'SNMP OK - 42 | iso.3.6.1.4.1.8072.3.2.67.19=42 ', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" );
275
276$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 -M .1");
277is($res->return_code, 0, "Test multiply RC" );
278is($res->output,'SNMP OK - 4.200000 | iso.3.6.1.4.1.8072.3.2.67.19=4.200000 ' , "Test multiply .1 output" );
279
280$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' ");
281is($res->return_code, 0, "Test multiply RC + format" );
282is($res->output, 'SNMP OK - 4.20 | iso.3.6.1.4.1.8072.3.2.67.19=4.20 ', "Test multiply .1 output + format" );
283
284$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' -w 1");
285is($res->return_code, 1, "Test multiply RC + format + thresholds" );
286is($res->output, 'SNMP WARNING - *4.20* | iso.3.6.1.4.1.8072.3.2.67.19=4.20;1 ', "Test multiply .1 output + format + thresholds" );
diff --git a/plugins/tests/check_snmp_agent.pl b/plugins/tests/check_snmp_agent.pl
index 0e41d57..38912e9 100644
--- a/plugins/tests/check_snmp_agent.pl
+++ b/plugins/tests/check_snmp_agent.pl
@@ -32,11 +32,11 @@ my $multilin5 = 'And now have fun with with this: "C:\\"
32because we\'re not done yet!'; 32because we\'re not done yet!';
33 33
34# Next are arrays of indexes (Type, initial value and increments) 34# Next are arrays of indexes (Type, initial value and increments)
35# 0..16 <---- please update comment when adding/removing fields 35# 0..19 <---- please update comment when adding/removing fields
36my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER, ASN_OCTET_STR, ASN_OCTET_STR ); 36my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER );
37my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000, "stringtests", "3.5", "87.4startswithnumberbutshouldbestring", '555"I said"', 'CUSTOM CHECK OK: foo is 12345', -2, '-4', '-6.6' ); 37my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000, "stringtests", "3.5", "87.4startswithnumberbutshouldbestring", '555"I said"', 'CUSTOM CHECK OK: foo is 12345', -2, '-4', '-6.6', 42 );
38# undef increments are randomized 38# undef increments are randomized
39my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666, undef, undef, undef, undef, undef, -1, undef, undef ); 39my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666, undef, undef, undef, undef, undef, -1, undef, undef, 0 );
40 40
41# Number of elements in our OID 41# Number of elements in our OID
42my $oidelts; 42my $oidelts;
diff --git a/plugins/tests/var/ps-axwo.debian b/plugins/tests/var/ps-axwo.debian
new file mode 100644
index 0000000..5889e9a
--- /dev/null
+++ b/plugins/tests/var/ps-axwo.debian
@@ -0,0 +1,219 @@
1STAT UID PID PPID VSZ RSS %CPU ELAPSED COMMAND COMMAND
2Ss 0 1 0 167244 7144 0.1 26-03:07:26 systemd /lib/systemd/systemd --system --deserialize 17
3S 0 2 0 0 0 0.0 26-03:07:26 kthreadd [kthreadd]
4I< 0 3 2 0 0 0.0 26-03:07:26 rcu_gp [rcu_gp]
5I< 0 4 2 0 0 0.0 26-03:07:26 rcu_par_gp [rcu_par_gp]
6I< 0 6 2 0 0 0.0 26-03:07:26 kworker/0:0H-ev [kworker/0:0H-events_highpri]
7I< 0 9 2 0 0 0.0 26-03:07:26 mm_percpu_wq [mm_percpu_wq]
8S 0 10 2 0 0 0.0 26-03:07:26 rcu_tasks_rude_ [rcu_tasks_rude_]
9S 0 11 2 0 0 0.0 26-03:07:26 rcu_tasks_trace [rcu_tasks_trace]
10S 0 12 2 0 0 0.0 26-03:07:26 ksoftirqd/0 [ksoftirqd/0]
11I 0 13 2 0 0 0.0 26-03:07:26 rcu_sched [rcu_sched]
12S 0 14 2 0 0 0.0 26-03:07:26 migration/0 [migration/0]
13S 0 15 2 0 0 0.0 26-03:07:26 cpuhp/0 [cpuhp/0]
14S 0 16 2 0 0 0.0 26-03:07:26 cpuhp/1 [cpuhp/1]
15S 0 17 2 0 0 0.0 26-03:07:26 migration/1 [migration/1]
16S 0 18 2 0 0 0.0 26-03:07:26 ksoftirqd/1 [ksoftirqd/1]
17I< 0 20 2 0 0 0.0 26-03:07:26 kworker/1:0H-ev [kworker/1:0H-events_highpri]
18S 0 21 2 0 0 0.0 26-03:07:26 cpuhp/2 [cpuhp/2]
19S 0 22 2 0 0 0.0 26-03:07:26 migration/2 [migration/2]
20S 0 23 2 0 0 0.0 26-03:07:26 ksoftirqd/2 [ksoftirqd/2]
21I< 0 25 2 0 0 0.0 26-03:07:26 kworker/2:0H-ev [kworker/2:0H-events_highpri]
22S 0 26 2 0 0 0.0 26-03:07:26 cpuhp/3 [cpuhp/3]
23S 0 27 2 0 0 0.0 26-03:07:26 migration/3 [migration/3]
24S 0 28 2 0 0 0.0 26-03:07:26 ksoftirqd/3 [ksoftirqd/3]
25I< 0 30 2 0 0 0.0 26-03:07:26 kworker/3:0H-ev [kworker/3:0H-events_highpri]
26S 0 35 2 0 0 0.0 26-03:07:26 kdevtmpfs [kdevtmpfs]
27I< 0 36 2 0 0 0.0 26-03:07:26 netns [netns]
28S 0 37 2 0 0 0.0 26-03:07:26 kauditd [kauditd]
29S 0 38 2 0 0 0.0 26-03:07:26 khungtaskd [khungtaskd]
30S 0 39 2 0 0 0.0 26-03:07:26 oom_reaper [oom_reaper]
31I< 0 40 2 0 0 0.0 26-03:07:26 writeback [writeback]
32S 0 41 2 0 0 0.0 26-03:07:26 kcompactd0 [kcompactd0]
33SN 0 42 2 0 0 0.0 26-03:07:26 ksmd [ksmd]
34SN 0 43 2 0 0 0.0 26-03:07:26 khugepaged [khugepaged]
35I< 0 62 2 0 0 0.0 26-03:07:26 kintegrityd [kintegrityd]
36I< 0 63 2 0 0 0.0 26-03:07:26 kblockd [kblockd]
37I< 0 64 2 0 0 0.0 26-03:07:26 blkcg_punt_bio [blkcg_punt_bio]
38I< 0 65 2 0 0 0.0 26-03:07:26 edac-poller [edac-poller]
39I< 0 66 2 0 0 0.0 26-03:07:26 devfreq_wq [devfreq_wq]
40I< 0 67 2 0 0 0.0 26-03:07:26 kworker/2:1H-ev [kworker/2:1H-events_highpri]
41S 0 70 2 0 0 0.3 26-03:07:25 kswapd0 [kswapd0]
42I< 0 71 2 0 0 0.0 26-03:07:25 kthrotld [kthrotld]
43I< 0 72 2 0 0 0.0 26-03:07:25 acpi_thermal_pm [acpi_thermal_pm]
44I< 0 74 2 0 0 0.0 26-03:07:25 ipv6_addrconf [ipv6_addrconf]
45I< 0 80 2 0 0 0.0 26-03:07:25 kworker/3:1H-ev [kworker/3:1H-events_highpri]
46I< 0 84 2 0 0 0.0 26-03:07:25 kstrp [kstrp]
47I< 0 87 2 0 0 0.0 26-03:07:25 zswap-shrink [zswap-shrink]
48I< 0 110 2 0 0 0.0 26-03:07:25 kworker/0:1H-ev [kworker/0:1H-events_highpri]
49I< 0 141 2 0 0 0.0 26-03:07:25 ata_sff [ata_sff]
50S 0 143 2 0 0 0.0 26-03:07:25 scsi_eh_0 [scsi_eh_0]
51I< 0 144 2 0 0 0.0 26-03:07:25 scsi_tmf_0 [scsi_tmf_0]
52S 0 145 2 0 0 0.0 26-03:07:25 scsi_eh_1 [scsi_eh_1]
53I< 0 146 2 0 0 0.0 26-03:07:25 scsi_tmf_1 [scsi_tmf_1]
54S 0 147 2 0 0 0.0 26-03:07:25 scsi_eh_2 [scsi_eh_2]
55I< 0 148 2 0 0 0.0 26-03:07:25 scsi_tmf_2 [scsi_tmf_2]
56S 0 149 2 0 0 0.0 26-03:07:25 scsi_eh_3 [scsi_eh_3]
57I< 0 150 2 0 0 0.0 26-03:07:25 scsi_tmf_3 [scsi_tmf_3]
58S 0 151 2 0 0 0.0 26-03:07:25 scsi_eh_4 [scsi_eh_4]
59I< 0 152 2 0 0 0.0 26-03:07:25 scsi_tmf_4 [scsi_tmf_4]
60S 0 153 2 0 0 0.0 26-03:07:25 scsi_eh_5 [scsi_eh_5]
61I< 0 154 2 0 0 0.0 26-03:07:25 scsi_tmf_5 [scsi_tmf_5]
62S 0 158 2 0 0 0.0 26-03:07:25 card0-crtc0 [card0-crtc0]
63S 0 159 2 0 0 0.0 26-03:07:25 card0-crtc1 [card0-crtc1]
64S 0 160 2 0 0 0.0 26-03:07:25 card0-crtc2 [card0-crtc2]
65I< 0 162 2 0 0 0.0 26-03:07:25 kworker/1:1H-ev [kworker/1:1H-events_highpri]
66S 0 163 2 0 0 0.0 26-03:07:25 scsi_eh_6 [scsi_eh_6]
67I< 0 164 2 0 0 0.0 26-03:07:25 scsi_tmf_6 [scsi_tmf_6]
68S 0 165 2 0 0 0.0 26-03:07:25 usb-storage [usb-storage]
69I< 0 167 2 0 0 0.0 26-03:07:25 uas [uas]
70I< 0 176 2 0 0 0.0 26-03:07:25 kdmflush [kdmflush]
71I< 0 177 2 0 0 0.0 26-03:07:25 kdmflush [kdmflush]
72S 0 202 2 0 0 0.0 26-03:07:24 scsi_eh_7 [scsi_eh_7]
73I< 0 203 2 0 0 0.0 26-03:07:24 scsi_tmf_7 [scsi_tmf_7]
74S 0 204 2 0 0 0.0 26-03:07:24 usb-storage [usb-storage]
75I< 0 232 2 0 0 0.0 26-03:07:23 btrfs-worker [btrfs-worker]
76I< 0 233 2 0 0 0.0 26-03:07:23 btrfs-worker-hi [btrfs-worker-hi]
77I< 0 234 2 0 0 0.0 26-03:07:23 btrfs-delalloc [btrfs-delalloc]
78I< 0 235 2 0 0 0.0 26-03:07:23 btrfs-flush_del [btrfs-flush_del]
79I< 0 236 2 0 0 0.0 26-03:07:23 btrfs-cache [btrfs-cache]
80I< 0 237 2 0 0 0.0 26-03:07:23 btrfs-fixup [btrfs-fixup]
81I< 0 238 2 0 0 0.0 26-03:07:23 btrfs-endio [btrfs-endio]
82I< 0 239 2 0 0 0.0 26-03:07:23 btrfs-endio-met [btrfs-endio-met]
83I< 0 240 2 0 0 0.0 26-03:07:23 btrfs-endio-met [btrfs-endio-met]
84I< 0 241 2 0 0 0.0 26-03:07:23 btrfs-endio-rai [btrfs-endio-rai]
85I< 0 242 2 0 0 0.0 26-03:07:23 btrfs-rmw [btrfs-rmw]
86I< 0 243 2 0 0 0.0 26-03:07:23 btrfs-endio-wri [btrfs-endio-wri]
87I< 0 244 2 0 0 0.0 26-03:07:23 btrfs-freespace [btrfs-freespace]
88I< 0 245 2 0 0 0.0 26-03:07:23 btrfs-delayed-m [btrfs-delayed-m]
89I< 0 246 2 0 0 0.0 26-03:07:23 btrfs-readahead [btrfs-readahead]
90I< 0 247 2 0 0 0.0 26-03:07:23 btrfs-qgroup-re [btrfs-qgroup-re]
91S 0 248 2 0 0 0.0 26-03:07:23 btrfs-cleaner [btrfs-cleaner]
92S 0 249 2 0 0 0.2 26-03:07:23 btrfs-transacti [btrfs-transacti]
93I< 0 317 2 0 0 0.0 26-03:07:22 rpciod [rpciod]
94I< 0 322 2 0 0 0.0 26-03:07:22 xprtiod [xprtiod]
95S 0 381 2 0 0 0.0 26-03:07:22 irq/133-mei_me [irq/133-mei_me]
96S 0 422 2 0 0 0.0 26-03:07:22 watchdogd [watchdogd]
97I< 0 523 2 0 0 0.0 26-03:07:22 led_workqueue [led_workqueue]
98I< 0 583 2 0 0 0.0 26-03:07:22 cryptd [cryptd]
99I< 0 590 2 0 0 0.0 26-03:07:22 ext4-rsv-conver [ext4-rsv-conver]
100Ss 104 693 1 12324 4292 0.5 26-03:07:21 dbus-daemon /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
101Ss 0 731 1 575120 1368 0.0 26-03:07:21 systemd-logind /lib/systemd/systemd-logind
102Ssl 0 1111 1 121248 732 0.0 26-03:07:18 unattended-upgr /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
103S 0 1141 2 0 0 0.0 26-03:07:18 lockd [lockd]
104I< 0 1459 2 0 0 0.0 26-03:07:16 nfsiod [nfsiod]
105S 0 1621 2 0 0 0.0 26-03:07:15 NFSv4 callback [NFSv4 callback]
106Ssl 0 1771 1 1548340 676 0.0 26-03:07:13 libvirtd /usr/sbin/libvirtd
107I< 0 24315 2 0 0 0.0 26-02:49:02 cifsiod [cifsiod]
108I< 0 24316 2 0 0 0.0 26-02:49:02 smb3decryptd [smb3decryptd]
109I< 0 24317 2 0 0 0.0 26-02:49:02 cifsfileinfoput [cifsfileinfoput]
110I< 0 24318 2 0 0 0.0 26-02:49:02 cifsoplockd [cifsoplockd]
111I< 0 24319 2 0 0 0.0 26-02:49:02 cifs-dfscache [cifs-dfscache]
112S 0 24322 2 0 0 0.0 26-02:49:02 cifsd [cifsd]
113I< 0 24413 2 0 0 0.0 26-02:48:57 btrfs-worker [btrfs-worker]
114I< 0 24414 2 0 0 0.0 26-02:48:57 btrfs-worker-hi [btrfs-worker-hi]
115I< 0 24415 2 0 0 0.0 26-02:48:57 btrfs-delalloc [btrfs-delalloc]
116I< 0 24416 2 0 0 0.0 26-02:48:57 btrfs-flush_del [btrfs-flush_del]
117I< 0 24418 2 0 0 0.0 26-02:48:57 btrfs-cache [btrfs-cache]
118I< 0 24419 2 0 0 0.0 26-02:48:57 btrfs-fixup [btrfs-fixup]
119I< 0 24420 2 0 0 0.0 26-02:48:57 btrfs-endio [btrfs-endio]
120I< 0 24421 2 0 0 0.0 26-02:48:57 btrfs-endio-met [btrfs-endio-met]
121I< 0 24422 2 0 0 0.0 26-02:48:57 btrfs-endio-met [btrfs-endio-met]
122I< 0 24423 2 0 0 0.0 26-02:48:57 btrfs-endio-rai [btrfs-endio-rai]
123I< 0 24424 2 0 0 0.0 26-02:48:57 btrfs-rmw [btrfs-rmw]
124I< 0 24425 2 0 0 0.0 26-02:48:57 btrfs-endio-wri [btrfs-endio-wri]
125I< 0 24426 2 0 0 0.0 26-02:48:57 btrfs-freespace [btrfs-freespace]
126I< 0 24427 2 0 0 0.0 26-02:48:57 btrfs-delayed-m [btrfs-delayed-m]
127I< 0 24428 2 0 0 0.0 26-02:48:57 btrfs-readahead [btrfs-readahead]
128I< 0 24429 2 0 0 0.0 26-02:48:57 btrfs-qgroup-re [btrfs-qgroup-re]
129S 0 24450 2 0 0 0.0 26-02:48:53 btrfs-cleaner [btrfs-cleaner]
130S 0 24451 2 0 0 0.0 26-02:48:53 btrfs-transacti [btrfs-transacti]
131I< 0 747708 2 0 0 0.0 16-21:06:20 xfsalloc [xfsalloc]
132I< 0 747709 2 0 0 0.0 16-21:06:20 xfs_mru_cache [xfs_mru_cache]
133S 0 747713 2 0 0 0.0 16-21:06:20 jfsIO [jfsIO]
134S 0 747714 2 0 0 0.0 16-21:06:20 jfsCommit [jfsCommit]
135S 0 747715 2 0 0 0.0 16-21:06:20 jfsCommit [jfsCommit]
136S 0 747716 2 0 0 0.0 16-21:06:20 jfsCommit [jfsCommit]
137S 0 747717 2 0 0 0.0 16-21:06:20 jfsCommit [jfsCommit]
138S 0 747718 2 0 0 0.0 16-21:06:20 jfsSync [jfsSync]
139Ss 0 1071687 1 105976 28304 0.0 3-03:12:31 systemd-journal /lib/systemd/systemd-journald
140Ss 0 1934146 1 25672 4704 0.0 11:19:31 cupsd /usr/sbin/cupsd -l
141Ssl 0 1934148 1 182868 8540 0.0 11:19:31 cups-browsed /usr/sbin/cups-browsed
142S 13 1934155 3392655 5752 88 0.0 11:19:31 pinger (pinger)
143S< 33 1934166 3393034 57996 5460 0.0 11:19:31 apache2 /usr/sbin/apache2 -k start
144S< 33 1934167 3393034 216944 13892 0.0 11:19:30 apache2 /usr/sbin/apache2 -k start
145S< 33 1934168 3393034 216944 13756 0.0 11:19:30 apache2 /usr/sbin/apache2 -k start
146S< 33 1934169 3393034 216936 13732 0.0 11:19:30 apache2 /usr/sbin/apache2 -k start
147S< 33 1934170 3393034 216944 13888 0.0 11:19:30 apache2 /usr/sbin/apache2 -k start
148S< 33 1934172 3393034 216944 15388 0.0 11:19:30 apache2 /usr/sbin/apache2 -k start
149S< 33 1934701 3393034 216936 13736 0.0 11:19:29 apache2 /usr/sbin/apache2 -k start
150S< 33 1935056 3393034 216920 13724 0.0 11:19:28 apache2 /usr/sbin/apache2 -k start
151S 7 1936834 1934146 16652 832 0.0 11:18:12 dbus /usr/lib/cups/notifier/dbus dbus://
152S< 33 1955909 3393034 216928 13792 0.0 11:00:25 apache2 /usr/sbin/apache2 -k start
153I< 0 2531464 2 0 0 0.0 06:35:47 kworker/u9:0-i9 [kworker/u9:0-i915_flip]
154I 0 2570506 2 0 0 0.0 06:27:41 kworker/1:0-cgr [kworker/1:0-cgroup_destroy]
155I 0 2596195 2 0 0 0.0 06:21:52 kworker/1:1-eve [kworker/1:1-events]
156I 0 2785341 2 0 0 0.0 03:34:16 kworker/u8:8-bt [kworker/u8:8-btrfs-endio-write]
157I 0 2785520 2 0 0 0.0 03:33:50 kworker/3:0-eve [kworker/3:0-events]
158I 0 2798669 2 0 0 0.0 03:21:09 kworker/u8:5-bt [kworker/u8:5-btrfs-endio-write]
159Ss 0 2803015 1 5616 3108 0.0 03:17:54 cron /usr/sbin/cron -f
160I 0 2845483 2 0 0 0.0 02:38:11 kworker/0:3-eve [kworker/0:3-events]
161I 0 2939490 2 0 0 0.1 01:10:32 kworker/0:0-eve [kworker/0:0-events]
162I 0 2939754 2 0 0 0.0 01:10:26 kworker/u8:1-i9 [kworker/u8:1-i915]
163I 0 2942040 2 0 0 0.0 01:08:02 kworker/u8:7-bt [kworker/u8:7-btrfs-endio-meta]
164S 117 2954268 3392551 40044 5772 0.0 56:37 pickup pickup -l -t unix -u -c
165I 0 2965195 2 0 0 0.0 46:00 kworker/u8:0-bt [kworker/u8:0-btrfs-worker]
166I 0 2977972 2 0 0 0.0 33:54 kworker/u8:2-bt [kworker/u8:2-btrfs-endio-write]
167I 0 2985488 2 0 0 0.0 27:02 kworker/u8:3-bl [kworker/u8:3-blkcg_punt_bio]
168I 0 2987519 2 0 0 1.0 25:15 kworker/2:1-eve [kworker/2:1-events]
169I 0 2987601 2 0 0 0.0 25:03 kworker/u8:9-i9 [kworker/u8:9-i915]
170I< 0 2995218 2 0 0 0.0 18:41 kworker/u9:2-xp [kworker/u9:2-xprtiod]
171I 0 2997170 2 0 0 0.0 16:41 kworker/3:1-rcu [kworker/3:1-rcu_gp]
172I 0 3001264 2 0 0 0.0 13:01 kworker/u8:4-bt [kworker/u8:4-btrfs-endio-write]
173I 0 3004697 2 0 0 0.7 09:41 kworker/2:0-eve [kworker/2:0-events]
174I 0 3010619 2 0 0 1.0 04:29 kworker/2:2-eve [kworker/2:2-events]
175I 0 3014612 2 0 0 0.0 00:41 kworker/3:2-eve [kworker/3:2-events]
176S 0 3015082 2803015 6716 3028 0.0 00:30 cron /usr/sbin/CRON -f
177I 0 3015382 2 0 0 0.0 00:00 kworker/u8:6-bt [kworker/u8:6-btrfs-endio-meta]
178Ss 1 3392068 1 5592 504 0.0 15-02:34:39 atd /usr/sbin/atd -f
179Ssl 0 3392072 1 235796 1740 0.0 15-02:34:39 accounts-daemon /usr/libexec/accounts-daemon
180Ssl 106 3392076 1 315708 6128 0.0 15-02:34:39 colord /usr/libexec/colord
181Ss 0 3392083 1 8120 720 0.0 15-02:34:39 haveged /usr/sbin/haveged --Foreground --verbose=1
182Ss 0 3392090 1 5168 132 0.0 15-02:34:39 blkmapd /usr/sbin/blkmapd
183SNsl 111 3392094 1 155648 440 0.0 15-02:34:39 rtkit-daemon /usr/libexec/rtkit-daemon
184Ssl 0 3392097 1 290168 1352 0.0 15-02:34:39 packagekitd /usr/libexec/packagekitd
185Ss 128 3392100 1 7960 448 0.0 15-02:34:39 rpcbind /sbin/rpcbind -f -w
186Ss 0 3392114 1 13432 616 0.0 15-02:34:39 systemd-machine /lib/systemd/systemd-machined
187Ss 0 3392118 1 13316 848 0.0 15-02:34:39 sshd sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
188Ssl 0 3392124 1 244072 2456 0.0 15-02:34:39 upowerd /usr/libexec/upowerd
189Ssl 0 3392138 1 1634748 10684 0.0 15-02:34:39 containerd /usr/bin/containerd
190Ssl 0 3392139 1 222768 1784 0.0 15-02:34:39 rsyslogd /usr/sbin/rsyslogd -n -iNONE
191Ss 13 3392140 1 3344 152 0.0 15-02:34:39 polipo /usr/bin/polipo -c /etc/polipo/config pidFile=/var/run/polipo/polipo.pid daemonise=true
192Ssl 119 3392156 1 76472 1688 0.0 15-02:34:39 ntpd /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 119:126
193Ss 120 3392168 1 4656 276 0.0 15-02:34:39 rpc.statd /sbin/rpc.statd --no-notify
194Ss 0 3392171 1 5072 432 0.0 15-02:34:39 rpc.mountd /usr/sbin/rpc.mountd --manage-gids
195Ss 0 3392176 1 5008 288 0.0 15-02:34:39 rpc.idmapd /usr/sbin/rpc.idmapd
196Ss 105 3392184 1 15544 6816 3.5 15-02:34:39 avahi-daemon avahi-daemon: running [tsui.local]
197Ss 0 3392186 1 25288 3860 0.0 15-02:34:39 systemd-udevd /lib/systemd/systemd-udevd
198S 105 3392190 3392184 8788 52 0.0 15-02:34:39 avahi-daemon avahi-daemon: chroot helper
199Ssl 0 3392197 1 396120 4188 0.0 15-02:34:39 udisksd /usr/libexec/udisks2/udisksd
200Ssl 0 3392214 1 237504 6632 0.0 15-02:34:39 polkitd /usr/libexec/polkitd --no-debug
201Ss 0 3392284 1 9684 560 0.0 15-02:34:38 xinetd /usr/sbin/xinetd -pidfile /run/xinetd.pid -stayalive -inetd_compat -inetd_ipv6
202Ssl 0 3392285 1 314840 1352 0.0 15-02:34:38 ModemManager /usr/sbin/ModemManager
203Ss 0 3392317 1 2352 140 0.0 15-02:34:38 acpid /usr/sbin/acpid
204S 0 3392400 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
205S 0 3392401 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
206S 0 3392402 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
207S 0 3392403 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
208S 0 3392404 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
209S 0 3392405 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
210S 0 3392407 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
211S 0 3392410 2 0 0 0.0 15-02:34:38 nfsd [nfsd]
212Ss 0 3392551 1 40092 1304 0.0 15-02:34:37 master /usr/lib/postfix/sbin/master -w
213S 117 3392553 3392551 40156 568 0.0 15-02:34:37 qmgr qmgr -l -t unix -u
214Ss 0 3392650 1 63652 4 0.0 15-02:34:36 squid /usr/sbin/squid --foreground -sYC
215Ssl 116 3392652 1 1675196 93848 0.0 15-02:34:36 mariadbd /usr/sbin/mariadbd
216S 13 3392655 3392650 81776 21232 0.0 15-02:34:36 squid (squid-1) --kid squid-1 --foreground -sYC
217S 13 3392657 3392655 5572 68 0.0 15-02:34:36 log_file_daemon (logfile-daemon) /var/log/squid/access.log
218S<s 0 3393034 1 216648 7560 0.0 15-02:34:34 apache2 /usr/sbin/apache2 -k start
219Ss 33 3393037 1 3432 180 0.0 15-02:34:34 htcacheclean /usr/bin/htcacheclean -d 120 -p /var/cache/apache2/mod_cache_disk -l 300M -n
diff --git a/plugins/tests/var/ps_axwo.debian b/plugins/tests/var/ps_axwo.debian
deleted file mode 100644
index 37a2d35..0000000
--- a/plugins/tests/var/ps_axwo.debian
+++ /dev/null
@@ -1,84 +0,0 @@
1STAT UID PID PPID VSZ RSS %CPU COMMAND COMMAND
2S 0 1 0 1504 428 0.0 init init [2]
3SN 0 2 1 0 0 0.0 ksoftirqd/0 [ksoftirqd/0]
4S< 0 3 1 0 0 0.0 events/0 [events/0]
5S< 0 4 3 0 0 0.0 khelper [khelper]
6S< 0 5 3 0 0 0.0 kacpid [kacpid]
7S< 0 38 3 0 0 0.0 kblockd/0 [kblockd/0]
8S 0 48 3 0 0 0.0 pdflush [pdflush]
9S< 0 51 3 0 0 0.0 aio/0 [aio/0]
10S 0 50 1 0 0 0.0 kswapd0 [kswapd0]
11S 0 193 1 0 0 0.0 kseriod [kseriod]
12S 0 214 1 0 0 0.0 scsi_eh_0 [scsi_eh_0]
13S 0 221 1 0 0 0.0 khubd [khubd]
14S 0 299 1 0 0 0.3 kjournald [kjournald]
15S 0 1148 1 0 0 0.0 pciehpd_event [pciehpd_event]
16S 0 1168 1 0 0 0.0 shpchpd_event [shpchpd_event]
17Ss 1 1795 1 1612 276 0.0 portmap /sbin/portmap
18Ss 0 2200 1 1652 568 0.0 vmware-guestd /usr/sbin/vmware-guestd --background /var/run/vmware-guestd.pid
19Ss 0 2209 1 2240 532 0.0 inetd /usr/sbin/inetd
20Ss 0 2319 1 3468 792 0.0 sshd /usr/sbin/sshd
21Ss 0 2323 1 2468 676 0.0 rpc.statd /sbin/rpc.statd
22Ss 1 2332 1 1684 488 0.0 atd /usr/sbin/atd
23Ss 0 2335 1 1764 636 0.0 cron /usr/sbin/cron
24Ss+ 0 2350 1 1500 348 0.0 getty /sbin/getty 38400 tty1
25Ss+ 0 2351 1 1500 348 0.0 getty /sbin/getty 38400 tty2
26Ss+ 0 2352 1 1500 348 0.0 getty /sbin/getty 38400 tty3
27Ss+ 0 2353 1 1500 348 0.0 getty /sbin/getty 38400 tty4
28Ss+ 0 2354 1 1500 348 0.0 getty /sbin/getty 38400 tty5
29Ss+ 0 2355 1 1500 348 0.0 getty /sbin/getty 38400 tty6
30S 0 6907 1 2308 892 0.0 mysqld_safe /bin/sh /usr/bin/mysqld_safe
31S 103 6944 6907 123220 27724 0.0 mysqld /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --skip-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock
32S 0 6945 6907 1488 420 0.0 logger logger -p daemon.err -t mysqld_safe -i -t mysqld
33S 1001 17778 1 6436 1588 0.0 snmpd /usr/sbin/snmpd -u nagios -Lsd -Lf /dev/null -p/var/run/snmpd.pid
34Ss 0 17789 1 9496 5556 0.0 snmptrapd /usr/sbin/snmptrapd -t -m ALL -M /usr/share/snmp/mibs:/usr/local/monitoring/snmp/load -p /var/run/snmptrapd.pid
35Ss 0 847 2319 14452 1752 0.0 sshd sshd: tonvoon [priv]
36S 1000 857 847 14616 1832 0.0 sshd sshd: tonvoon@pts/3
37Ss 1000 860 857 2984 1620 0.0 bash -bash
38S 0 868 860 2588 1428 0.0 bash -su
39S+ 1001 877 868 2652 1568 0.0 bash -su
40S 0 6086 3 0 0 0.0 pdflush [pdflush]
41Ss 0 17832 2319 14452 1752 0.0 sshd sshd: tonvoon [priv]
42S 1000 18155 17832 14620 1840 0.0 sshd sshd: tonvoon@pts/0
43Ss 1000 18156 18155 2984 1620 0.0 bash -bash
44S 0 18518 18156 2588 1428 0.0 bash -su
45S 1001 18955 18518 2672 1600 0.0 bash -su
46Ss 0 21683 2319 14452 1756 0.0 sshd sshd: tonvoon [priv]
47S 1000 21742 21683 14620 1896 0.0 sshd sshd: tonvoon@pts/1
48Ss 1000 21743 21742 2984 1620 0.0 bash -bash
49S 0 21748 21743 2592 1432 0.0 bash -su
50S 1001 21757 21748 2620 1540 0.0 bash -su
51Ss 0 2334 2319 14452 1756 0.0 sshd sshd: tonvoon [priv]
52S 1000 2343 2334 14620 1840 0.0 sshd sshd: tonvoon@pts/2
53Ss 1000 2344 2343 2984 1620 0.0 bash -bash
54S 0 2349 2344 2592 1432 0.0 bash -su
55S+ 1001 2364 2349 2620 1520 0.0 bash -su
56T 1001 2454 2364 2096 1032 0.0 vi vi configure.in.rej
57S+ 1001 8500 21757 69604 52576 0.0 opsview_web_ser /usr/bin/perl -w ./script/opsview_web_server.pl -f -d
58Ss 0 7609 2319 14452 1756 0.0 sshd sshd: tonvoon [priv]
59S 1000 7617 7609 14460 1828 0.0 sshd sshd: tonvoon@pts/4
60Ss 1000 7618 7617 2984 1620 0.0 bash -bash
61S 0 7623 7618 2592 1432 0.0 bash -su
62S+ 1001 7632 7623 2620 1528 0.0 bash -su
63Ss 1001 12678 1 20784 17728 0.0 opsviewd opsviewd
64Ss 0 832 1 14512 6360 0.0 apache2 /usr/sbin/apache2 -k start -DSSL
65S 33 842 832 14648 6596 0.0 apache2 /usr/sbin/apache2 -k start -DSSL
66S 33 843 832 14512 6504 0.0 apache2 /usr/sbin/apache2 -k start -DSSL
67S 33 844 832 14512 6476 0.0 apache2 /usr/sbin/apache2 -k start -DSSL
68S 33 845 832 14512 6476 0.0 apache2 /usr/sbin/apache2 -k start -DSSL
69S 33 846 832 14512 6476 0.0 apache2 /usr/sbin/apache2 -k start -DSSL
70Ss 7 4081 1 2464 884 0.0 lpd /usr/sbin/lpd -s
71S 33 26484 832 14512 6476 0.0 apache2 /usr/sbin/apache2 -k start -DSSL
72Ss 1001 22324 1 20252 1612 0.1 nagios ../../bin/nagios -d /usr/local/nagios/etc/nagios.cfg
73Ss 0 23336 2319 14452 1756 0.0 sshd sshd: tonvoon [priv]
74S 1000 23339 23336 14620 1840 0.0 sshd sshd: tonvoon@pts/5
75Ss 1000 23340 23339 2996 1636 0.0 bash -bash
76S 0 23367 23340 3020 1628 0.0 bash bash
77S 1001 23370 23367 3064 1748 0.0 bash bash
78Ss 1001 23783 1 3220 764 0.0 ndo2db /usr/local/nagios/bin/ndo2db -c /usr/local/nagios/etc/ndo2db.cfg
79Ss 1001 23784 1 6428 4948 0.0 import_ndologsd import_ndologsd
80S+ 1001 9803 18955 4132 1936 0.0 ssh ssh altinity@cube02.lei.altinity
81S 1001 22505 22324 20256 1616 0.0 nagios ../../bin/nagios -d /usr/local/nagios/etc/nagios.cfg
82S 1001 22506 22505 1676 608 0.0 check_ping /usr/local/libexec/check_ping -H 192.168.10.23 -w 3000.0,80% -c 5000.0,100% -p 1
83S 1001 22507 22506 1660 492 0.0 ping /bin/ping -n -U -w 10 -c 1 192.168.10.23
84R+ 1001 22508 23370 2308 680 0.0 ps ps axwo stat uid pid ppid vsz rss pcpu comm args
diff --git a/plugins/utils.c b/plugins/utils.c
index ebdae2e..b4214c6 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -589,10 +589,12 @@ char *perfdata (const char *label,
589 xasprintf (&data, "%s;", data); 589 xasprintf (&data, "%s;", data);
590 590
591 if (minp) 591 if (minp)
592 xasprintf (&data, "%s%ld", data, minv); 592 xasprintf (&data, "%s%ld;", data, minv);
593 else
594 xasprintf (&data, "%s;", data);
593 595
594 if (maxp) 596 if (maxp)
595 xasprintf (&data, "%s;%ld", data, maxv); 597 xasprintf (&data, "%s%ld", data, maxv);
596 598
597 return data; 599 return data;
598} 600}
@@ -613,27 +615,27 @@ char *perfdata_uint64 (const char *label,
613 char *data = NULL; 615 char *data = NULL;
614 616
615 if (strpbrk (label, "'= ")) 617 if (strpbrk (label, "'= "))
616 xasprintf (&data, "'%s'=%ld%s;", label, val, uom); 618 xasprintf (&data, "'%s'=%" PRIu64 "%s;", label, val, uom);
617 else 619 else
618 xasprintf (&data, "%s=%ld%s;", label, val, uom); 620 xasprintf (&data, "%s=%" PRIu64 "%s;", label, val, uom);
619 621
620 if (warnp) 622 if (warnp)
621 xasprintf (&data, "%s%lu;", data, warn); 623 xasprintf (&data, "%s%" PRIu64 ";", data, warn);
622 else 624 else
623 xasprintf (&data, "%s;", data); 625 xasprintf (&data, "%s;", data);
624 626
625 if (critp) 627 if (critp)
626 xasprintf (&data, "%s%lu;", data, crit); 628 xasprintf (&data, "%s%" PRIu64 ";", data, crit);
627 else 629 else
628 xasprintf (&data, "%s;", data); 630 xasprintf (&data, "%s;", data);
629 631
630 if (minp) 632 if (minp)
631 xasprintf (&data, "%s%lu;", data, minv); 633 xasprintf (&data, "%s%" PRIu64 ";", data, minv);
632 else 634 else
633 xasprintf (&data, "%s;", data); 635 xasprintf (&data, "%s;", data);
634 636
635 if (maxp) 637 if (maxp)
636 xasprintf (&data, "%s%lu", data, maxv); 638 xasprintf (&data, "%s%" PRIu64, data, maxv);
637 639
638 return data; 640 return data;
639} 641}
@@ -654,27 +656,27 @@ char *perfdata_int64 (const char *label,
654 char *data = NULL; 656 char *data = NULL;
655 657
656 if (strpbrk (label, "'= ")) 658 if (strpbrk (label, "'= "))
657 xasprintf (&data, "'%s'=%ld%s;", label, val, uom); 659 xasprintf (&data, "'%s'=%" PRId64 "%s;", label, val, uom);
658 else 660 else
659 xasprintf (&data, "%s=%ld%s;", label, val, uom); 661 xasprintf (&data, "%s=%" PRId64 "%s;", label, val, uom);
660 662
661 if (warnp) 663 if (warnp)
662 xasprintf (&data, "%s%ld;", data, warn); 664 xasprintf (&data, "%s%" PRId64 ";", data, warn);
663 else 665 else
664 xasprintf (&data, "%s;", data); 666 xasprintf (&data, "%s;", data);
665 667
666 if (critp) 668 if (critp)
667 xasprintf (&data, "%s%ld;", data, crit); 669 xasprintf (&data, "%s%" PRId64 ";", data, crit);
668 else 670 else
669 xasprintf (&data, "%s;", data); 671 xasprintf (&data, "%s;", data);
670 672
671 if (minp) 673 if (minp)
672 xasprintf (&data, "%s%ld;", data, minv); 674 xasprintf (&data, "%s%" PRId64 ";", data, minv);
673 else 675 else
674 xasprintf (&data, "%s;", data); 676 xasprintf (&data, "%s;", data);
675 677
676 if (maxp) 678 if (maxp)
677 xasprintf (&data, "%s%ld", data, maxv); 679 xasprintf (&data, "%s%" PRId64, data, maxv);
678 680
679 return data; 681 return data;
680} 682}
diff --git a/plugins/utils.h b/plugins/utils.h
index 5b54da3..c76b321 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -7,7 +7,7 @@
7/* The purpose of this package is to provide safer alternatives to C 7/* The purpose of this package is to provide safer alternatives to C
8functions that might otherwise be vulnerable to hacking. This 8functions that might otherwise be vulnerable to hacking. This
9currently includes a standard suite of validation routines to be sure 9currently includes a standard suite of validation routines to be sure
10that an string argument acually converts to its intended type and a 10that an string argument actually converts to its intended type and a
11suite of string handling routine that do their own memory management 11suite of string handling routine that do their own memory management
12in order to resist overflow attacks. In addition, a few functions are 12in order to resist overflow attacks. In addition, a few functions are
13provided to standardize version and error reporting across the entire 13provided to standardize version and error reporting across the entire