summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorLorenz <12514511+RincewindsHat@users.noreply.github.com>2023-03-10 10:33:25 (GMT)
committerGitHub <noreply@github.com>2023-03-10 10:33:25 (GMT)
commit5077120a251980b4fafed61b4aa8fa5730a85443 (patch)
tree8500b8f5dbe774b399cfdc79f5665ba88ef7f255 /plugins
parenta3de84594104ac87a91e200d569fb57edacca928 (diff)
parent269718094177fb8a7e3d3005d1310495009fe8c4 (diff)
downloadmonitoring-plugins-5077120a251980b4fafed61b4aa8fa5730a85443.tar.gz
Merge branch 'master' into master
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am4
-rw-r--r--plugins/check_apt.c72
-rw-r--r--plugins/check_by_ssh.c34
-rw-r--r--plugins/check_curl.c441
-rw-r--r--plugins/check_disk.c270
-rw-r--r--plugins/check_dns.c81
-rw-r--r--plugins/check_fping.c37
-rw-r--r--plugins/check_game.c2
-rw-r--r--plugins/check_hpjd.c17
-rw-r--r--plugins/check_http.c401
-rw-r--r--plugins/check_ldap.c5
-rw-r--r--plugins/check_load.c124
-rw-r--r--plugins/check_mysql_query.c12
-rw-r--r--plugins/check_ntp.c8
-rw-r--r--plugins/check_pgsql.c65
-rw-r--r--plugins/check_ping.c69
-rw-r--r--plugins/check_procs.c54
-rw-r--r--plugins/check_smtp.c18
-rw-r--r--plugins/check_snmp.c153
-rw-r--r--plugins/check_swap.c301
-rw-r--r--plugins/check_ups.c5
-rw-r--r--plugins/picohttpparser/picohttpparser.c30
-rw-r--r--plugins/picohttpparser/picohttpparser.h4
-rw-r--r--plugins/sslutils.c34
-rw-r--r--plugins/t/NPTest.cache.travis54
-rw-r--r--plugins/t/check_curl.t58
-rw-r--r--plugins/t/check_disk.t7
-rw-r--r--plugins/t/check_dns.t10
-rw-r--r--plugins/t/check_fping.t32
-rw-r--r--plugins/t/check_http.t12
-rw-r--r--plugins/t/check_load.t15
-rw-r--r--plugins/t/check_swap.t6
-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.t50
-rwxr-xr-xplugins/tests/check_http.t354
-rwxr-xr-xplugins/tests/check_procs.t26
-rwxr-xr-xplugins/tests/check_snmp.t37
-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.c130
-rw-r--r--plugins/utils.h9
56 files changed, 2587 insertions, 1239 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 3fde54d..ab59eb7 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
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 13d8bc3..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,8 +243,10 @@ 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 host_or_die(optarg);
234 hostname = optarg; 250 hostname = optarg;
235 break; 251 break;
236 case 'p': /* port number */ 252 case 'p': /* port number */
@@ -308,6 +324,9 @@ process_arguments (int argc, char **argv)
308 else 324 else
309 skip_stderr = atoi (optarg); 325 skip_stderr = atoi (optarg);
310 break; 326 break;
327 case 'W': /* exit with warning if there is an output on stderr */
328 warn_on_stderr = 1;
329 break;
311 case 'o': /* Extra options for the ssh command */ 330 case 'o': /* Extra options for the ssh command */
312 comm_append("-o"); 331 comm_append("-o");
313 comm_append(optarg); 332 comm_append(optarg);
@@ -329,7 +348,6 @@ process_arguments (int argc, char **argv)
329 if (c <= argc) { 348 if (c <= argc) {
330 die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname); 349 die (STATE_UNKNOWN, _("%s: You must provide a host name\n"), progname);
331 } 350 }
332 host_or_die(argv[c]);
333 hostname = argv[c++]; 351 hostname = argv[c++];
334 } 352 }
335 353
@@ -415,6 +433,8 @@ print_help (void)
415 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]"));
416 printf (" %s\n", "-E, --skip-stderr[=n]"); 434 printf (" %s\n", "-E, --skip-stderr[=n]");
417 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"));
418 printf (" %s\n", "-f"); 438 printf (" %s\n", "-f");
419 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"));
420 printf (" %s\n","-C, --command='COMMAND STRING'"); 440 printf (" %s\n","-C, --command='COMMAND STRING'");
@@ -437,6 +457,8 @@ print_help (void)
437 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]"));
438 printf (UT_WARN_CRIT); 458 printf (UT_WARN_CRIT);
439 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"));
440 printf (UT_VERBOSE); 462 printf (UT_VERBOSE);
441 printf("\n"); 463 printf("\n");
442 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"));
@@ -466,8 +488,8 @@ void
466print_usage (void) 488print_usage (void)
467{ 489{
468 printf ("%s\n", _("Usage:")); 490 printf ("%s\n", _("Usage:"));
469 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"
470 " [-S [lines]] [-E [lines]] [-t timeout] [-i identity]\n" 492 " [-S [lines]] [-E [lines]] [-W] [-t timeout] [-i identity]\n"
471 " [-l user] [-n name] [-s servicelist] [-O outputfile]\n" 493 " [-l user] [-n name] [-s servicelist] [-O outputfile]\n"
472 " [-p port] [-o ssh-option] [-F configfile]\n", 494 " [-p port] [-o ssh-option] [-F configfile]\n",
473 progname); 495 progname);
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 2d69b31..c37d45d 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"
@@ -55,18 +56,24 @@ const char *email = "devel@monitoring-plugins.org";
55 56
56#include <arpa/inet.h> 57#include <arpa/inet.h>
57 58
59#if defined(HAVE_SSL) && defined(USE_OPENSSL)
60#include <openssl/opensslv.h>
61#endif
62
63#include <netdb.h>
64
58#define MAKE_LIBCURL_VERSION(major, minor, patch) ((major)*0x10000 + (minor)*0x100 + (patch)) 65#define MAKE_LIBCURL_VERSION(major, minor, patch) ((major)*0x10000 + (minor)*0x100 + (patch))
59 66
60#define DEFAULT_BUFFER_SIZE 2048 67#define DEFAULT_BUFFER_SIZE 2048
61#define DEFAULT_SERVER_URL "/" 68#define DEFAULT_SERVER_URL "/"
62#define HTTP_EXPECT "HTTP/" 69#define HTTP_EXPECT "HTTP/"
63#define DEFAULT_MAX_REDIRS 15
64#define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN 70#define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN
65enum { 71enum {
66 MAX_IPV4_HOSTLENGTH = 255, 72 MAX_IPV4_HOSTLENGTH = 255,
67 HTTP_PORT = 80, 73 HTTP_PORT = 80,
68 HTTPS_PORT = 443, 74 HTTPS_PORT = 443,
69 MAX_PORT = 65535 75 MAX_PORT = 65535,
76 DEFAULT_MAX_REDIRS = 15
70}; 77};
71 78
72enum { 79enum {
@@ -117,7 +124,7 @@ typedef enum curlhelp_ssl_library {
117 124
118enum { 125enum {
119 REGS = 2, 126 REGS = 2,
120 MAX_RE_SIZE = 256 127 MAX_RE_SIZE = 1024
121}; 128};
122#include "regex.h" 129#include "regex.h"
123regex_t preg; 130regex_t preg;
@@ -125,14 +132,14 @@ regmatch_t pmatch[REGS];
125char regexp[MAX_RE_SIZE]; 132char regexp[MAX_RE_SIZE];
126int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; 133int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE;
127int errcode; 134int errcode;
128int invert_regex = 0; 135bool invert_regex = false;
129 136
130char *server_address = NULL; 137char *server_address = NULL;
131char *host_name = NULL; 138char *host_name = NULL;
132char *server_url = 0; 139char *server_url = 0;
133char server_ip[DEFAULT_BUFFER_SIZE]; 140char server_ip[DEFAULT_BUFFER_SIZE];
134struct curl_slist *server_ips = NULL; 141struct curl_slist *server_ips = NULL;
135int specify_port = FALSE; 142bool specify_port = false;
136unsigned short server_port = HTTP_PORT; 143unsigned short server_port = HTTP_PORT;
137unsigned short virtual_port = 0; 144unsigned short virtual_port = 0;
138int host_name_length; 145int host_name_length;
@@ -144,7 +151,8 @@ int days_till_exp_warn, days_till_exp_crit;
144thresholds *thlds; 151thresholds *thlds;
145char user_agent[DEFAULT_BUFFER_SIZE]; 152char user_agent[DEFAULT_BUFFER_SIZE];
146int verbose = 0; 153int verbose = 0;
147int show_extended_perfdata = FALSE; 154bool show_extended_perfdata = false;
155bool show_body = false;
148int min_page_len = 0; 156int min_page_len = 0;
149int max_page_len = 0; 157int max_page_len = 0;
150int redir_depth = 0; 158int redir_depth = 0;
@@ -153,10 +161,16 @@ char *http_method = NULL;
153char *http_post_data = NULL; 161char *http_post_data = NULL;
154char *http_content_type = NULL; 162char *http_content_type = NULL;
155CURL *curl; 163CURL *curl;
164bool curl_global_initialized = false;
165bool curl_easy_initialized = false;
156struct curl_slist *header_list = NULL; 166struct curl_slist *header_list = NULL;
167bool body_buf_initialized = false;
157curlhelp_write_curlbuf body_buf; 168curlhelp_write_curlbuf body_buf;
169bool header_buf_initialized = false;
158curlhelp_write_curlbuf header_buf; 170curlhelp_write_curlbuf header_buf;
171bool status_line_initialized = false;
159curlhelp_statusline status_line; 172curlhelp_statusline status_line;
173bool put_buf_initialized = false;
160curlhelp_read_curlbuf put_buf; 174curlhelp_read_curlbuf put_buf;
161char http_header[DEFAULT_BUFFER_SIZE]; 175char http_header[DEFAULT_BUFFER_SIZE];
162long code; 176long code;
@@ -166,7 +180,7 @@ double time_connect;
166double time_appconnect; 180double time_appconnect;
167double time_headers; 181double time_headers;
168double time_firstbyte; 182double time_firstbyte;
169char errbuf[CURL_ERROR_SIZE+1]; 183char errbuf[MAX_INPUT_BUFFER];
170CURLcode res; 184CURLcode res;
171char url[DEFAULT_BUFFER_SIZE]; 185char url[DEFAULT_BUFFER_SIZE];
172char msg[DEFAULT_BUFFER_SIZE]; 186char msg[DEFAULT_BUFFER_SIZE];
@@ -179,13 +193,14 @@ char user_auth[MAX_INPUT_BUFFER] = "";
179char proxy_auth[MAX_INPUT_BUFFER] = ""; 193char proxy_auth[MAX_INPUT_BUFFER] = "";
180char **http_opt_headers; 194char **http_opt_headers;
181int http_opt_headers_count = 0; 195int http_opt_headers_count = 0;
182int display_html = FALSE; 196bool display_html = false;
183int onredirect = STATE_OK; 197int onredirect = STATE_OK;
184int followmethod = FOLLOW_HTTP_CURL; 198int followmethod = FOLLOW_HTTP_CURL;
185int followsticky = STICKY_NONE; 199int followsticky = STICKY_NONE;
186int use_ssl = FALSE; 200bool use_ssl = false;
187int use_sni = TRUE; 201bool use_sni = true;
188int check_cert = FALSE; 202bool check_cert = false;
203bool continue_after_check_cert = false;
189typedef union { 204typedef union {
190 struct curl_slist* to_info; 205 struct curl_slist* to_info;
191 struct curl_certinfo* to_certinfo; 206 struct curl_certinfo* to_certinfo;
@@ -195,17 +210,20 @@ int ssl_version = CURL_SSLVERSION_DEFAULT;
195char *client_cert = NULL; 210char *client_cert = NULL;
196char *client_privkey = NULL; 211char *client_privkey = NULL;
197char *ca_cert = NULL; 212char *ca_cert = NULL;
198int is_openssl_callback = FALSE; 213bool verify_peer_and_host = false;
214bool is_openssl_callback = false;
199#if defined(HAVE_SSL) && defined(USE_OPENSSL) 215#if defined(HAVE_SSL) && defined(USE_OPENSSL)
200X509 *cert = NULL; 216X509 *cert = NULL;
201#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ 217#endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */
202int no_body = FALSE; 218bool no_body = false;
203int maximum_age = -1; 219int maximum_age = -1;
204int address_family = AF_UNSPEC; 220int address_family = AF_UNSPEC;
205curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; 221curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN;
206int curl_http_version = CURL_HTTP_VERSION_NONE; 222int curl_http_version = CURL_HTTP_VERSION_NONE;
223bool automatic_decompression = false;
224char *cookie_jar_file = NULL;
207 225
208int process_arguments (int, char**); 226bool process_arguments (int, char**);
209void handle_curl_option_return_code (CURLcode res, const char* option); 227void handle_curl_option_return_code (CURLcode res, const char* option);
210int check_http (void); 228int check_http (void);
211void redir (curlhelp_write_curlbuf*); 229void redir (curlhelp_write_curlbuf*);
@@ -259,10 +277,10 @@ main (int argc, char **argv)
259 progname, NP_VERSION, VERSION, curl_version()); 277 progname, NP_VERSION, VERSION, curl_version());
260 278
261 /* parse arguments */ 279 /* parse arguments */
262 if (process_arguments (argc, argv) == ERROR) 280 if (process_arguments (argc, argv) == false)
263 usage4 (_("Could not parse arguments")); 281 usage4 (_("Could not parse arguments"));
264 282
265 if (display_html == TRUE) 283 if (display_html)
266 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", 284 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">",
267 use_ssl ? "https" : "http", 285 use_ssl ? "https" : "http",
268 host_name ? host_name : server_address, 286 host_name ? host_name : server_address,
@@ -283,6 +301,20 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
283 * TODO: is the last certificate always the server certificate? 301 * TODO: is the last certificate always the server certificate?
284 */ 302 */
285 cert = X509_STORE_CTX_get_current_cert(x509_ctx); 303 cert = X509_STORE_CTX_get_current_cert(x509_ctx);
304#if OPENSSL_VERSION_NUMBER >= 0x10100000L
305 X509_up_ref(cert);
306#endif
307 if (verbose>=2) {
308 puts("* SSL verify callback with certificate:");
309 X509_NAME *subject, *issuer;
310 printf("* issuer:\n");
311 issuer = X509_get_issuer_name( cert );
312 X509_NAME_print_ex_fp(stdout, issuer, 5, XN_FLAG_MULTILINE);
313 printf("* curl verify_callback:\n* subject:\n");
314 subject = X509_get_subject_name( cert );
315 X509_NAME_print_ex_fp(stdout, subject, 5, XN_FLAG_MULTILINE);
316 puts("");
317 }
286 return 1; 318 return 1;
287} 319}
288 320
@@ -296,6 +328,28 @@ CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm)
296#endif /* USE_OPENSSL */ 328#endif /* USE_OPENSSL */
297#endif /* HAVE_SSL */ 329#endif /* HAVE_SSL */
298 330
331/* returns a string "HTTP/1.x" or "HTTP/2" */
332static char *string_statuscode (int major, int minor)
333{
334 static char buf[10];
335
336 switch (major) {
337 case 1:
338 snprintf (buf, sizeof (buf), "HTTP/%d.%d", major, minor);
339 break;
340 case 2:
341 case 3:
342 snprintf (buf, sizeof (buf), "HTTP/%d", major);
343 break;
344 default:
345 /* assuming here HTTP/N with N>=4 */
346 snprintf (buf, sizeof (buf), "HTTP/%d", major);
347 break;
348 }
349
350 return buf;
351}
352
299/* Checks if the server 'reply' is one of the expected 'statuscodes' */ 353/* Checks if the server 'reply' is one of the expected 'statuscodes' */
300static int 354static int
301expected_statuscode (const char *reply, const char *statuscodes) 355expected_statuscode (const char *reply, const char *statuscodes)
@@ -327,35 +381,110 @@ handle_curl_option_return_code (CURLcode res, const char* option)
327} 381}
328 382
329int 383int
384lookup_host (const char *host, char *buf, size_t buflen)
385{
386 struct addrinfo hints, *res, *result;
387 int errcode;
388 void *ptr;
389
390 memset (&hints, 0, sizeof (hints));
391 hints.ai_family = address_family;
392 hints.ai_socktype = SOCK_STREAM;
393 hints.ai_flags |= AI_CANONNAME;
394
395 errcode = getaddrinfo (host, NULL, &hints, &result);
396 if (errcode != 0)
397 return errcode;
398
399 res = result;
400
401 while (res) {
402 inet_ntop (res->ai_family, res->ai_addr->sa_data, buf, buflen);
403 switch (res->ai_family) {
404 case AF_INET:
405 ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
406 break;
407 case AF_INET6:
408 ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
409 break;
410 }
411 inet_ntop (res->ai_family, ptr, buf, buflen);
412 if (verbose >= 1)
413 printf ("* getaddrinfo IPv%d address: %s\n",
414 res->ai_family == PF_INET6 ? 6 : 4, buf);
415 res = res->ai_next;
416 }
417
418 freeaddrinfo(result);
419
420 return 0;
421}
422
423static void
424cleanup (void)
425{
426 if (status_line_initialized) curlhelp_free_statusline(&status_line);
427 status_line_initialized = false;
428 if (curl_easy_initialized) curl_easy_cleanup (curl);
429 curl_easy_initialized = false;
430 if (curl_global_initialized) curl_global_cleanup ();
431 curl_global_initialized = false;
432 if (body_buf_initialized) curlhelp_freewritebuffer (&body_buf);
433 body_buf_initialized = false;
434 if (header_buf_initialized) curlhelp_freewritebuffer (&header_buf);
435 header_buf_initialized = false;
436 if (put_buf_initialized) curlhelp_freereadbuffer (&put_buf);
437 put_buf_initialized = false;
438}
439
440int
330check_http (void) 441check_http (void)
331{ 442{
332 int result = STATE_OK; 443 int result = STATE_OK;
333 int page_len = 0; 444 int page_len = 0;
334 int i; 445 int i;
335 char *force_host_header = NULL; 446 char *force_host_header = NULL;
447 struct curl_slist *host = NULL;
448 char addrstr[100];
449 char dnscache[DEFAULT_BUFFER_SIZE];
336 450
337 /* initialize curl */ 451 /* initialize curl */
338 if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK) 452 if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK)
339 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); 453 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n");
454 curl_global_initialized = true;
340 455
341 if ((curl = curl_easy_init()) == NULL) 456 if ((curl = curl_easy_init()) == NULL) {
342 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n"); 457 die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n");
458 }
459 curl_easy_initialized = true;
343 460
461 /* register cleanup function to shut down libcurl properly */
462 atexit (cleanup);
463
344 if (verbose >= 1) 464 if (verbose >= 1)
345 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, TRUE), "CURLOPT_VERBOSE"); 465 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, 1), "CURLOPT_VERBOSE");
346 466
347 /* print everything on stdout like check_http would do */ 467 /* print everything on stdout like check_http would do */
348 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR"); 468 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR");
349 469
470 if (automatic_decompression)
471#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6)
472 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""), "CURLOPT_ACCEPT_ENCODING");
473#else
474 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_ENCODING, ""), "CURLOPT_ENCODING");
475#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) */
476
350 /* initialize buffer for body of the answer */ 477 /* initialize buffer for body of the answer */
351 if (curlhelp_initwritebuffer(&body_buf) < 0) 478 if (curlhelp_initwritebuffer(&body_buf) < 0)
352 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); 479 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n");
480 body_buf_initialized = true;
353 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_WRITEFUNCTION"); 481 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_WRITEFUNCTION");
354 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA"); 482 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA");
355 483
356 /* initialize buffer for header of the answer */ 484 /* initialize buffer for header of the answer */
357 if (curlhelp_initwritebuffer( &header_buf ) < 0) 485 if (curlhelp_initwritebuffer( &header_buf ) < 0)
358 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" ); 486 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" );
487 header_buf_initialized = true;
359 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_HEADERFUNCTION"); 488 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), "CURLOPT_HEADERFUNCTION");
360 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER"); 489 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER");
361 490
@@ -368,15 +497,30 @@ check_http (void)
368 497
369 // 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 498 // 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
370 if(use_ssl && host_name != NULL) { 499 if(use_ssl && host_name != NULL) {
371 struct curl_slist *host = NULL; 500 if ( (res=lookup_host (server_address, addrstr, 100)) != 0) {
372 char dnscache[DEFAULT_BUFFER_SIZE]; 501 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"),
373 snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, server_address); 502 server_address, res, gai_strerror (res));
503 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
504 }
505 snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, addrstr);
374 host = curl_slist_append(NULL, dnscache); 506 host = curl_slist_append(NULL, dnscache);
375 curl_easy_setopt(curl, CURLOPT_RESOLVE, host); 507 curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
376 if (verbose>=1) 508 if (verbose>=1)
377 printf ("* curl CURLOPT_RESOLVE: %s\n", dnscache); 509 printf ("* curl CURLOPT_RESOLVE: %s\n", dnscache);
378 } 510 }
379 511
512 // If server_address is an IPv6 address it must be surround by square brackets
513 struct in6_addr tmp_in_addr;
514 if (inet_pton(AF_INET6, server_address, &tmp_in_addr) == 1) {
515 char *new_server_address = malloc(strlen(server_address) + 3);
516 if (new_server_address == NULL) {
517 die(STATE_UNKNOWN, "HTTP UNKNOWN - Unable to allocate memory\n");
518 }
519 snprintf(new_server_address, strlen(server_address)+3, "[%s]", server_address);
520 free(server_address);
521 server_address = new_server_address;
522 }
523
380 /* compose URL: use the address we want to connect to, set Host: header later */ 524 /* compose URL: use the address we want to connect to, set Host: header later */
381 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", 525 snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s",
382 use_ssl ? "https" : "http", 526 use_ssl ? "https" : "http",
@@ -401,7 +545,7 @@ check_http (void)
401 545
402 /* disable body for HEAD request */ 546 /* disable body for HEAD request */
403 if (http_method && !strcmp (http_method, "HEAD" )) { 547 if (http_method && !strcmp (http_method, "HEAD" )) {
404 no_body = TRUE; 548 no_body = true;
405 } 549 }
406 550
407 /* set HTTP protocol version */ 551 /* set HTTP protocol version */
@@ -467,9 +611,11 @@ check_http (void)
467 if (client_privkey) 611 if (client_privkey)
468 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSLKEY, client_privkey), "CURLOPT_SSLKEY"); 612 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSLKEY, client_privkey), "CURLOPT_SSLKEY");
469 if (ca_cert) { 613 if (ca_cert) {
614 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CAINFO, ca_cert), "CURLOPT_CAINFO");
615 }
616 if (ca_cert || verify_peer_and_host) {
470 /* per default if we have a CA verify both the peer and the 617 /* per default if we have a CA verify both the peer and the
471 * hostname in the certificate, can be switched off later */ 618 * hostname in the certificate, can be switched off later */
472 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CAINFO, ca_cert), "CURLOPT_CAINFO");
473 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1), "CURLOPT_SSL_VERIFYPEER"); 619 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1), "CURLOPT_SSL_VERIFYPEER");
474 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2), "CURLOPT_SSL_VERIFYHOST"); 620 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2), "CURLOPT_SSL_VERIFYHOST");
475 } else { 621 } else {
@@ -496,7 +642,7 @@ check_http (void)
496#ifdef USE_OPENSSL 642#ifdef USE_OPENSSL
497 /* libcurl and monitoring plugins built with OpenSSL, good */ 643 /* libcurl and monitoring plugins built with OpenSSL, good */
498 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); 644 handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION");
499 is_openssl_callback = TRUE; 645 is_openssl_callback = true;
500#else /* USE_OPENSSL */ 646#else /* USE_OPENSSL */
501#endif /* USE_OPENSSL */ 647#endif /* USE_OPENSSL */
502 /* libcurl is built with OpenSSL, monitoring plugins, so falling 648 /* libcurl is built with OpenSSL, monitoring plugins, so falling
@@ -575,9 +721,11 @@ check_http (void)
575 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS"); 721 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS");
576 722
577 /* for now allow only http and https (we are a http(s) check plugin in the end) */ 723 /* for now allow only http and https (we are a http(s) check plugin in the end) */
578#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) 724#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 85, 0)
725 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"), "CURLOPT_REDIR_PROTOCOLS_STR");
726#elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4)
579 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS"); 727 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS");
580#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) */ 728#endif
581 729
582 /* TODO: handle the following aspects of redirection, make them 730 /* TODO: handle the following aspects of redirection, make them
583 * command line options too later: 731 * command line options too later:
@@ -621,11 +769,19 @@ check_http (void)
621 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_POSTFIELDS, http_post_data), "CURLOPT_POSTFIELDS"); 769 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_POSTFIELDS, http_post_data), "CURLOPT_POSTFIELDS");
622 } else if (!strcmp(http_method, "PUT")) { 770 } else if (!strcmp(http_method, "PUT")) {
623 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), "CURLOPT_READFUNCTION"); 771 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), "CURLOPT_READFUNCTION");
624 curlhelp_initreadbuffer (&put_buf, http_post_data, strlen (http_post_data)); 772 if (curlhelp_initreadbuffer (&put_buf, http_post_data, strlen (http_post_data)) < 0)
773 die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating read buffer for PUT\n");
774 put_buf_initialized = true;
625 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA"); 775 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA");
626 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE"); 776 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE");
627 } 777 }
628 } 778 }
779
780 /* cookie handling */
781 if (cookie_jar_file != NULL) {
782 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEJAR, cookie_jar_file), "CURLOPT_COOKIEJAR");
783 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEFILE, cookie_jar_file), "CURLOPT_COOKIEFILE");
784 }
629 785
630 /* do the request */ 786 /* do the request */
631 res = curl_easy_perform(curl); 787 res = curl_easy_perform(curl);
@@ -640,21 +796,23 @@ check_http (void)
640 /* Curl errors, result in critical Nagios state */ 796 /* Curl errors, result in critical Nagios state */
641 if (res != CURLE_OK) { 797 if (res != CURLE_OK) {
642 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"), 798 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"),
643 server_port, res, curl_easy_strerror(res)); 799 server_port, res, errbuf[0] ? errbuf : curl_easy_strerror(res));
644 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 800 die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
645 } 801 }
646 802
647 /* certificate checks */ 803 /* certificate checks */
648#ifdef LIBCURL_FEATURE_SSL 804#ifdef LIBCURL_FEATURE_SSL
649 if (use_ssl == TRUE) { 805 if (use_ssl) {
650 if (check_cert == TRUE) { 806 if (check_cert) {
651 if (is_openssl_callback) { 807 if (is_openssl_callback) {
652#ifdef USE_OPENSSL 808#ifdef USE_OPENSSL
653 /* check certificate with OpenSSL functions, curl has been built against OpenSSL 809 /* check certificate with OpenSSL functions, curl has been built against OpenSSL
654 * and we actually have OpenSSL in the monitoring tools 810 * and we actually have OpenSSL in the monitoring tools
655 */ 811 */
656 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 812 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
657 return result; 813 if (!continue_after_check_cert) {
814 return result;
815 }
658#else /* USE_OPENSSL */ 816#else /* USE_OPENSSL */
659 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); 817 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n");
660#endif /* USE_OPENSSL */ 818#endif /* USE_OPENSSL */
@@ -694,13 +852,17 @@ GOT_FIRST_CERT:
694 } 852 }
695 BIO_free (cert_BIO); 853 BIO_free (cert_BIO);
696 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 854 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
697 return result; 855 if (!continue_after_check_cert) {
856 return result;
857 }
698#else /* USE_OPENSSL */ 858#else /* USE_OPENSSL */
699 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, 859 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal,
700 * so we use the libcurl CURLINFO data 860 * so we use the libcurl CURLINFO data
701 */ 861 */
702 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); 862 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit);
703 return result; 863 if (!continue_after_check_cert) {
864 return result;
865 }
704#endif /* USE_OPENSSL */ 866#endif /* USE_OPENSSL */
705 } else { 867 } else {
706 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"), 868 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"),
@@ -726,7 +888,7 @@ GOT_FIRST_CERT:
726 perfd_time(total_time), 888 perfd_time(total_time),
727 perfd_size(page_len), 889 perfd_size(page_len),
728 perfd_time_connect(time_connect), 890 perfd_time_connect(time_connect),
729 use_ssl == TRUE ? perfd_time_ssl (time_appconnect-time_connect) : "", 891 use_ssl ? perfd_time_ssl (time_appconnect-time_connect) : "",
730 perfd_time_headers(time_headers - time_appconnect), 892 perfd_time_headers(time_headers - time_appconnect),
731 perfd_time_firstbyte(time_firstbyte - time_headers), 893 perfd_time_firstbyte(time_firstbyte - time_headers),
732 perfd_time_transfer(total_time-time_firstbyte) 894 perfd_time_transfer(total_time-time_firstbyte)
@@ -746,8 +908,10 @@ GOT_FIRST_CERT:
746 if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) { 908 if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) {
747 snprintf (msg, DEFAULT_BUFFER_SIZE, "Unparsable status line in %.3g seconds response time|%s\n", 909 snprintf (msg, DEFAULT_BUFFER_SIZE, "Unparsable status line in %.3g seconds response time|%s\n",
748 total_time, perfstring); 910 total_time, perfstring);
749 die (STATE_CRITICAL, "HTTP CRITICAL HTTP/1.x %ld unknown - %s", code, msg); 911 /* we cannot know the major/minor version here for sure as we cannot parse the first line */
912 die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg);
750 } 913 }
914 status_line_initialized = true;
751 915
752 /* get result code from cURL */ 916 /* get result code from cURL */
753 handle_curl_option_return_code (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE"); 917 handle_curl_option_return_code (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE");
@@ -766,7 +930,9 @@ GOT_FIRST_CERT:
766 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line); 930 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line);
767 else 931 else
768 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, status_line.first_line); 932 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, status_line.first_line);
769 die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg); 933 die (STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg,
934 show_body ? "\n" : "",
935 show_body ? body_buf.buf : "");
770 } 936 }
771 937
772 if( server_expect_yn ) { 938 if( server_expect_yn ) {
@@ -823,8 +989,8 @@ GOT_FIRST_CERT:
823 989
824 /* check status codes, set exit status accordingly */ 990 /* check status codes, set exit status accordingly */
825 if( status_line.http_code != code ) { 991 if( status_line.http_code != code ) {
826 die (STATE_CRITICAL, _("HTTP CRITICAL HTTP/%d.%d %d %s - different HTTP codes (cUrl has %ld)\n"), 992 die (STATE_CRITICAL, _("HTTP CRITICAL %s %d %s - different HTTP codes (cUrl has %ld)\n"),
827 status_line.http_major, status_line.http_minor, 993 string_statuscode (status_line.http_major, status_line.http_minor),
828 status_line.http_code, status_line.msg, code); 994 status_line.http_code, status_line.msg, code);
829 } 995 }
830 996
@@ -858,12 +1024,12 @@ GOT_FIRST_CERT:
858 1024
859 if (strlen (regexp)) { 1025 if (strlen (regexp)) {
860 errcode = regexec (&preg, body_buf.buf, REGS, pmatch, 0); 1026 errcode = regexec (&preg, body_buf.buf, REGS, pmatch, 0);
861 if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { 1027 if ((errcode == 0 && !invert_regex) || (errcode == REG_NOMATCH && invert_regex)) {
862 /* OK - No-op to avoid changing the logic around it */ 1028 /* OK - No-op to avoid changing the logic around it */
863 result = max_state_alt(STATE_OK, result); 1029 result = max_state_alt(STATE_OK, result);
864 } 1030 }
865 else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { 1031 else if ((errcode == REG_NOMATCH && !invert_regex) || (errcode == 0 && invert_regex)) {
866 if (invert_regex == 0) 1032 if (!invert_regex)
867 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg); 1033 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg);
868 else 1034 else
869 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg); 1035 snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg);
@@ -889,29 +1055,23 @@ GOT_FIRST_CERT:
889 result = max_state_alt(get_status(total_time, thlds), result); 1055 result = max_state_alt(get_status(total_time, thlds), result);
890 1056
891 /* Cut-off trailing characters */ 1057 /* Cut-off trailing characters */
892 if(msg[strlen(msg)-2] == ',') 1058 if (strlen(msg) >= 2) {
893 msg[strlen(msg)-2] = '\0'; 1059 if(msg[strlen(msg)-2] == ',')
894 else 1060 msg[strlen(msg)-2] = '\0';
895 msg[strlen(msg)-3] = '\0'; 1061 else
896 1062 msg[strlen(msg)-3] = '\0';
1063 }
1064
897 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ 1065 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */
898 die (result, "HTTP %s: HTTP/%d.%d %d %s%s%s - %d bytes in %.3f second response time %s|%s\n", 1066 die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s",
899 state_text(result), status_line.http_major, status_line.http_minor, 1067 state_text(result), string_statuscode (status_line.http_major, status_line.http_minor),
900 status_line.http_code, status_line.msg, 1068 status_line.http_code, status_line.msg,
901 strlen(msg) > 0 ? " - " : "", 1069 strlen(msg) > 0 ? " - " : "",
902 msg, page_len, total_time, 1070 msg, page_len, total_time,
903 (display_html ? "</A>" : ""), 1071 (display_html ? "</A>" : ""),
904 perfstring); 1072 perfstring,
905 1073 (show_body ? body_buf.buf : ""),
906 /* proper cleanup after die? */ 1074 (show_body ? "\n" : "") );
907 curlhelp_free_statusline(&status_line);
908 curl_easy_cleanup (curl);
909 curl_global_cleanup ();
910 curlhelp_freewritebuffer (&body_buf);
911 curlhelp_freewritebuffer (&header_buf);
912 if (!strcmp (http_method, "PUT")) {
913 curlhelp_freereadbuffer (&put_buf);
914 }
915 1075
916 return result; 1076 return result;
917} 1077}
@@ -928,8 +1088,8 @@ char*
928uri_string (const UriTextRangeA range, char* buf, size_t buflen) 1088uri_string (const UriTextRangeA range, char* buf, size_t buflen)
929{ 1089{
930 if (!range.first) return "(null)"; 1090 if (!range.first) return "(null)";
931 strncpy (buf, range.first, max (buflen, range.afterLast - range.first)); 1091 strncpy (buf, range.first, max (buflen-1, range.afterLast - range.first));
932 buf[max (buflen, range.afterLast - range.first)] = '\0'; 1092 buf[max (buflen-1, range.afterLast - range.first)] = '\0';
933 buf[range.afterLast - range.first] = '\0'; 1093 buf[range.afterLast - range.first] = '\0';
934 return buf; 1094 return buf;
935} 1095}
@@ -949,7 +1109,7 @@ redir (curlhelp_write_curlbuf* header_buf)
949 char *new_url; 1109 char *new_url;
950 1110
951 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 1111 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
952 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 1112 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
953 headers, &nof_headers, 0); 1113 headers, &nof_headers, 0);
954 1114
955 location = get_header_value (headers, nof_headers, "location"); 1115 location = get_header_value (headers, nof_headers, "location");
@@ -1008,7 +1168,10 @@ redir (curlhelp_write_curlbuf* header_buf)
1008 } 1168 }
1009 } 1169 }
1010 1170
1011 use_ssl = !uri_strcmp (uri.scheme, "https"); 1171 if (!uri_strcmp (uri.scheme, "https"))
1172 use_ssl = true;
1173 else
1174 use_ssl = false;
1012 1175
1013 /* we do a sloppy test here only, because uriparser would have failed 1176 /* we do a sloppy test here only, because uriparser would have failed
1014 * above, if the port would be invalid, we just check for MAX_PORT 1177 * above, if the port would be invalid, we just check for MAX_PORT
@@ -1041,7 +1204,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1041 const UriPathSegmentA* p = uri.pathHead; 1204 const UriPathSegmentA* p = uri.pathHead;
1042 for (; p; p = p->next) { 1205 for (; p; p = p->next) {
1043 strncat (new_url, "/", DEFAULT_BUFFER_SIZE); 1206 strncat (new_url, "/", DEFAULT_BUFFER_SIZE);
1044 strncat (new_url, uri_string (p->text, buf, DEFAULT_BUFFER_SIZE), DEFAULT_BUFFER_SIZE); 1207 strncat (new_url, uri_string (p->text, buf, DEFAULT_BUFFER_SIZE), DEFAULT_BUFFER_SIZE-1);
1045 } 1208 }
1046 } 1209 }
1047 1210
@@ -1049,8 +1212,8 @@ redir (curlhelp_write_curlbuf* header_buf)
1049 !strncmp(server_address, new_host, MAX_IPV4_HOSTLENGTH) && 1212 !strncmp(server_address, new_host, MAX_IPV4_HOSTLENGTH) &&
1050 (host_name && !strncmp(host_name, new_host, MAX_IPV4_HOSTLENGTH)) && 1213 (host_name && !strncmp(host_name, new_host, MAX_IPV4_HOSTLENGTH)) &&
1051 !strcmp(server_url, new_url)) 1214 !strcmp(server_url, new_url))
1052 die (STATE_WARNING, 1215 die (STATE_CRITICAL,
1053 _("HTTP WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"), 1216 _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"),
1054 use_ssl ? "https" : "http", new_host, new_port, new_url, (display_html ? "</A>" : "")); 1217 use_ssl ? "https" : "http", new_host, new_port, new_url, (display_html ? "</A>" : ""));
1055 1218
1056 /* set new values for redirected request */ 1219 /* set new values for redirected request */
@@ -1083,6 +1246,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1083 * attached to the URL in Location 1246 * attached to the URL in Location
1084 */ 1247 */
1085 1248
1249 cleanup ();
1086 check_http (); 1250 check_http ();
1087} 1251}
1088 1252
@@ -1095,7 +1259,7 @@ test_file (char *path)
1095 usage2 (_("file does not exist or is not readable"), path); 1259 usage2 (_("file does not exist or is not readable"), path);
1096} 1260}
1097 1261
1098int 1262bool
1099process_arguments (int argc, char **argv) 1263process_arguments (int argc, char **argv)
1100{ 1264{
1101 char *p; 1265 char *p;
@@ -1105,8 +1269,12 @@ process_arguments (int argc, char **argv)
1105 enum { 1269 enum {
1106 INVERT_REGEX = CHAR_MAX + 1, 1270 INVERT_REGEX = CHAR_MAX + 1,
1107 SNI_OPTION, 1271 SNI_OPTION,
1272 MAX_REDIRS_OPTION,
1273 CONTINUE_AFTER_CHECK_CERT,
1108 CA_CERT_OPTION, 1274 CA_CERT_OPTION,
1109 HTTP_VERSION_OPTION 1275 HTTP_VERSION_OPTION,
1276 AUTOMATIC_DECOMPRESSION,
1277 COOKIE_JAR
1110 }; 1278 };
1111 1279
1112 int option = 0; 1280 int option = 0;
@@ -1136,6 +1304,8 @@ process_arguments (int argc, char **argv)
1136 {"client-cert", required_argument, 0, 'J'}, 1304 {"client-cert", required_argument, 0, 'J'},
1137 {"private-key", required_argument, 0, 'K'}, 1305 {"private-key", required_argument, 0, 'K'},
1138 {"ca-cert", required_argument, 0, CA_CERT_OPTION}, 1306 {"ca-cert", required_argument, 0, CA_CERT_OPTION},
1307 {"verify-cert", no_argument, 0, 'D'},
1308 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
1139 {"useragent", required_argument, 0, 'A'}, 1309 {"useragent", required_argument, 0, 'A'},
1140 {"header", required_argument, 0, 'k'}, 1310 {"header", required_argument, 0, 'k'},
1141 {"no-body", no_argument, 0, 'N'}, 1311 {"no-body", no_argument, 0, 'N'},
@@ -1146,12 +1316,16 @@ process_arguments (int argc, char **argv)
1146 {"use-ipv4", no_argument, 0, '4'}, 1316 {"use-ipv4", no_argument, 0, '4'},
1147 {"use-ipv6", no_argument, 0, '6'}, 1317 {"use-ipv6", no_argument, 0, '6'},
1148 {"extended-perfdata", no_argument, 0, 'E'}, 1318 {"extended-perfdata", no_argument, 0, 'E'},
1319 {"show-body", no_argument, 0, 'B'},
1320 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
1149 {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, 1321 {"http-version", required_argument, 0, HTTP_VERSION_OPTION},
1322 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION},
1323 {"cookie-jar", required_argument, 0, COOKIE_JAR},
1150 {0, 0, 0, 0} 1324 {0, 0, 0, 0}
1151 }; 1325 };
1152 1326
1153 if (argc < 2) 1327 if (argc < 2)
1154 return ERROR; 1328 return false;
1155 1329
1156 /* support check_http compatible arguments */ 1330 /* support check_http compatible arguments */
1157 for (c = 1; c < argc; c++) { 1331 for (c = 1; c < argc; c++) {
@@ -1170,7 +1344,7 @@ process_arguments (int argc, char **argv)
1170 server_url = strdup(DEFAULT_SERVER_URL); 1344 server_url = strdup(DEFAULT_SERVER_URL);
1171 1345
1172 while (1) { 1346 while (1) {
1173 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:NE", longopts, &option); 1347 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NEB", longopts, &option);
1174 if (c == -1 || c == EOF || c == 1) 1348 if (c == -1 || c == EOF || c == 1)
1175 break; 1349 break;
1176 1350
@@ -1231,7 +1405,7 @@ process_arguments (int argc, char **argv)
1231 if( strtol(optarg, NULL, 10) > MAX_PORT) 1405 if( strtol(optarg, NULL, 10) > MAX_PORT)
1232 usage2 (_("Invalid port number, supplied port number is too big"), optarg); 1406 usage2 (_("Invalid port number, supplied port number is too big"), optarg);
1233 server_port = (unsigned short)strtol(optarg, NULL, 10); 1407 server_port = (unsigned short)strtol(optarg, NULL, 10);
1234 specify_port = TRUE; 1408 specify_port = true;
1235 } 1409 }
1236 break; 1410 break;
1237 case 'a': /* authorization info */ 1411 case 'a': /* authorization info */
@@ -1265,10 +1439,10 @@ process_arguments (int argc, char **argv)
1265 http_opt_headers[http_opt_headers_count - 1] = optarg; 1439 http_opt_headers[http_opt_headers_count - 1] = optarg;
1266 break; 1440 break;
1267 case 'L': /* show html link */ 1441 case 'L': /* show html link */
1268 display_html = TRUE; 1442 display_html = true;
1269 break; 1443 break;
1270 case 'n': /* do not show html link */ 1444 case 'n': /* do not show html link */
1271 display_html = FALSE; 1445 display_html = false;
1272 break; 1446 break;
1273 case 'C': /* Check SSL cert validity */ 1447 case 'C': /* Check SSL cert validity */
1274#ifdef LIBCURL_FEATURE_SSL 1448#ifdef LIBCURL_FEATURE_SSL
@@ -1289,9 +1463,14 @@ process_arguments (int argc, char **argv)
1289 usage2 (_("Invalid certificate expiration period"), optarg); 1463 usage2 (_("Invalid certificate expiration period"), optarg);
1290 days_till_exp_warn = atoi (optarg); 1464 days_till_exp_warn = atoi (optarg);
1291 } 1465 }
1292 check_cert = TRUE; 1466 check_cert = true;
1293 goto enable_ssl; 1467 goto enable_ssl;
1294#endif 1468#endif
1469 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
1470#ifdef HAVE_SSL
1471 continue_after_check_cert = true;
1472 break;
1473#endif
1295 case 'J': /* use client certificate */ 1474 case 'J': /* use client certificate */
1296#ifdef LIBCURL_FEATURE_SSL 1475#ifdef LIBCURL_FEATURE_SSL
1297 test_file(optarg); 1476 test_file(optarg);
@@ -1310,10 +1489,15 @@ process_arguments (int argc, char **argv)
1310 ca_cert = optarg; 1489 ca_cert = optarg;
1311 goto enable_ssl; 1490 goto enable_ssl;
1312#endif 1491#endif
1492#ifdef LIBCURL_FEATURE_SSL
1493 case 'D': /* verify peer certificate & host */
1494 verify_peer_and_host = true;
1495 break;
1496#endif
1313 case 'S': /* use SSL */ 1497 case 'S': /* use SSL */
1314#ifdef LIBCURL_FEATURE_SSL 1498#ifdef LIBCURL_FEATURE_SSL
1315 enable_ssl: 1499 enable_ssl:
1316 use_ssl = TRUE; 1500 use_ssl = true;
1317 /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default. 1501 /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default.
1318 * Only set if it's non-zero. This helps when we include multiple 1502 * Only set if it's non-zero. This helps when we include multiple
1319 * parameters, like -S and -C combinations */ 1503 * parameters, like -S and -C combinations */
@@ -1354,7 +1538,7 @@ process_arguments (int argc, char **argv)
1354 ssl_version = CURL_SSLVERSION_DEFAULT; 1538 ssl_version = CURL_SSLVERSION_DEFAULT;
1355#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) */ 1539#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) */
1356 else 1540 else
1357 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); 1541 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2, 1.3 (with optional '+' suffix)"));
1358 } 1542 }
1359#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) 1543#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0)
1360 if (got_plus) { 1544 if (got_plus) {
@@ -1387,17 +1571,24 @@ process_arguments (int argc, char **argv)
1387#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ 1571#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */
1388 if (verbose >= 2) 1572 if (verbose >= 2)
1389 printf(_("* Set SSL/TLS version to %d\n"), ssl_version); 1573 printf(_("* Set SSL/TLS version to %d\n"), ssl_version);
1390 if (specify_port == FALSE) 1574 if (!specify_port)
1391 server_port = HTTPS_PORT; 1575 server_port = HTTPS_PORT;
1392 break; 1576 break;
1393#else /* LIBCURL_FEATURE_SSL */ 1577#else /* LIBCURL_FEATURE_SSL */
1394 /* -C -J and -K fall through to here without SSL */ 1578 /* -C -J and -K fall through to here without SSL */
1395 usage4 (_("Invalid option - SSL is not available")); 1579 usage4 (_("Invalid option - SSL is not available"));
1396 break; 1580 break;
1397 case SNI_OPTION: /* --sni is parsed, but ignored, the default is TRUE with libcurl */ 1581 case SNI_OPTION: /* --sni is parsed, but ignored, the default is true with libcurl */
1398 use_sni = TRUE; 1582 use_sni = true;
1399 break; 1583 break;
1400#endif /* LIBCURL_FEATURE_SSL */ 1584#endif /* LIBCURL_FEATURE_SSL */
1585 case MAX_REDIRS_OPTION:
1586 if (!is_intnonneg (optarg))
1587 usage2 (_("Invalid max_redirs count"), optarg);
1588 else {
1589 max_depth = atoi (optarg);
1590 }
1591 break;
1401 case 'f': /* onredirect */ 1592 case 'f': /* onredirect */
1402 if (!strcmp (optarg, "ok")) 1593 if (!strcmp (optarg, "ok"))
1403 onredirect = STATE_OK; 1594 onredirect = STATE_OK;
@@ -1449,11 +1640,11 @@ process_arguments (int argc, char **argv)
1449 if (errcode != 0) { 1640 if (errcode != 0) {
1450 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 1641 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
1451 printf (_("Could Not Compile Regular Expression: %s"), errbuf); 1642 printf (_("Could Not Compile Regular Expression: %s"), errbuf);
1452 return ERROR; 1643 return false;
1453 } 1644 }
1454 break; 1645 break;
1455 case INVERT_REGEX: 1646 case INVERT_REGEX:
1456 invert_regex = 1; 1647 invert_regex = true;
1457 break; 1648 break;
1458 case '4': 1649 case '4':
1459 address_family = AF_INET; 1650 address_family = AF_INET;
@@ -1488,7 +1679,7 @@ process_arguments (int argc, char **argv)
1488 break; 1679 break;
1489 } 1680 }
1490 case 'N': /* no-body */ 1681 case 'N': /* no-body */
1491 no_body = TRUE; 1682 no_body = true;
1492 break; 1683 break;
1493 case 'M': /* max-age */ 1684 case 'M': /* max-age */
1494 { 1685 {
@@ -1511,7 +1702,10 @@ process_arguments (int argc, char **argv)
1511 } 1702 }
1512 break; 1703 break;
1513 case 'E': /* show extended perfdata */ 1704 case 'E': /* show extended perfdata */
1514 show_extended_perfdata = TRUE; 1705 show_extended_perfdata = true;
1706 break;
1707 case 'B': /* print body content after status line */
1708 show_body = true;
1515 break; 1709 break;
1516 case HTTP_VERSION_OPTION: 1710 case HTTP_VERSION_OPTION:
1517 curl_http_version = CURL_HTTP_VERSION_NONE; 1711 curl_http_version = CURL_HTTP_VERSION_NONE;
@@ -1526,10 +1720,16 @@ process_arguments (int argc, char **argv)
1526 curl_http_version = CURL_HTTP_VERSION_NONE; 1720 curl_http_version = CURL_HTTP_VERSION_NONE;
1527#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */ 1721#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */
1528 } else { 1722 } else {
1529 fprintf (stderr, "unkown http-version parameter: %s\n", optarg); 1723 fprintf (stderr, "unknown http-version parameter: %s\n", optarg);
1530 exit (STATE_WARNING); 1724 exit (STATE_WARNING);
1531 } 1725 }
1532 break; 1726 break;
1727 case AUTOMATIC_DECOMPRESSION:
1728 automatic_decompression = true;
1729 break;
1730 case COOKIE_JAR:
1731 cookie_jar_file = optarg;
1732 break;
1533 case '?': 1733 case '?':
1534 /* print short usage statement if args not parsable */ 1734 /* print short usage statement if args not parsable */
1535 usage5 (); 1735 usage5 ();
@@ -1569,52 +1769,52 @@ process_arguments (int argc, char **argv)
1569 virtual_port = server_port; 1769 virtual_port = server_port;
1570 else { 1770 else {
1571 if ((use_ssl && server_port == HTTPS_PORT) || (!use_ssl && server_port == HTTP_PORT)) 1771 if ((use_ssl && server_port == HTTPS_PORT) || (!use_ssl && server_port == HTTP_PORT))
1572 if(specify_port == FALSE) 1772 if(!specify_port)
1573 server_port = virtual_port; 1773 server_port = virtual_port;
1574 } 1774 }
1575 1775
1576 return TRUE; 1776 return true;
1577} 1777}
1578 1778
1579char *perfd_time (double elapsed_time) 1779char *perfd_time (double elapsed_time)
1580{ 1780{
1581 return fperfdata ("time", elapsed_time, "s", 1781 return fperfdata ("time", elapsed_time, "s",
1582 thlds->warning?TRUE:FALSE, thlds->warning?thlds->warning->end:0, 1782 thlds->warning?true:false, thlds->warning?thlds->warning->end:0,
1583 thlds->critical?TRUE:FALSE, thlds->critical?thlds->critical->end:0, 1783 thlds->critical?true:false, thlds->critical?thlds->critical->end:0,
1584 TRUE, 0, TRUE, socket_timeout); 1784 true, 0, true, socket_timeout);
1585} 1785}
1586 1786
1587char *perfd_time_connect (double elapsed_time_connect) 1787char *perfd_time_connect (double elapsed_time_connect)
1588{ 1788{
1589 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1789 return fperfdata ("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1590} 1790}
1591 1791
1592char *perfd_time_ssl (double elapsed_time_ssl) 1792char *perfd_time_ssl (double elapsed_time_ssl)
1593{ 1793{
1594 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1794 return fperfdata ("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1595} 1795}
1596 1796
1597char *perfd_time_headers (double elapsed_time_headers) 1797char *perfd_time_headers (double elapsed_time_headers)
1598{ 1798{
1599 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1799 return fperfdata ("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1600} 1800}
1601 1801
1602char *perfd_time_firstbyte (double elapsed_time_firstbyte) 1802char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1603{ 1803{
1604 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1804 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1605} 1805}
1606 1806
1607char *perfd_time_transfer (double elapsed_time_transfer) 1807char *perfd_time_transfer (double elapsed_time_transfer)
1608{ 1808{
1609 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, TRUE, socket_timeout); 1809 return fperfdata ("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1610} 1810}
1611 1811
1612char *perfd_size (int page_len) 1812char *perfd_size (int page_len)
1613{ 1813{
1614 return perfdata ("size", page_len, "B", 1814 return perfdata ("size", page_len, "B",
1615 (min_page_len>0?TRUE:FALSE), min_page_len, 1815 (min_page_len>0?true:false), min_page_len,
1616 (min_page_len>0?TRUE:FALSE), 0, 1816 (min_page_len>0?true:false), 0,
1617 TRUE, 0, FALSE, 0); 1817 true, 0, false, 0);
1618} 1818}
1619 1819
1620void 1820void
@@ -1659,7 +1859,7 @@ print_help (void)
1659 printf (" %s\n", "-S, --ssl=VERSION[+]"); 1859 printf (" %s\n", "-S, --ssl=VERSION[+]");
1660 printf (" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); 1860 printf (" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents"));
1661 printf (" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); 1861 printf (" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,"));
1662 printf (" %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted.")); 1862 printf (" %s\n", _("1.2 = TLSv1.2, 1.3 = TLSv1.3). With a '+' suffix, newer versions are also accepted."));
1663 printf (" %s\n", _("Note: SSLv2 and SSLv3 are deprecated and are usually disabled in libcurl")); 1863 printf (" %s\n", _("Note: SSLv2 and SSLv3 are deprecated and are usually disabled in libcurl"));
1664 printf (" %s\n", "--sni"); 1864 printf (" %s\n", "--sni");
1665 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 1865 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
@@ -1671,7 +1871,11 @@ print_help (void)
1671#endif 1871#endif
1672 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1872 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1673 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1873 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1674 printf (" %s\n", _("(when this option is used the URL is not checked.)")); 1874 printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use"));
1875 printf (" %s\n", _(" --continue-after-certificate to override this behavior)"));
1876 printf (" %s\n", "--continue-after-certificate");
1877 printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check."));
1878 printf (" %s\n", _("Does nothing unless -C is used."));
1675 printf (" %s\n", "-J, --client-cert=FILE"); 1879 printf (" %s\n", "-J, --client-cert=FILE");
1676 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); 1880 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1677 printf (" %s\n", _("to be used in establishing the SSL session")); 1881 printf (" %s\n", _("to be used in establishing the SSL session"));
@@ -1680,6 +1884,8 @@ print_help (void)
1680 printf (" %s\n", _("matching the client certificate")); 1884 printf (" %s\n", _("matching the client certificate"));
1681 printf (" %s\n", "--ca-cert=FILE"); 1885 printf (" %s\n", "--ca-cert=FILE");
1682 printf (" %s\n", _("CA certificate file to verify peer against")); 1886 printf (" %s\n", _("CA certificate file to verify peer against"));
1887 printf (" %s\n", "-D, --verify-cert");
1888 printf (" %s\n", _("Verify the peer's SSL certificate and hostname"));
1683#endif 1889#endif
1684 1890
1685 printf (" %s\n", "-e, --expect=STRING"); 1891 printf (" %s\n", "-e, --expect=STRING");
@@ -1723,6 +1929,8 @@ print_help (void)
1723 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); 1929 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers"));
1724 printf (" %s\n", "-E, --extended-perfdata"); 1930 printf (" %s\n", "-E, --extended-perfdata");
1725 printf (" %s\n", _("Print additional performance data")); 1931 printf (" %s\n", _("Print additional performance data"));
1932 printf (" %s\n", "-B, --show-body");
1933 printf (" %s\n", _("Print body content below status line"));
1726 printf (" %s\n", "-L, --link"); 1934 printf (" %s\n", "-L, --link");
1727 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); 1935 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)"));
1728 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport|curl>"); 1936 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport|curl>");
@@ -1730,12 +1938,19 @@ print_help (void)
1730 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); 1938 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same."));
1731 printf (" %s\n", _("follow uses the old redirection algorithm of check_http.")); 1939 printf (" %s\n", _("follow uses the old redirection algorithm of check_http."));
1732 printf (" %s\n", _("curl uses CURL_FOLLOWLOCATION built into libcurl.")); 1940 printf (" %s\n", _("curl uses CURL_FOLLOWLOCATION built into libcurl."));
1941 printf (" %s\n", "--max-redirs=INTEGER");
1942 printf (" %s", _("Maximal number of redirects (default: "));
1943 printf ("%d)\n", DEFAULT_MAX_REDIRS);
1733 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 1944 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
1734 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); 1945 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
1735 printf ("\n"); 1946 printf ("\n");
1736 printf (" %s\n", "--http-version=VERSION"); 1947 printf (" %s\n", "--http-version=VERSION");
1737 printf (" %s\n", _("Connect via specific HTTP protocol.")); 1948 printf (" %s\n", _("Connect via specific HTTP protocol."));
1738 printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); 1949 printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)"));
1950 printf (" %s\n", "--enable-automatic-decompression");
1951 printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING)."));
1952 printf (" %s\n", "---cookie-jar=FILE");
1953 printf (" %s\n", _("Store cookies in the cookie jar and send them out when requested."));
1739 printf ("\n"); 1954 printf ("\n");
1740 1955
1741 printf (UT_WARN_CRIT); 1956 printf (UT_WARN_CRIT);
@@ -1813,15 +2028,22 @@ print_usage (void)
1813{ 2028{
1814 printf ("%s\n", _("Usage:")); 2029 printf ("%s\n", _("Usage:"));
1815 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); 2030 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
1816 printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>]\n"); 2031 printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>] [-D]\n");
1817 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); 2032 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
1818 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport|curl>]\n"); 2033 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport|curl>]\n");
1819 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); 2034 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
1820 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 2035 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
1821 printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n"); 2036 printf (" [-A string] [-k string] [-S <version>] [--sni]\n");
1822 printf (" [-T <content-type>] [-j method]\n"); 2037 printf (" [-T <content-type>] [-j method]\n");
1823 printf (" [--http-version=<version>]\n"); 2038 printf (" [--http-version=<version>] [--enable-automatic-decompression]\n");
2039 printf (" [--cookie-jar=<cookie jar file>\n");
2040 printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname);
2041 printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n");
1824 printf ("\n"); 2042 printf ("\n");
2043#ifdef LIBCURL_FEATURE_SSL
2044 printf ("%s\n", _("In the first form, make an HTTP request."));
2045 printf ("%s\n\n", _("In the second form, connect to the server and check the TLS certificate."));
2046#endif
1825 printf ("%s\n", _("WARNING: check_curl is experimental. Please use")); 2047 printf ("%s\n", _("WARNING: check_curl is experimental. Please use"));
1826 printf ("%s\n\n", _("check_http if you need a stable version.")); 2048 printf ("%s\n\n", _("check_http if you need a stable version."));
1827} 2049}
@@ -1848,9 +2070,12 @@ curlhelp_buffer_write_callback (void *buffer, size_t size, size_t nmemb, void *s
1848 curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream; 2070 curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream;
1849 2071
1850 while (buf->bufsize < buf->buflen + size * nmemb + 1) { 2072 while (buf->bufsize < buf->buflen + size * nmemb + 1) {
1851 buf->bufsize *= buf->bufsize * 2; 2073 buf->bufsize = buf->bufsize * 2;
1852 buf->buf = (char *)realloc (buf->buf, buf->bufsize); 2074 buf->buf = (char *)realloc (buf->buf, buf->bufsize);
1853 if (buf->buf == NULL) return -1; 2075 if (buf->buf == NULL) {
2076 fprintf(stderr, "malloc failed (%d) %s\n", errno, strerror(errno));
2077 return -1;
2078 }
1854 } 2079 }
1855 2080
1856 memcpy (buf->buf + buf->buflen, buffer, size * nmemb); 2081 memcpy (buf->buf + buf->buflen, buffer, size * nmemb);
@@ -1944,7 +2169,7 @@ curlhelp_parse_statusline (const char *buf, curlhelp_statusline *status_line)
1944 char *first_line_buf; 2169 char *first_line_buf;
1945 2170
1946 /* find last start of a new header */ 2171 /* find last start of a new header */
1947 start = strrstr2 (buf, "\r\nHTTP"); 2172 start = strrstr2 (buf, "\r\nHTTP/");
1948 if (start != NULL) { 2173 if (start != NULL) {
1949 start += 2; 2174 start += 2;
1950 buf = start; 2175 buf = start;
@@ -2037,7 +2262,7 @@ get_header_value (const struct phr_header* headers, const size_t nof_headers, co
2037{ 2262{
2038 int i; 2263 int i;
2039 for( i = 0; i < nof_headers; i++ ) { 2264 for( i = 0; i < nof_headers; i++ ) {
2040 if( strncasecmp( header, headers[i].name, max( headers[i].name_len, 4 ) ) == 0 ) { 2265 if(headers[i].name != NULL && strncasecmp( header, headers[i].name, max( headers[i].name_len, 4 ) ) == 0 ) {
2041 return strndup( headers[i].value, headers[i].value_len ); 2266 return strndup( headers[i].value, headers[i].value_len );
2042 } 2267 }
2043 } 2268 }
@@ -2056,7 +2281,7 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA
2056 size_t msglen; 2281 size_t msglen;
2057 2282
2058 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2283 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2059 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2284 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2060 headers, &nof_headers, 0); 2285 headers, &nof_headers, 0);
2061 2286
2062 server_date = get_header_value (headers, nof_headers, "date"); 2287 server_date = get_header_value (headers, nof_headers, "date");
@@ -2114,7 +2339,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri
2114 curlhelp_statusline status_line; 2339 curlhelp_statusline status_line;
2115 2340
2116 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2341 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2117 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2342 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2118 headers, &nof_headers, 0); 2343 headers, &nof_headers, 0);
2119 2344
2120 content_length_s = get_header_value (headers, nof_headers, "content-length"); 2345 content_length_s = get_header_value (headers, nof_headers, "content-length");
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 844e625..935acce 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -1,29 +1,29 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_disk plugin 3* Monitoring check_disk plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2008 Monitoring Plugins Development Team 6* Copyright (c) 1999-2008 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_disk plugin 10* This file contains the check_disk plugin
11* 11*
12* 12*
13* This program is free software: you can redistribute it and/or modify 13* This program is free software: you can redistribute it and/or modify
14* it under the terms of the GNU General Public License as published by 14* it under the terms of the GNU General Public License as published by
15* the Free Software Foundation, either version 3 of the License, or 15* the Free Software Foundation, either version 3 of the License, or
16* (at your option) any later version. 16* (at your option) any later version.
17* 17*
18* This program is distributed in the hope that it will be useful, 18* This program is distributed in the hope that it will be useful,
19* but WITHOUT ANY WARRANTY; without even the implied warranty of 19* but WITHOUT ANY WARRANTY; without even the implied warranty of
20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21* GNU General Public License for more details. 21* GNU General Public License for more details.
22* 22*
23* You should have received a copy of the GNU General Public License 23* You should have received a copy of the GNU General Public License
24* along with this program. If not, see <http://www.gnu.org/licenses/>. 24* along with this program. If not, see <http://www.gnu.org/licenses/>.
25* 25*
26* 26*
27*****************************************************************************/ 27*****************************************************************************/
28 28
29const char *progname = "check_disk"; 29const char *progname = "check_disk";
@@ -46,7 +46,7 @@ const char *email = "devel@monitoring-plugins.org";
46#include <stdarg.h> 46#include <stdarg.h>
47#include "fsusage.h" 47#include "fsusage.h"
48#include "mountlist.h" 48#include "mountlist.h"
49#include "intprops.h" /* necessary for TYPE_MAXIMUM */ 49#include "intprops.h" /* necessary for TYPE_MAXIMUM */
50#if HAVE_LIMITS_H 50#if HAVE_LIMITS_H
51# include <limits.h> 51# include <limits.h>
52#endif 52#endif
@@ -171,9 +171,6 @@ main (int argc, char **argv)
171 char *perf_ilabel; 171 char *perf_ilabel;
172 char *preamble; 172 char *preamble;
173 char *flag_header; 173 char *flag_header;
174 double inode_space_pct;
175 double warning_high_tide;
176 double critical_high_tide;
177 int temp_result; 174 int temp_result;
178 175
179 struct mount_entry *me; 176 struct mount_entry *me;
@@ -232,8 +229,10 @@ main (int argc, char **argv)
232 /* Process for every path in list */ 229 /* Process for every path in list */
233 for (path = path_select_list; path; path=path->name_next) { 230 for (path = path_select_list; path; path=path->name_next) {
234 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) 231 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL)
235 printf("Thresholds(pct) for %s warn: %f crit %f\n",path->name, path->freespace_percent->warning->end, 232 printf("Thresholds(pct) for %s warn: %f crit %f\n",
236 path->freespace_percent->critical->end); 233 path->name,
234 path->freespace_percent->warning->end,
235 path->freespace_percent->critical->end);
237 236
238 if (verbose >= 3 && path->group != NULL) 237 if (verbose >= 3 && path->group != NULL)
239 printf("Group of %s: %s\n",path->name,path->group); 238 printf("Group of %s: %s\n",path->name,path->group);
@@ -245,17 +244,17 @@ main (int argc, char **argv)
245 244
246#ifdef __CYGWIN__ 245#ifdef __CYGWIN__
247 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) 246 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11)
248 continue; 247 continue;
249 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); 248 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10);
250 if (GetDriveType(mountdir) != DRIVE_FIXED) 249 if (GetDriveType(mountdir) != DRIVE_FIXED)
251 me->me_remote = 1; 250 me->me_remote = 1;
252#endif 251#endif
253 /* Filters */ 252 /* Filters */
254 253
255 /* Remove filesystems already seen */ 254 /* Remove filesystems already seen */
256 if (np_seen_name(seen, me->me_mountdir)) { 255 if (np_seen_name(seen, me->me_mountdir)) {
257 continue; 256 continue;
258 } 257 }
259 np_add_name(&seen, me->me_mountdir); 258 np_add_name(&seen, me->me_mountdir);
260 259
261 if (path->group == NULL) { 260 if (path->group == NULL) {
@@ -288,8 +287,17 @@ main (int argc, char **argv)
288 get_stats (path, &fsp); 287 get_stats (path, &fsp);
289 288
290 if (verbose >= 3) { 289 if (verbose >= 3) {
291 printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%llu mult=%llu\n", 290 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",
292 me->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult); 291 me->me_mountdir,
292 path->dused_pct,
293 path->dfree_pct,
294 path->dused_units,
295 path->dfree_units,
296 path->dtotal_units,
297 path->dused_inodes_percent,
298 path->dfree_inodes_percent,
299 fsp.fsu_blocksize,
300 mult);
293 } 301 }
294 302
295 /* Threshold comparisons */ 303 /* Threshold comparisons */
@@ -326,84 +334,78 @@ main (int argc, char **argv)
326 */ 334 */
327 335
328 /* *_high_tide must be reinitialized at each run */ 336 /* *_high_tide must be reinitialized at each run */
329 warning_high_tide = UINT_MAX; 337 uint64_t warning_high_tide = UINT64_MAX;
330 critical_high_tide = UINT_MAX;
331 338
332 if (path->freespace_units->warning != NULL) { 339 if (path->freespace_units->warning != NULL) {
333 warning_high_tide = path->dtotal_units - path->freespace_units->warning->end; 340 warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * mult;
334 } 341 }
335 if (path->freespace_percent->warning != NULL) { 342 if (path->freespace_percent->warning != NULL) {
336 warning_high_tide = abs( min( (double) warning_high_tide, (double) (1.0 - path->freespace_percent->warning->end/100)*path->dtotal_units )); 343 warning_high_tide = min( warning_high_tide, (uint64_t)((1.0 - path->freespace_percent->warning->end/100) * (path->dtotal_units * mult)) );
337 } 344 }
345
346 uint64_t critical_high_tide = UINT64_MAX;
347
338 if (path->freespace_units->critical != NULL) { 348 if (path->freespace_units->critical != NULL) {
339 critical_high_tide = path->dtotal_units - path->freespace_units->critical->end; 349 critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * mult;
340 } 350 }
341 if (path->freespace_percent->critical != NULL) { 351 if (path->freespace_percent->critical != NULL) {
342 critical_high_tide = abs( min( (double) critical_high_tide, (double) (1.0 - path->freespace_percent->critical->end/100)*path->dtotal_units )); 352 critical_high_tide = min( critical_high_tide, (uint64_t)((1.0 - path->freespace_percent->critical->end/100) * (path->dtotal_units * mult)) );
343 } 353 }
344 354
345 /* Nb: *_high_tide are unset when == UINT_MAX */ 355 /* Nb: *_high_tide are unset when == UINT64_MAX */
346 xasprintf (&perf, "%s %s", perf, 356 xasprintf (&perf, "%s %s", perf,
347 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 357 perfdata_uint64 (
348 path->dused_units, units, 358 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
349 (warning_high_tide != UINT_MAX ? TRUE : FALSE), warning_high_tide, 359 path->dused_units * mult, "B",
350 (critical_high_tide != UINT_MAX ? TRUE : FALSE), critical_high_tide, 360 (warning_high_tide == UINT64_MAX ? FALSE : TRUE), warning_high_tide,
351 TRUE, 0, 361 (critical_high_tide == UINT64_MAX ? FALSE : TRUE), critical_high_tide,
352 TRUE, path->dtotal_units)); 362 TRUE, 0,
363 TRUE, path->dtotal_units * mult));
353 364
354 if (display_inodes_perfdata) { 365 if (display_inodes_perfdata) {
355 /* *_high_tide must be reinitialized at each run */ 366 /* *_high_tide must be reinitialized at each run */
356 warning_high_tide = UINT_MAX; 367 warning_high_tide = UINT64_MAX;
357 critical_high_tide = UINT_MAX; 368 critical_high_tide = UINT64_MAX;
358 369
359 if (path->freeinodes_percent->warning != NULL) { 370 if (path->freeinodes_percent->warning != NULL) {
360 warning_high_tide = abs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total )); 371 warning_high_tide = (uint64_t) fabs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total ));
361 } 372 }
362 if (path->freeinodes_percent->critical != NULL) { 373 if (path->freeinodes_percent->critical != NULL) {
363 critical_high_tide = abs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total )); 374 critical_high_tide = (uint64_t) fabs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total ));
364 } 375 }
365 376
366 xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); 377 xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir);
367 /* Nb: *_high_tide are unset when == UINT_MAX */ 378 /* Nb: *_high_tide are unset when == UINT64_MAX */
368 xasprintf (&perf, "%s %s", perf, 379 xasprintf (&perf, "%s %s", perf,
369 perfdata (perf_ilabel, 380 perfdata_uint64 (perf_ilabel,
370 path->inodes_used, "", 381 path->inodes_used, "",
371 (warning_high_tide != UINT_MAX ? TRUE : FALSE), warning_high_tide, 382 (warning_high_tide != UINT64_MAX ? TRUE : FALSE), warning_high_tide,
372 (critical_high_tide != UINT_MAX ? TRUE : FALSE), critical_high_tide, 383 (critical_high_tide != UINT64_MAX ? TRUE : FALSE), critical_high_tide,
373 TRUE, 0, 384 TRUE, 0,
374 TRUE, path->inodes_total)); 385 TRUE, path->inodes_total));
375 } 386 }
376 387
377 if (disk_result==STATE_OK && erronly && !verbose) 388 if (disk_result==STATE_OK && erronly && !verbose)
378 continue; 389 continue;
379 390
380 if(disk_result && verbose >= 1) { 391 if(disk_result && verbose >= 1) {
381 xasprintf(&flag_header, " %s [", state_text (disk_result)); 392 xasprintf(&flag_header, " %s [", state_text (disk_result));
382 } else { 393 } else {
383 xasprintf(&flag_header, ""); 394 xasprintf(&flag_header, "");
384 } 395 }
385 xasprintf (&output, "%s%s %s %.0f %s (%.0f%%", 396 xasprintf (&output, "%s%s %s %llu%s (%.0f%%",
386 output, flag_header, 397 output, flag_header,
387 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 398 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
388 path->dfree_units, 399 path->dfree_units,
389 units, 400 units,
390 path->dfree_pct); 401 path->dfree_pct);
391 if (path->dused_inodes_percent < 0) { 402 if (path->dused_inodes_percent < 0) {
392 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); 403 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : ""));
393 } else { 404 } else {
394 xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : "")); 405 xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : ""));
395 } 406 }
396 free(flag_header); 407 free(flag_header);
397 /* TODO: Need to do a similar debug line
398 xasprintf (&details, _("%s\n\
399%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
400 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
401 me->me_devname, me->me_type, me->me_mountdir,
402 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
403 */
404
405 } 408 }
406
407 } 409 }
408 410
409 if (verbose >= 2) 411 if (verbose >= 2)
@@ -557,14 +559,14 @@ process_arguments (int argc, char **argv)
557 } 559 }
558 break; 560 break;
559 561
560 case 'W': /* warning inode threshold */ 562 case 'W': /* warning inode threshold */
561 if (*optarg == '@') { 563 if (*optarg == '@') {
562 warn_freeinodes_percent = optarg; 564 warn_freeinodes_percent = optarg;
563 } else { 565 } else {
564 xasprintf(&warn_freeinodes_percent, "@%s", optarg); 566 xasprintf(&warn_freeinodes_percent, "@%s", optarg);
565 } 567 }
566 break; 568 break;
567 case 'K': /* critical inode threshold */ 569 case 'K': /* critical inode threshold */
568 if (*optarg == '@') { 570 if (*optarg == '@') {
569 crit_freeinodes_percent = optarg; 571 crit_freeinodes_percent = optarg;
570 } else { 572 } else {
@@ -574,21 +576,24 @@ process_arguments (int argc, char **argv)
574 case 'u': 576 case 'u':
575 if (units) 577 if (units)
576 free(units); 578 free(units);
577 if (! strcmp (optarg, "bytes")) { 579 if (! strcasecmp (optarg, "bytes")) {
578 mult = (uintmax_t)1; 580 mult = (uintmax_t)1;
579 units = strdup ("B"); 581 units = strdup ("B");
580 } else if (! strcmp (optarg, "kB")) { 582 } else if ( (! strcmp (optarg, "kB")) || (!strcmp(optarg, "KiB")) ) {
581 mult = (uintmax_t)1024; 583 mult = (uintmax_t)1024;
582 units = strdup ("kB"); 584 units = strdup ("kiB");
583 } else if (! strcmp (optarg, "MB")) { 585 } else if ( (! strcmp (optarg, "MB")) || (!strcmp(optarg, "MiB")) ) {
584 mult = (uintmax_t)1024 * 1024; 586 mult = (uintmax_t)1024 * 1024;
585 units = strdup ("MB"); 587 units = strdup ("MiB");
586 } else if (! strcmp (optarg, "GB")) { 588 } else if ( (! strcmp (optarg, "GB")) || (!strcmp(optarg, "GiB")) ) {
587 mult = (uintmax_t)1024 * 1024 * 1024; 589 mult = (uintmax_t)1024 * 1024 * 1024;
588 units = strdup ("GB"); 590 units = strdup ("GiB");
589 } else if (! strcmp (optarg, "TB")) { 591 } else if ( (! strcmp (optarg, "TB")) || (!strcmp(optarg, "TiB")) ) {
590 mult = (uintmax_t)1024 * 1024 * 1024 * 1024; 592 mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
591 units = strdup ("TB"); 593 units = strdup ("TiB");
594 } else if ( (! strcmp (optarg, "PB")) || (!strcmp(optarg, "PiB")) ) {
595 mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024;
596 units = strdup ("PiB");
592 } else { 597 } else {
593 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg); 598 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
594 } 599 }
@@ -599,13 +604,13 @@ process_arguments (int argc, char **argv)
599 mult = 1024; 604 mult = 1024;
600 if (units) 605 if (units)
601 free(units); 606 free(units);
602 units = strdup ("kB"); 607 units = strdup ("kiB");
603 break; 608 break;
604 case 'm': /* display mountpoint */ 609 case 'm': /* display mountpoint */
605 mult = 1024 * 1024; 610 mult = 1024 * 1024;
606 if (units) 611 if (units)
607 free(units); 612 free(units);
608 units = strdup ("MB"); 613 units = strdup ("MiB");
609 break; 614 break;
610 case 'L': 615 case 'L':
611 stat_remote_fs = 1; 616 stat_remote_fs = 1;
@@ -675,6 +680,7 @@ process_arguments (int argc, char **argv)
675 break; 680 break;
676 case 'I': 681 case 'I':
677 cflags |= REG_ICASE; 682 cflags |= REG_ICASE;
683 // Intentional fallthrough
678 case 'i': 684 case 'i':
679 if (!path_selected) 685 if (!path_selected)
680 die (STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); 686 die (STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly"));
@@ -714,8 +720,10 @@ process_arguments (int argc, char **argv)
714 720
715 case 'A': 721 case 'A':
716 optarg = strdup(".*"); 722 optarg = strdup(".*");
723 // Intentional fallthrough
717 case 'R': 724 case 'R':
718 cflags |= REG_ICASE; 725 cflags |= REG_ICASE;
726 // Intentional fallthrough
719 case 'r': 727 case 'r':
720 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 728 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
721 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 729 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
@@ -812,7 +820,7 @@ process_arguments (int argc, char **argv)
812 } 820 }
813 821
814 if (units == NULL) { 822 if (units == NULL) {
815 units = strdup ("MB"); 823 units = strdup ("MiB");
816 mult = (uintmax_t)1024 * 1024; 824 mult = (uintmax_t)1024 * 1024;
817 } 825 }
818 826
@@ -848,51 +856,6 @@ set_all_thresholds (struct parameter_list *path)
848 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); 856 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
849} 857}
850 858
851/* TODO: Remove?
852
853int
854validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
855{
856 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
857 printf (_("INPUT ERROR: No thresholds specified"));
858 print_path (mypath);
859 return ERROR;
860 }
861 else if ((wp >= 0.0 || cp >= 0.0) &&
862 (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
863 printf (_("\
864INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
865 cp, wp);
866 print_path (mypath);
867 return ERROR;
868 }
869 else if ((iwp >= 0.0 || icp >= 0.0) &&
870 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
871 printf (_("\
872INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
873 icp, iwp);
874 print_path (mypath);
875 return ERROR;
876 }
877 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
878 printf (_("\
879INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
880 (unsigned long)c, (unsigned long)w);
881 print_path (mypath);
882 return ERROR;
883 }
884
885 return OK;
886}
887
888*/
889
890
891
892
893
894
895
896void 859void
897print_help (void) 860print_help (void)
898{ 861{
@@ -947,7 +910,7 @@ print_help (void)
947 printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); 910 printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems"));
948 printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); 911 printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)"));
949 printf (" %s\n", "-M, --mountpoint"); 912 printf (" %s\n", "-M, --mountpoint");
950 printf (" %s\n", _("Display the mountpoint instead of the partition")); 913 printf (" %s\n", _("Display the (block) device instead of the mount point"));
951 printf (" %s\n", "-m, --megabytes"); 914 printf (" %s\n", "-m, --megabytes");
952 printf (" %s\n", _("Same as '--units MB'")); 915 printf (" %s\n", _("Same as '--units MB'"));
953 printf (" %s\n", "-A, --all"); 916 printf (" %s\n", "-A, --all");
@@ -988,7 +951,7 @@ void
988print_usage (void) 951print_usage (void)
989{ 952{
990 printf ("%s\n", _("Usage:")); 953 printf ("%s\n", _("Usage:"));
991 printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname); 954 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);
992 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); 955 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
993 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); 956 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n");
994} 957}
@@ -1026,20 +989,26 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
1026 if (p_list->group && ! (strcmp(p_list->group, p->group))) { 989 if (p_list->group && ! (strcmp(p_list->group, p->group))) {
1027 stat_path(p_list); 990 stat_path(p_list);
1028 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); 991 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
1029 get_path_stats(p_list, &tmpfsp); 992 get_path_stats(p_list, &tmpfsp);
1030 if (verbose >= 3) 993 if (verbose >= 3)
1031 printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", 994 printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n",
1032 p_list->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, p_list->dfree_units, 995 p_list->group,
1033 p_list->dtotal_units, mult); 996 tmpfsp.fsu_blocks,
1034 997 tmpfsp.fsu_blocksize,
1035 /* prevent counting the first FS of a group twice since its parameter_list entry 998 p_list->best_match->me_mountdir,
999 p_list->dused_units,
1000 p_list->dfree_units,
1001 p_list->dtotal_units,
1002 mult);
1003
1004 /* prevent counting the first FS of a group twice since its parameter_list entry
1036 * is used to carry the information of all file systems of the entire group */ 1005 * is used to carry the information of all file systems of the entire group */
1037 if (! first) { 1006 if (! first) {
1038 p->total += p_list->total; 1007 p->total += p_list->total;
1039 p->available += p_list->available; 1008 p->available += p_list->available;
1040 p->available_to_root += p_list->available_to_root; 1009 p->available_to_root += p_list->available_to_root;
1041 p->used += p_list->used; 1010 p->used += p_list->used;
1042 1011
1043 p->dused_units += p_list->dused_units; 1012 p->dused_units += p_list->dused_units;
1044 p->dfree_units += p_list->dfree_units; 1013 p->dfree_units += p_list->dfree_units;
1045 p->dtotal_units += p_list->dtotal_units; 1014 p->dtotal_units += p_list->dtotal_units;
@@ -1050,28 +1019,29 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
1050 } 1019 }
1051 first = 0; 1020 first = 0;
1052 } 1021 }
1053 if (verbose >= 3) 1022 if (verbose >= 3)
1054 printf("Group %s now has: used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", 1023 printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n",
1055 p->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p->best_match->me_mountdir, p->dused_units, 1024 p->group,
1056 p->dfree_units, p->dtotal_units, mult); 1025 p->dused_units,
1026 p->dfree_units,
1027 p->dtotal_units,
1028 tmpfsp.fsu_blocksize,
1029 mult);
1057 } 1030 }
1058 /* modify devname and mountdir for output */ 1031 /* modify devname and mountdir for output */
1059 p->best_match->me_mountdir = p->best_match->me_devname = p->group; 1032 p->best_match->me_mountdir = p->best_match->me_devname = p->group;
1060 } 1033 }
1061 /* finally calculate percentages for either plain FS or summed up group */ 1034 /* finally calculate percentages for either plain FS or summed up group */
1062 p->dused_pct = calculate_percent( p->used, p->used + p->available ); /* used + available can never be > uintmax */ 1035 p->dused_pct = calculate_percent( p->used, p->used + p->available ); /* used + available can never be > uintmax */
1063 p->dfree_pct = 100 - p->dused_pct; 1036 p->dfree_pct = 100 - p->dused_pct;
1064 p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); 1037 p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total);
1065 p->dfree_inodes_percent = 100 - p->dused_inodes_percent; 1038 p->dfree_inodes_percent = 100 - p->dused_inodes_percent;
1066 1039
1067} 1040}
1068 1041
1069void 1042void
1070get_path_stats (struct parameter_list *p, struct fs_usage *fsp) { 1043get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1071 /* 2007-12-08 - Workaround for Gnulib reporting insanely high available 1044 p->available = fsp->fsu_bavail;
1072 * space on BSD (the actual value should be negative but fsp->fsu_bavail
1073 * is unsigned) */
1074 p->available = fsp->fsu_bavail > fsp->fsu_bfree ? 0 : fsp->fsu_bavail;
1075 p->available_to_root = fsp->fsu_bfree; 1045 p->available_to_root = fsp->fsu_bfree;
1076 p->used = fsp->fsu_blocks - fsp->fsu_bfree; 1046 p->used = fsp->fsu_blocks - fsp->fsu_bfree;
1077 if (freespace_ignore_reserved) { 1047 if (freespace_ignore_reserved) {
@@ -1081,12 +1051,12 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1081 /* default behaviour : take all the blocks into account */ 1051 /* default behaviour : take all the blocks into account */
1082 p->total = fsp->fsu_blocks; 1052 p->total = fsp->fsu_blocks;
1083 } 1053 }
1084 1054
1085 p->dused_units = p->used*fsp->fsu_blocksize/mult; 1055 p->dused_units = p->used*fsp->fsu_blocksize/mult;
1086 p->dfree_units = p->available*fsp->fsu_blocksize/mult; 1056 p->dfree_units = p->available*fsp->fsu_blocksize/mult;
1087 p->dtotal_units = p->total*fsp->fsu_blocksize/mult; 1057 p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
1088 /* Free file nodes. Not sure the workaround is required, but in case...*/ 1058 /* Free file nodes. Not sure the workaround is required, but in case...*/
1089 p->inodes_free = fsp->fsu_favail > fsp->fsu_ffree ? 0 : fsp->fsu_favail; 1059 p->inodes_free = fsp->fsu_ffree;
1090 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ 1060 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */
1091 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; 1061 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree;
1092 if (freespace_ignore_reserved) { 1062 if (freespace_ignore_reserved) {
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index b90f50e..9de6caf 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -41,7 +41,7 @@ const char *email = "devel@monitoring-plugins.org";
41 41
42int process_arguments (int, char **); 42int process_arguments (int, char **);
43int validate_arguments (void); 43int validate_arguments (void);
44int error_scan (char *); 44int error_scan (char *, int *);
45int ip_match_cidr(const char *, const char *); 45int ip_match_cidr(const char *, const char *);
46unsigned long ip2long(const char *); 46unsigned long ip2long(const char *);
47void print_help (void); 47void print_help (void);
@@ -54,6 +54,7 @@ char ptr_server[ADDRESS_LENGTH] = "";
54int verbose = FALSE; 54int verbose = FALSE;
55char **expected_address = NULL; 55char **expected_address = NULL;
56int expected_address_cnt = 0; 56int expected_address_cnt = 0;
57int expect_nxdomain = FALSE;
57 58
58int expect_authority = FALSE; 59int expect_authority = FALSE;
59int all_match = FALSE; 60int all_match = FALSE;
@@ -87,6 +88,7 @@ main (int argc, char **argv)
87 int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ 88 int parse_address = FALSE; /* This flag scans for Address: but only after Name: */
88 output chld_out, chld_err; 89 output chld_out, chld_err;
89 size_t i; 90 size_t i;
91 int is_nxdomain = FALSE;
90 92
91 setlocale (LC_ALL, ""); 93 setlocale (LC_ALL, "");
92 bindtextdomain (PACKAGE, LOCALEDIR); 94 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -186,7 +188,7 @@ main (int argc, char **argv)
186 } 188 }
187 189
188 190
189 result = error_scan (chld_out.line[i]); 191 result = error_scan (chld_out.line[i], &is_nxdomain);
190 if (result != STATE_OK) { 192 if (result != STATE_OK) {
191 msg = strchr (chld_out.line[i], ':'); 193 msg = strchr (chld_out.line[i], ':');
192 if(msg) msg++; 194 if(msg) msg++;
@@ -199,8 +201,8 @@ main (int argc, char **argv)
199 if (verbose) 201 if (verbose)
200 puts(chld_err.line[i]); 202 puts(chld_err.line[i]);
201 203
202 if (error_scan (chld_err.line[i]) != STATE_OK) { 204 if (error_scan (chld_err.line[i], &is_nxdomain) != STATE_OK) {
203 result = max_state (result, error_scan (chld_err.line[i])); 205 result = max_state (result, error_scan (chld_err.line[i], &is_nxdomain));
204 msg = strchr(input_buffer, ':'); 206 msg = strchr(input_buffer, ':');
205 if(msg) 207 if(msg)
206 msg++; 208 msg++;
@@ -209,6 +211,10 @@ main (int argc, char **argv)
209 } 211 }
210 } 212 }
211 213
214 if (is_nxdomain && !expect_nxdomain) {
215 die (STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), query_address);
216 }
217
212 if (addresses) { 218 if (addresses) {
213 int i,slen; 219 int i,slen;
214 char *adrp; 220 char *adrp;
@@ -260,6 +266,16 @@ main (int argc, char **argv)
260 } 266 }
261 } 267 }
262 268
269 if (expect_nxdomain) {
270 if (!is_nxdomain) {
271 result = STATE_CRITICAL;
272 xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address);
273 } else {
274 if (address != NULL) free(address);
275 address = "NXDOMAIN";
276 }
277 }
278
263 /* check if authoritative */ 279 /* check if authoritative */
264 if (result == STATE_OK && expect_authority && non_authoritative) { 280 if (result == STATE_OK && expect_authority && non_authoritative) {
265 result = STATE_CRITICAL; 281 result = STATE_CRITICAL;
@@ -339,9 +355,15 @@ ip2long(const char* src) {
339} 355}
340 356
341int 357int
342error_scan (char *input_buffer) 358error_scan (char *input_buffer, int *is_nxdomain)
343{ 359{
344 360
361 const int nxdomain = strstr (input_buffer, "Non-existent") ||
362 strstr (input_buffer, "** server can't find") ||
363 strstr (input_buffer, "** Can't find") ||
364 strstr (input_buffer, "NXDOMAIN");
365 if (nxdomain) *is_nxdomain = TRUE;
366
345 /* the DNS lookup timed out */ 367 /* the DNS lookup timed out */
346 if (strstr (input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || 368 if (strstr (input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) ||
347 strstr (input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || 369 strstr (input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) ||
@@ -360,7 +382,7 @@ error_scan (char *input_buffer)
360 382
361 /* Connection was refused */ 383 /* Connection was refused */
362 else if (strstr (input_buffer, "Connection refused") || 384 else if (strstr (input_buffer, "Connection refused") ||
363 strstr (input_buffer, "Couldn't find server") || 385 strstr (input_buffer, "Couldn't find server") ||
364 strstr (input_buffer, "Refused") || 386 strstr (input_buffer, "Refused") ||
365 (strstr (input_buffer, "** server can't find") && 387 (strstr (input_buffer, "** server can't find") &&
366 strstr (input_buffer, ": REFUSED"))) 388 strstr (input_buffer, ": REFUSED")))
@@ -374,13 +396,6 @@ error_scan (char *input_buffer)
374 else if (strstr (input_buffer, "No information")) 396 else if (strstr (input_buffer, "No information"))
375 die (STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server); 397 die (STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server);
376 398
377 /* Host or domain name does not exist */
378 else if (strstr (input_buffer, "Non-existent") ||
379 strstr (input_buffer, "** server can't find") ||
380 strstr (input_buffer, "** Can't find") ||
381 strstr (input_buffer,"NXDOMAIN"))
382 die (STATE_CRITICAL, _("Domain %s was not found by the server\n"), query_address);
383
384 /* Network is unreachable */ 399 /* Network is unreachable */
385 else if (strstr (input_buffer, "Network is unreachable")) 400 else if (strstr (input_buffer, "Network is unreachable"))
386 die (STATE_CRITICAL, _("Network is unreachable\n")); 401 die (STATE_CRITICAL, _("Network is unreachable\n"));
@@ -417,6 +432,7 @@ process_arguments (int argc, char **argv)
417 {"server", required_argument, 0, 's'}, 432 {"server", required_argument, 0, 's'},
418 {"reverse-server", required_argument, 0, 'r'}, 433 {"reverse-server", required_argument, 0, 'r'},
419 {"expected-address", required_argument, 0, 'a'}, 434 {"expected-address", required_argument, 0, 'a'},
435 {"expect-nxdomain", no_argument, 0, 'n'},
420 {"expect-authority", no_argument, 0, 'A'}, 436 {"expect-authority", no_argument, 0, 'A'},
421 {"all", no_argument, 0, 'L'}, 437 {"all", no_argument, 0, 'L'},
422 {"warning", required_argument, 0, 'w'}, 438 {"warning", required_argument, 0, 'w'},
@@ -432,7 +448,7 @@ process_arguments (int argc, char **argv)
432 strcpy (argv[c], "-t"); 448 strcpy (argv[c], "-t");
433 449
434 while (1) { 450 while (1) {
435 c = getopt_long (argc, argv, "hVvALt:H:s:r:a:w:c:", long_opts, &opt_index); 451 c = getopt_long (argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index);
436 452
437 if (c == -1 || c == EOF) 453 if (c == -1 || c == EOF)
438 break; 454 break;
@@ -473,9 +489,26 @@ process_arguments (int argc, char **argv)
473 case 'a': /* expected address */ 489 case 'a': /* expected address */
474 if (strlen (optarg) >= ADDRESS_LENGTH) 490 if (strlen (optarg) >= ADDRESS_LENGTH)
475 die (STATE_UNKNOWN, _("Input buffer overflow\n")); 491 die (STATE_UNKNOWN, _("Input buffer overflow\n"));
476 expected_address = (char **)realloc(expected_address, (expected_address_cnt+1) * sizeof(char**)); 492 if (strchr(optarg, ',') != NULL) {
477 expected_address[expected_address_cnt] = strdup(optarg); 493 char *comma = strchr(optarg, ',');
478 expected_address_cnt++; 494 while (comma != NULL) {
495 expected_address = (char **)realloc(expected_address, (expected_address_cnt+1) * sizeof(char**));
496 expected_address[expected_address_cnt] = strndup(optarg, comma - optarg);
497 expected_address_cnt++;
498 optarg = comma + 1;
499 comma = strchr(optarg, ',');
500 }
501 expected_address = (char **)realloc(expected_address, (expected_address_cnt+1) * sizeof(char**));
502 expected_address[expected_address_cnt] = strdup(optarg);
503 expected_address_cnt++;
504 } else {
505 expected_address = (char **)realloc(expected_address, (expected_address_cnt+1) * sizeof(char**));
506 expected_address[expected_address_cnt] = strdup(optarg);
507 expected_address_cnt++;
508 }
509 break;
510 case 'n': /* expect NXDOMAIN */
511 expect_nxdomain = TRUE;
479 break; 512 break;
480 case 'A': /* expect authority */ 513 case 'A': /* expect authority */
481 expect_authority = TRUE; 514 expect_authority = TRUE;
@@ -518,8 +551,15 @@ process_arguments (int argc, char **argv)
518int 551int
519validate_arguments () 552validate_arguments ()
520{ 553{
521 if (query_address[0] == 0) 554 if (query_address[0] == 0) {
555 printf ("missing --host argument\n");
522 return ERROR; 556 return ERROR;
557 }
558
559 if (expected_address_cnt > 0 && expect_nxdomain) {
560 printf ("--expected-address and --expect-nxdomain cannot be combined\n");
561 return ERROR;
562 }
523 563
524 return OK; 564 return OK;
525} 565}
@@ -552,6 +592,9 @@ print_help (void)
552 printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); 592 printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end"));
553 printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); 593 printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any"));
554 printf (" %s\n", _("value matches).")); 594 printf (" %s\n", _("value matches)."));
595 printf (" -n, --expect-nxdomain\n");
596 printf (" %s\n", _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)"));
597 printf (" %s\n", _("Cannot be used together with -a"));
555 printf (" -A, --expect-authority\n"); 598 printf (" -A, --expect-authority\n");
556 printf (" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup")); 599 printf (" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup"));
557 printf (" -w, --warning=seconds\n"); 600 printf (" -w, --warning=seconds\n");
@@ -572,5 +615,5 @@ void
572print_usage (void) 615print_usage (void)
573{ 616{
574 printf ("%s\n", _("Usage:")); 617 printf ("%s\n", _("Usage:"));
575 printf ("%s -H host [-s server] [-a expected-address] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname); 618 printf ("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname);
576} 619}
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index 521d0fe..db43316 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,6 +66,7 @@ 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
@@ -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);
@@ -446,9 +465,7 @@ get_threshold (char *arg, char *rv[2])
446} 465}
447 466
448 467
449void 468void print_help (void) {
450print_help (void)
451{
452 469
453 print_revision (progname, NP_VERSION); 470 print_revision (progname, NP_VERSION);
454 471
@@ -474,6 +491,8 @@ print_help (void)
474 printf (" %s\n", _("warning threshold pair")); 491 printf (" %s\n", _("warning threshold pair"));
475 printf (" %s\n", "-c, --critical=THRESHOLD"); 492 printf (" %s\n", "-c, --critical=THRESHOLD");
476 printf (" %s\n", _("critical threshold pair")); 493 printf (" %s\n", _("critical threshold pair"));
494 printf (" %s\n", "-a, --alive");
495 printf (" %s\n", _("Return OK after first successful reply"));
477 printf (" %s\n", "-b, --bytes=INTEGER"); 496 printf (" %s\n", "-b, --bytes=INTEGER");
478 printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE); 497 printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE);
479 printf (" %s\n", "-n, --number=INTEGER"); 498 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..c4b4417 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);
@@ -380,11 +384,8 @@ process_arguments (int argc, char **argv)
380 community = strdup (DEFAULT_COMMUNITY); 384 community = strdup (DEFAULT_COMMUNITY);
381 } 385 }
382 386
383 if (port == NULL) { 387 if (port == 0) {
384 if (argv[c] != NULL ) 388 port = atoi(DEFAULT_PORT);
385 port = argv[c];
386 else
387 port = atoi (DEFAULT_PORT);
388 } 389 }
389 390
390 return validate_arguments (); 391 return validate_arguments ();
diff --git a/plugins/check_http.c b/plugins/check_http.c
index de59a06..8dda046 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,12 +70,12 @@ 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 {
74 REGS = 2, 77 REGS = 2,
75 MAX_RE_SIZE = 256 78 MAX_RE_SIZE = 1024
76}; 79};
77#include "regex.h" 80#include "regex.h"
78regex_t preg; 81regex_t preg;
@@ -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 succes, 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 */
@@ -484,7 +505,7 @@ process_arguments (int argc, char **argv)
484 if (errcode != 0) { 505 if (errcode != 0) {
485 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 506 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
486 printf (_("Could Not Compile Regular Expression: %s"), errbuf); 507 printf (_("Could Not Compile Regular Expression: %s"), errbuf);
487 return ERROR; 508 return false;
488 } 509 }
489 break; 510 break;
490 case INVERT_REGEX: 511 case INVERT_REGEX:
@@ -501,7 +522,7 @@ process_arguments (int argc, char **argv)
501#endif 522#endif
502 break; 523 break;
503 case 'v': /* verbose */ 524 case 'v': /* verbose */
504 verbose = TRUE; 525 verbose = true;
505 break; 526 break;
506 case 'm': /* min_page_length */ 527 case 'm': /* min_page_length */
507 { 528 {
@@ -526,7 +547,7 @@ process_arguments (int argc, char **argv)
526 break; 547 break;
527 } 548 }
528 case 'N': /* no-body */ 549 case 'N': /* no-body */
529 no_body = TRUE; 550 no_body = true;
530 break; 551 break;
531 case 'M': /* max-age */ 552 case 'M': /* max-age */
532 { 553 {
@@ -547,10 +568,10 @@ process_arguments (int argc, char **argv)
547 } 568 }
548 break; 569 break;
549 case 'E': /* show extended perfdata */ 570 case 'E': /* show extended perfdata */
550 show_extended_perfdata = TRUE; 571 show_extended_perfdata = true;
551 break; 572 break;
552 case 'B': /* print body content after status line */ 573 case 'B': /* print body content after status line */
553 show_body = TRUE; 574 show_body = true;
554 break; 575 break;
555 } 576 }
556 } 577 }
@@ -587,7 +608,7 @@ process_arguments (int argc, char **argv)
587 if (virtual_port == 0) 608 if (virtual_port == 0)
588 virtual_port = server_port; 609 virtual_port = server_port;
589 610
590 return TRUE; 611 return true;
591} 612}
592 613
593 614
@@ -927,10 +948,25 @@ check_http (void)
927 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */ 948 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */
928 949
929 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 950 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
930 && host_name != NULL && use_ssl == TRUE) { 951 && host_name != NULL && use_ssl == true) {
931 952
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); 953 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); 954 asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent);
955 if (strlen(proxy_auth)) {
956 base64_encode_alloc (proxy_auth, strlen (proxy_auth), &auth);
957 xasprintf (&buf, "%sProxy-Authorization: Basic %s\r\n", buf, auth);
958 }
959 /* optionally send any other header tag */
960 if (http_opt_headers_count) {
961 for (i = 0; i < http_opt_headers_count ; i++) {
962 if (force_host_header != http_opt_headers[i]) {
963 xasprintf (&buf, "%s%s\r\n", buf, http_opt_headers[i]);
964 }
965 }
966 /* This cannot be free'd here because a redirection will then try to access this and segfault */
967 /* Covered in a testcase in tests/check_http.t */
968 /* free(http_opt_headers); */
969 }
934 asprintf (&buf, "%sProxy-Connection: keep-alive\r\n", buf); 970 asprintf (&buf, "%sProxy-Connection: keep-alive\r\n", buf);
935 asprintf (&buf, "%sHost: %s\r\n", buf, host_name); 971 asprintf (&buf, "%sHost: %s\r\n", buf, host_name);
936 /* we finished our request, send empty line with CRLF */ 972 /* we finished our request, send empty line with CRLF */
@@ -946,7 +982,7 @@ check_http (void)
946 } 982 }
947#ifdef HAVE_SSL 983#ifdef HAVE_SSL
948 elapsed_time_connect = (double)microsec_connect / 1.0e6; 984 elapsed_time_connect = (double)microsec_connect / 1.0e6;
949 if (use_ssl == TRUE) { 985 if (use_ssl == true) {
950 gettimeofday (&tv_temp, NULL); 986 gettimeofday (&tv_temp, NULL);
951 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey); 987 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
952 if (verbose) printf ("SSL initialized\n"); 988 if (verbose) printf ("SSL initialized\n");
@@ -954,17 +990,19 @@ check_http (void)
954 die (STATE_CRITICAL, NULL); 990 die (STATE_CRITICAL, NULL);
955 microsec_ssl = deltime (tv_temp); 991 microsec_ssl = deltime (tv_temp);
956 elapsed_time_ssl = (double)microsec_ssl / 1.0e6; 992 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
957 if (check_cert == TRUE) { 993 if (check_cert == true) {
958 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 994 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
959 if (sd) close(sd); 995 if (continue_after_check_cert == false) {
960 np_net_ssl_cleanup(); 996 if (sd) close(sd);
961 return result; 997 np_net_ssl_cleanup();
998 return result;
999 }
962 } 1000 }
963 } 1001 }
964#endif /* HAVE_SSL */ 1002#endif /* HAVE_SSL */
965 1003
966 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 1004 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
967 && host_name != NULL && use_ssl == TRUE) 1005 && host_name != NULL && use_ssl == true)
968 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); 1006 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);
969 else 1007 else
970 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); 1008 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent);
@@ -992,10 +1030,10 @@ check_http (void)
992 * 14.23). Some server applications/configurations cause trouble if the 1030 * 14.23). Some server applications/configurations cause trouble if the
993 * (default) port is explicitly specified in the "Host:" header line. 1031 * (default) port is explicitly specified in the "Host:" header line.
994 */ 1032 */
995 if ((use_ssl == FALSE && virtual_port == HTTP_PORT) || 1033 if ((use_ssl == false && virtual_port == HTTP_PORT) ||
996 (use_ssl == TRUE && virtual_port == HTTPS_PORT) || 1034 (use_ssl == true && virtual_port == HTTPS_PORT) ||
997 (server_address != NULL && strcmp(http_method, "CONNECT") == 0 1035 (server_address != NULL && strcmp(http_method, "CONNECT") == 0
998 && host_name != NULL && use_ssl == TRUE)) 1036 && host_name != NULL && use_ssl == true))
999 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name); 1037 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name);
1000 else 1038 else
1001 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port); 1039 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port);
@@ -1035,9 +1073,8 @@ check_http (void)
1035 } 1073 }
1036 1074
1037 xasprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data)); 1075 xasprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data));
1038 xasprintf (&buf, "%s%s%s", buf, http_post_data, CRLF); 1076 xasprintf (&buf, "%s%s", buf, http_post_data);
1039 } 1077 } else {
1040 else {
1041 /* or just a newline so the server knows we're done with the request */ 1078 /* or just a newline so the server knows we're done with the request */
1042 xasprintf (&buf, "%s%s", buf, CRLF); 1079 xasprintf (&buf, "%s%s", buf, CRLF);
1043 } 1080 }
@@ -1061,9 +1098,14 @@ check_http (void)
1061 *pos = ' '; 1098 *pos = ' ';
1062 } 1099 }
1063 buffer[i] = '\0'; 1100 buffer[i] = '\0';
1064 xasprintf (&full_page_new, "%s%s", full_page, buffer); 1101
1065 free (full_page); 1102 if ((full_page_new = realloc(full_page, pagesize + i + 1)) == NULL)
1103 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate memory for full_page\n"));
1104
1105 memmove(&full_page_new[pagesize], buffer, i + 1);
1106
1066 full_page = full_page_new; 1107 full_page = full_page_new;
1108
1067 pagesize += i; 1109 pagesize += i;
1068 1110
1069 if (no_body && document_headers_done (full_page)) { 1111 if (no_body && document_headers_done (full_page)) {
@@ -1075,25 +1117,7 @@ check_http (void)
1075 elapsed_time_transfer = (double)microsec_transfer / 1.0e6; 1117 elapsed_time_transfer = (double)microsec_transfer / 1.0e6;
1076 1118
1077 if (i < 0 && errno != ECONNRESET) { 1119 if (i < 0 && errno != ECONNRESET) {
1078#ifdef HAVE_SSL 1120 die(STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1079 /*
1080 if (use_ssl) {
1081 sslerr=SSL_get_error(ssl, i);
1082 if ( sslerr == SSL_ERROR_SSL ) {
1083 die (STATE_WARNING, _("HTTP WARNING - Client Certificate Required\n"));
1084 } else {
1085 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1086 }
1087 }
1088 else {
1089 */
1090#endif
1091 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1092#ifdef HAVE_SSL
1093 /* XXX
1094 }
1095 */
1096#endif
1097 } 1121 }
1098 1122
1099 /* return a CRITICAL status if we couldn't read any data */ 1123 /* return a CRITICAL status if we couldn't read any data */
@@ -1218,32 +1242,73 @@ check_http (void)
1218 } 1242 }
1219 1243
1220 /* Page and Header content checks go here */ 1244 /* Page and Header content checks go here */
1221 if (strlen (header_expect)) { 1245 if (strlen(header_expect) > 0) {
1222 if (!strstr (header, header_expect)) { 1246 if (strstr(header, header_expect) == NULL) {
1223 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search)); 1247 // We did not find the header, the rest is for building the output and setting the state
1224 if(output_header_search[sizeof(output_header_search)-1]!='\0') { 1248 char output_header_search[30] = "";
1225 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4); 1249
1250 strncpy(&output_header_search[0], header_expect,
1251 sizeof(output_header_search));
1252
1253 if (output_header_search[sizeof(output_header_search) - 1] != '\0') {
1254 bcopy("...",
1255 &output_header_search[sizeof(output_header_search) - 4],
1256 4);
1226 } 1257 }
1227 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); 1258
1259 xasprintf (&msg,
1260 _("%sheader '%s' not found on '%s://%s:%d%s', "),
1261 msg,
1262 output_header_search, use_ssl ? "https" : "http",
1263 host_name ? host_name : server_address, server_port,
1264 server_url);
1265
1228 result = STATE_CRITICAL; 1266 result = STATE_CRITICAL;
1229 } 1267 }
1230 } 1268 }
1231 1269
1270 // At this point we should test if the content is chunked and unchunk it, so
1271 // it can be searched (and possibly printed)
1272 const char *chunked_header_regex_string = "Transfer-Encoding: *chunked *";
1273 regex_t chunked_header_regex;
1274
1275 if (regcomp(&chunked_header_regex, chunked_header_regex_string, REG_ICASE)) {
1276 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to compile chunked_header_regex regex");
1277 }
1278
1279 regmatch_t chre_pmatch[1]; // We actually do not care about this, since we only want to know IF it was found
1280
1281 if (regexec(&chunked_header_regex, header, 1, chre_pmatch, 0) == 0) {
1282 if (verbose) {
1283 printf("Found chunked content\n");
1284 }
1285 // We actually found the chunked header
1286 char *tmp = unchunk_content(page);
1287 if (tmp == NULL) {
1288 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to unchunk message body");
1289 }
1290 page = tmp;
1291 }
1232 1292
1233 if (strlen (string_expect)) { 1293 if (strlen(string_expect) > 0) {
1234 if (!strstr (page, string_expect)) { 1294 if (!strstr(page, string_expect)) {
1235 strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); 1295 // We found the string the body, the rest is for building the output
1236 if(output_string_search[sizeof(output_string_search)-1]!='\0') { 1296 char output_string_search[30] = "";
1237 bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); 1297 strncpy(&output_string_search[0], string_expect,
1298 sizeof(output_string_search));
1299 if (output_string_search[sizeof(output_string_search) - 1] != '\0') {
1300 bcopy("...", &output_string_search[sizeof(output_string_search) - 4],
1301 4);
1238 } 1302 }
1239 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); 1303 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);
1240 result = STATE_CRITICAL; 1304 result = STATE_CRITICAL;
1241 } 1305 }
1242 } 1306 }
1243 1307
1244 if (strlen (regexp)) { 1308 if (strlen(regexp) > 0) {
1245 errcode = regexec (&preg, page, REGS, pmatch, 0); 1309 errcode = regexec(&preg, page, REGS, pmatch, 0);
1246 if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { 1310 if ((errcode == 0 && invert_regex == 0) ||
1311 (errcode == REG_NOMATCH && invert_regex == 1)) {
1247 /* OK - No-op to avoid changing the logic around it */ 1312 /* OK - No-op to avoid changing the logic around it */
1248 result = max_state_alt(STATE_OK, result); 1313 result = max_state_alt(STATE_OK, result);
1249 } 1314 }
@@ -1295,7 +1360,7 @@ check_http (void)
1295 perfd_time (elapsed_time), 1360 perfd_time (elapsed_time),
1296 perfd_size (page_len), 1361 perfd_size (page_len),
1297 perfd_time_connect (elapsed_time_connect), 1362 perfd_time_connect (elapsed_time_connect),
1298 use_ssl == TRUE ? perfd_time_ssl (elapsed_time_ssl) : "", 1363 use_ssl == true ? perfd_time_ssl (elapsed_time_ssl) : "",
1299 perfd_time_headers (elapsed_time_headers), 1364 perfd_time_headers (elapsed_time_headers),
1300 perfd_time_firstbyte (elapsed_time_firstbyte), 1365 perfd_time_firstbyte (elapsed_time_firstbyte),
1301 perfd_time_transfer (elapsed_time_transfer)); 1366 perfd_time_transfer (elapsed_time_transfer));
@@ -1317,7 +1382,95 @@ check_http (void)
1317 return STATE_UNKNOWN; 1382 return STATE_UNKNOWN;
1318} 1383}
1319 1384
1385/* Receivces a pointer to the beginning of the body of a HTTP message
1386 * which is chunked and returns a pointer to a freshly allocated memory
1387 * region containing the unchunked body or NULL if something failed.
1388 * The result must be freed by the caller.
1389 */
1390char *unchunk_content(const char *content) {
1391 // https://en.wikipedia.org/wiki/Chunked_transfer_encoding
1392 // https://www.rfc-editor.org/rfc/rfc7230#section-4.1
1393 char *result = NULL;
1394 size_t content_length = strlen(content);
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 }
1320 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}
1321 1474
1322/* per RFC 2396 */ 1475/* per RFC 2396 */
1323#define URI_HTTP "%5[HTPShtps]" 1476#define URI_HTTP "%5[HTPShtps]"
@@ -1328,7 +1481,9 @@ check_http (void)
1328#define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH 1481#define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH
1329#define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT 1482#define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT
1330#define HD4 URI_HTTP "://" URI_HOST 1483#define HD4 URI_HTTP "://" URI_HOST
1331#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
1332 1487
1333void 1488void
1334redir (char *pos, char *status_line) 1489redir (char *pos, char *status_line)
@@ -1405,9 +1560,21 @@ redir (char *pos, char *status_line)
1405 use_ssl = server_type_check (type); 1560 use_ssl = server_type_check (type);
1406 i = server_port_check (use_ssl); 1561 i = server_port_check (use_ssl);
1407 } 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 }
1408 1575
1409 /* URI_PATH */ 1576 /* URI_PATH */
1410 else if (sscanf (pos, HD5, url) == 1) { 1577 else if (sscanf (pos, HD6, url) == 1) {
1411 /* relative url */ 1578 /* relative url */
1412 if ((url[0] != '/')) { 1579 if ((url[0] != '/')) {
1413 if ((x = strrchr(server_url, '/'))) 1580 if ((x = strrchr(server_url, '/')))
@@ -1438,8 +1605,8 @@ redir (char *pos, char *status_line)
1438 !strncmp(server_address, addr, MAX_IPV4_HOSTLENGTH) && 1605 !strncmp(server_address, addr, MAX_IPV4_HOSTLENGTH) &&
1439 (host_name && !strncmp(host_name, addr, MAX_IPV4_HOSTLENGTH)) && 1606 (host_name && !strncmp(host_name, addr, MAX_IPV4_HOSTLENGTH)) &&
1440 !strcmp(server_url, url)) 1607 !strcmp(server_url, url))
1441 die (STATE_WARNING, 1608 die (STATE_CRITICAL,
1442 _("HTTP WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"), 1609 _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"),
1443 type, addr, i, url, (display_html ? "</A>" : "")); 1610 type, addr, i, url, (display_html ? "</A>" : ""));
1444 1611
1445 strcpy (server_type, type); 1612 strcpy (server_type, type);
@@ -1476,13 +1643,13 @@ redir (char *pos, char *status_line)
1476} 1643}
1477 1644
1478 1645
1479int 1646bool
1480server_type_check (const char *type) 1647server_type_check (const char *type)
1481{ 1648{
1482 if (strcmp (type, "https")) 1649 if (strcmp (type, "https"))
1483 return FALSE; 1650 return false;
1484 else 1651 else
1485 return TRUE; 1652 return true;
1486} 1653}
1487 1654
1488int 1655int
@@ -1497,42 +1664,42 @@ server_port_check (int ssl_flag)
1497char *perfd_time (double elapsed_time) 1664char *perfd_time (double elapsed_time)
1498{ 1665{
1499 return fperfdata ("time", elapsed_time, "s", 1666 return fperfdata ("time", elapsed_time, "s",
1500 thlds->warning?TRUE:FALSE, thlds->warning?thlds->warning->end:0, 1667 thlds->warning?true:false, thlds->warning?thlds->warning->end:0,
1501 thlds->critical?TRUE:FALSE, thlds->critical?thlds->critical->end:0, 1668 thlds->critical?true:false, thlds->critical?thlds->critical->end:0,
1502 TRUE, 0, TRUE, socket_timeout); 1669 true, 0, true, socket_timeout);
1503} 1670}
1504 1671
1505char *perfd_time_connect (double elapsed_time_connect) 1672char *perfd_time_connect (double elapsed_time_connect)
1506{ 1673{
1507 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);
1508} 1675}
1509 1676
1510char *perfd_time_ssl (double elapsed_time_ssl) 1677char *perfd_time_ssl (double elapsed_time_ssl)
1511{ 1678{
1512 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);
1513} 1680}
1514 1681
1515char *perfd_time_headers (double elapsed_time_headers) 1682char *perfd_time_headers (double elapsed_time_headers)
1516{ 1683{
1517 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);
1518} 1685}
1519 1686
1520char *perfd_time_firstbyte (double elapsed_time_firstbyte) 1687char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1521{ 1688{
1522 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);
1523} 1690}
1524 1691
1525char *perfd_time_transfer (double elapsed_time_transfer) 1692char *perfd_time_transfer (double elapsed_time_transfer)
1526{ 1693{
1527 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);
1528} 1695}
1529 1696
1530char *perfd_size (int page_len) 1697char *perfd_size (int page_len)
1531{ 1698{
1532 return perfdata ("size", page_len, "B", 1699 return perfdata ("size", page_len, "B",
1533 (min_page_len>0?TRUE:FALSE), min_page_len, 1700 (min_page_len>0?true:false), min_page_len,
1534 (min_page_len>0?TRUE:FALSE), 0, 1701 (min_page_len>0?true:false), 0,
1535 TRUE, 0, FALSE, 0); 1702 true, 0, false, 0);
1536} 1703}
1537 1704
1538void 1705void
@@ -1552,6 +1719,10 @@ print_help (void)
1552 1719
1553 print_usage (); 1720 print_usage ();
1554 1721
1722#ifdef HAVE_SSL
1723 printf (_("In the first form, make an HTTP request."));
1724 printf (_("In the second form, connect to the server and check the TLS certificate."));
1725#endif
1555 printf (_("NOTE: One or both of -H and -I must be specified")); 1726 printf (_("NOTE: One or both of -H and -I must be specified"));
1556 1727
1557 printf ("\n"); 1728 printf ("\n");
@@ -1579,7 +1750,11 @@ print_help (void)
1579 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 1750 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
1580 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1751 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1581 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"));
1582 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."));
1583 printf (" %s\n", "-J, --client-cert=FILE"); 1758 printf (" %s\n", "-J, --client-cert=FILE");
1584 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)"));
1585 printf (" %s\n", _("to be used in establishing the SSL session")); 1760 printf (" %s\n", _("to be used in establishing the SSL session"));
@@ -1638,9 +1813,11 @@ print_help (void)
1638 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); 1813 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>");
1639 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"));
1640 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);
1641 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 1819 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
1642 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)"));
1643
1644 printf (UT_WARN_CRIT); 1821 printf (UT_WARN_CRIT);
1645 1822
1646 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1823 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
@@ -1711,6 +1888,8 @@ print_usage (void)
1711 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n"); 1888 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n");
1712 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");
1713 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");
1714 printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n"); 1891 printf (" [-A string] [-k string] [-S <version>] [--sni]\n");
1715 printf (" [-T <content-type>] [-j method]\n"); 1892 printf (" [-T <content-type>] [-j method]\n");
1893 printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname);
1894 printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n");
1716} 1895}
diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c
index bc7bd44..845a4f5 100644
--- a/plugins/check_ldap.c
+++ b/plugins/check_ldap.c
@@ -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 bf7b94b..00f7c87 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,7 +103,7 @@ 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
@@ -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("%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_query.c b/plugins/check_mysql_query.c
index 49a14dd..ac2fb15 100644
--- a/plugins/check_mysql_query.c
+++ b/plugins/check_mysql_query.c
@@ -136,18 +136,18 @@ main (int argc, char **argv)
136 die (STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error); 136 die (STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error);
137 } 137 }
138 138
139 /* free the result */
140 mysql_free_result (res);
141
142 /* close the connection */
143 mysql_close (&mysql);
144
145 if (! is_numeric(row[0])) { 139 if (! is_numeric(row[0])) {
146 die (STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]); 140 die (STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]);
147 } 141 }
148 142
149 value = strtod(row[0], NULL); 143 value = strtod(row[0], NULL);
150 144
145 /* free the result */
146 mysql_free_result (res);
147
148 /* close the connection */
149 mysql_close (&mysql);
150
151 if (verbose >= 3) 151 if (verbose >= 3)
152 printf("mysql result: %f\n", value); 152 printf("mysql result: %f\n", value);
153 153
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c
index 914b40c..8b776ba 100644
--- a/plugins/check_ntp.c
+++ b/plugins/check_ntp.c
@@ -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;
@@ -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_pgsql.c b/plugins/check_pgsql.c
index 11ce691..c26cd43 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;
@@ -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 strcpy (dbName, 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");
@@ -642,7 +611,13 @@ do_query (PGconn *conn, char *query)
642 : (my_status == STATE_CRITICAL) 611 : (my_status == STATE_CRITICAL)
643 ? _("CRITICAL") 612 ? _("CRITICAL")
644 : _("UNKNOWN")); 613 : _("UNKNOWN"));
645 printf (_("'%s' returned %f"), query, value); 614 if(pgqueryname) {
615 printf (_("%s returned %f"), pgqueryname, value);
616 }
617 else {
618 printf (_("'%s' returned %f"), query, value);
619 }
620
646 printf ("|query=%f;%s;%s;;\n", value, 621 printf ("|query=%f;%s;%s;;\n", value,
647 query_warning ? query_warning : "", 622 query_warning ? query_warning : "",
648 query_critical ? query_critical : ""); 623 query_critical ? query_critical : "");
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..a025ee8 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
@@ -230,9 +230,9 @@ main (int argc, char **argv)
230 procseconds = convert_to_seconds(procetime); 230 procseconds = convert_to_seconds(procetime);
231 231
232 if (verbose >= 3) 232 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", 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",
234 procs, procuid, procvsz, procrss, 234 procs, procuid, procvsz, procrss,
235 procpid, procppid, procpcpu, procstat, 235 procpid, procppid, procpcpu, procstat,
236 procetime, procprog, procargs); 236 procetime, procprog, procargs);
237 237
238 /* Ignore self */ 238 /* Ignore self */
@@ -265,7 +265,7 @@ main (int argc, char **argv)
265 } 265 }
266 } 266 }
267 267
268 if ((options & STAT) && (strstr (statopts, procstat))) 268 if ((options & STAT) && (strstr (procstat, statopts)))
269 resultsum |= STAT; 269 resultsum |= STAT;
270 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) 270 if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL))
271 resultsum |= ARGS; 271 resultsum |= ARGS;
@@ -292,9 +292,9 @@ main (int argc, char **argv)
292 292
293 procs++; 293 procs++;
294 if (verbose >= 2) { 294 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", 295 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, 296 procuid, procvsz, procrss,
297 procpid, procppid, procpcpu, procstat, 297 procpid, procppid, procpcpu, procstat,
298 procetime, procprog, procargs); 298 procetime, procprog, procargs);
299 } 299 }
300 300
@@ -320,7 +320,7 @@ main (int argc, char **argv)
320 result = max_state (result, i); 320 result = max_state (result, i);
321 } 321 }
322 } 322 }
323 } 323 }
324 /* This should not happen */ 324 /* This should not happen */
325 else if (verbose) { 325 else if (verbose) {
326 printf(_("Not parseable: %s"), input_buffer); 326 printf(_("Not parseable: %s"), input_buffer);
@@ -332,7 +332,7 @@ main (int argc, char **argv)
332 return STATE_UNKNOWN; 332 return STATE_UNKNOWN;
333 } 333 }
334 334
335 if ( result == STATE_UNKNOWN ) 335 if ( result == STATE_UNKNOWN )
336 result = STATE_OK; 336 result = STATE_OK;
337 337
338 /* Needed if procs found, but none match filter */ 338 /* Needed if procs found, but none match filter */
@@ -352,9 +352,9 @@ main (int argc, char **argv)
352 if (metric != METRIC_PROCS) { 352 if (metric != METRIC_PROCS) {
353 printf (_("%d crit, %d warn out of "), crit, warn); 353 printf (_("%d crit, %d warn out of "), crit, warn);
354 } 354 }
355 } 355 }
356 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); 356 printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs);
357 357
358 if (strcmp(fmt,"") != 0) { 358 if (strcmp(fmt,"") != 0) {
359 printf (_(" with %s"), fmt); 359 printf (_(" with %s"), fmt);
360 } 360 }
@@ -440,7 +440,7 @@ process_arguments (int argc, char **argv)
440 break; 440 break;
441 case 'c': /* critical threshold */ 441 case 'c': /* critical threshold */
442 critical_range = optarg; 442 critical_range = optarg;
443 break; 443 break;
444 case 'w': /* warning threshold */ 444 case 'w': /* warning threshold */
445 warning_range = optarg; 445 warning_range = optarg;
446 break; 446 break;
@@ -542,11 +542,11 @@ process_arguments (int argc, char **argv)
542 if ( strcmp(optarg, "PROCS") == 0) { 542 if ( strcmp(optarg, "PROCS") == 0) {
543 metric = METRIC_PROCS; 543 metric = METRIC_PROCS;
544 break; 544 break;
545 } 545 }
546 else if ( strcmp(optarg, "VSZ") == 0) { 546 else if ( strcmp(optarg, "VSZ") == 0) {
547 metric = METRIC_VSZ; 547 metric = METRIC_VSZ;
548 break; 548 break;
549 } 549 }
550 else if ( strcmp(optarg, "RSS") == 0 ) { 550 else if ( strcmp(optarg, "RSS") == 0 ) {
551 metric = METRIC_RSS; 551 metric = METRIC_RSS;
552 break; 552 break;
@@ -559,7 +559,7 @@ process_arguments (int argc, char **argv)
559 metric = METRIC_ELAPSED; 559 metric = METRIC_ELAPSED;
560 break; 560 break;
561 } 561 }
562 562
563 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); 563 usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
564 case 'k': /* linux kernel thread filter */ 564 case 'k': /* linux kernel thread filter */
565 kthread_filter = 1; 565 kthread_filter = 1;
@@ -642,7 +642,7 @@ convert_to_seconds(char *etime) {
642 seconds = 0; 642 seconds = 0;
643 643
644 for (ptr = etime; *ptr != '\0'; ptr++) { 644 for (ptr = etime; *ptr != '\0'; ptr++) {
645 645
646 if (*ptr == '-') { 646 if (*ptr == '-') {
647 hyphcnt++; 647 hyphcnt++;
648 continue; 648 continue;
@@ -775,7 +775,7 @@ be the total number of running processes\n\n"));
775 printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); 775 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")); 776 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"); 777 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%%")); 778 printf (" %s\n", _("Alert if CPU of any processes over 10\% or 20\%"));
779 779
780 printf (UT_SUPPORT); 780 printf (UT_SUPPORT);
781} 781}
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index d37c57c..c1e92df 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -55,6 +55,7 @@ enum {
55#define SMTP_EXPECT "220" 55#define SMTP_EXPECT "220"
56#define SMTP_HELO "HELO " 56#define SMTP_HELO "HELO "
57#define SMTP_EHLO "EHLO " 57#define SMTP_EHLO "EHLO "
58#define SMTP_LHLO "LHLO "
58#define SMTP_QUIT "QUIT\r\n" 59#define SMTP_QUIT "QUIT\r\n"
59#define SMTP_STARTTLS "STARTTLS\r\n" 60#define SMTP_STARTTLS "STARTTLS\r\n"
60#define SMTP_AUTH_LOGIN "AUTH LOGIN\r\n" 61#define SMTP_AUTH_LOGIN "AUTH LOGIN\r\n"
@@ -102,6 +103,7 @@ int check_critical_time = FALSE;
102int verbose = 0; 103int verbose = 0;
103int use_ssl = FALSE; 104int use_ssl = FALSE;
104short use_ehlo = FALSE; 105short use_ehlo = FALSE;
106short use_lhlo = FALSE;
105short ssl_established = 0; 107short ssl_established = 0;
106char *localhostname = NULL; 108char *localhostname = NULL;
107int sd; 109int sd;
@@ -152,7 +154,9 @@ main (int argc, char **argv)
152 return STATE_CRITICAL; 154 return STATE_CRITICAL;
153 } 155 }
154 } 156 }
155 if(use_ehlo) 157 if(use_lhlo)
158 xasprintf (&helocmd, "%s%s%s", SMTP_LHLO, localhostname, "\r\n");
159 else if(use_ehlo)
156 xasprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); 160 xasprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n");
157 else 161 else
158 xasprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); 162 xasprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n");
@@ -197,7 +201,7 @@ main (int argc, char **argv)
197 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { 201 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) {
198 printf (_("recv() failed\n")); 202 printf (_("recv() failed\n"));
199 return STATE_WARNING; 203 return STATE_WARNING;
200 } else if(use_ehlo){ 204 } else if(use_ehlo || use_lhlo){
201 if(strstr(buffer, "250 STARTTLS") != NULL || 205 if(strstr(buffer, "250 STARTTLS") != NULL ||
202 strstr(buffer, "250-STARTTLS") != NULL){ 206 strstr(buffer, "250-STARTTLS") != NULL){
203 supports_tls=TRUE; 207 supports_tls=TRUE;
@@ -470,6 +474,7 @@ process_arguments (int argc, char **argv)
470 {"use-ipv4", no_argument, 0, '4'}, 474 {"use-ipv4", no_argument, 0, '4'},
471 {"use-ipv6", no_argument, 0, '6'}, 475 {"use-ipv6", no_argument, 0, '6'},
472 {"help", no_argument, 0, 'h'}, 476 {"help", no_argument, 0, 'h'},
477 {"lmtp", no_argument, 0, 'L'},
473 {"starttls",no_argument,0,'S'}, 478 {"starttls",no_argument,0,'S'},
474 {"certificate",required_argument,0,'D'}, 479 {"certificate",required_argument,0,'D'},
475 {"ignore-quit-failure",no_argument,0,'q'}, 480 {"ignore-quit-failure",no_argument,0,'q'},
@@ -489,7 +494,7 @@ process_arguments (int argc, char **argv)
489 } 494 }
490 495
491 while (1) { 496 while (1) {
492 c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:F:A:U:P:q", 497 c = getopt_long (argc, argv, "+hVv46Lt:p:f:e:c:w:H:C:R:SD:F:A:U:P:q",
493 longopts, &option); 498 longopts, &option);
494 499
495 if (c == -1 || c == EOF) 500 if (c == -1 || c == EOF)
@@ -616,6 +621,9 @@ process_arguments (int argc, char **argv)
616 use_ssl = TRUE; 621 use_ssl = TRUE;
617 use_ehlo = TRUE; 622 use_ehlo = TRUE;
618 break; 623 break;
624 case 'L':
625 use_lhlo = TRUE;
626 break;
619 case '4': 627 case '4':
620 address_family = AF_INET; 628 address_family = AF_INET;
621 break; 629 break;
@@ -824,6 +832,8 @@ print_help (void)
824 printf (" %s\n", _("SMTP AUTH username")); 832 printf (" %s\n", _("SMTP AUTH username"));
825 printf (" %s\n", "-P, --authpass=STRING"); 833 printf (" %s\n", "-P, --authpass=STRING");
826 printf (" %s\n", _("SMTP AUTH password")); 834 printf (" %s\n", _("SMTP AUTH password"));
835 printf (" %s\n", "-L, --lmtp");
836 printf (" %s\n", _("Send LHLO instead of HELO/EHLO"));
827 printf (" %s\n", "-q, --ignore-quit-failure"); 837 printf (" %s\n", "-q, --ignore-quit-failure");
828 printf (" %s\n", _("Ignore failure when sending QUIT command to server")); 838 printf (" %s\n", _("Ignore failure when sending QUIT command to server"));
829 839
@@ -850,6 +860,6 @@ print_usage (void)
850 printf ("%s\n", _("Usage:")); 860 printf ("%s\n", _("Usage:"));
851 printf ("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname); 861 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"); 862 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"); 863 printf ("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-v] \n");
854} 864}
855 865
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index e8a21a4..d3968a2 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";
@@ -90,6 +90,7 @@ char *thisarg (char *str);
90char *nextarg (char *str); 90char *nextarg (char *str);
91void print_usage (void); 91void print_usage (void);
92void print_help (void); 92void print_help (void);
93char *multiply (char *str);
93 94
94#include "regex.h" 95#include "regex.h"
95char regex_expect[MAX_INPUT_BUFFER] = ""; 96char regex_expect[MAX_INPUT_BUFFER] = "";
@@ -113,6 +114,7 @@ char *authproto = NULL;
113char *privproto = NULL; 114char *privproto = NULL;
114char *authpasswd = NULL; 115char *authpasswd = NULL;
115char *privpasswd = NULL; 116char *privpasswd = NULL;
117int nulloid = STATE_UNKNOWN;
116char **oids = NULL; 118char **oids = NULL;
117size_t oids_size = 0; 119size_t oids_size = 0;
118char *label; 120char *label;
@@ -153,6 +155,8 @@ double *previous_value;
153size_t previous_size = OID_COUNT_STEP; 155size_t previous_size = OID_COUNT_STEP;
154int perf_labels = 1; 156int perf_labels = 1;
155char* ip_version = ""; 157char* ip_version = "";
158double multiplier = 1.0;
159char *fmtstr = "";
156 160
157static char *fix_snmp_range(char *th) 161static char *fix_snmp_range(char *th)
158{ 162{
@@ -315,7 +319,7 @@ main (int argc, char **argv)
315 for (i = 0; i < numcontext; i++) { 319 for (i = 0; i < numcontext; i++) {
316 command_line[10 + i] = contextargs[i]; 320 command_line[10 + i] = contextargs[i];
317 } 321 }
318 322
319 for (i = 0; i < numauthpriv; i++) { 323 for (i = 0; i < numauthpriv; i++) {
320 command_line[10 + numcontext + i] = authpriv[i]; 324 command_line[10 + numcontext + i] = authpriv[i];
321 } 325 }
@@ -329,7 +333,7 @@ main (int argc, char **argv)
329 333
330 for (i = 0; i < numoids; i++) { 334 for (i = 0; i < numoids; i++) {
331 command_line[10 + numcontext + numauthpriv + 1 + i] = oids[i]; 335 command_line[10 + numcontext + numauthpriv + 1 + i] = oids[i];
332 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]); 336 xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
333 } 337 }
334 338
335 command_line[10 + numcontext + numauthpriv + 1 + numoids] = NULL; 339 command_line[10 + numcontext + numauthpriv + 1 + numoids] = NULL;
@@ -375,7 +379,7 @@ main (int argc, char **argv)
375 } 379 }
376 } 380 }
377 381
378 for (line=0, i=0; line < chld_out.lines; line++, i++) { 382 for (line=0, i=0; line < chld_out.lines && i < numoids ; line++, i++) {
379 if(calculate_rate) 383 if(calculate_rate)
380 conv = "%.10g"; 384 conv = "%.10g";
381 else 385 else
@@ -397,15 +401,15 @@ main (int argc, char **argv)
397 is_counter=0; 401 is_counter=0;
398 /* We strip out the datatype indicator for PHBs */ 402 /* We strip out the datatype indicator for PHBs */
399 if (strstr (response, "Gauge: ")) { 403 if (strstr (response, "Gauge: ")) {
400 show = strstr (response, "Gauge: ") + 7; 404 show = multiply (strstr (response, "Gauge: ") + 7);
401 } 405 }
402 else if (strstr (response, "Gauge32: ")) { 406 else if (strstr (response, "Gauge32: ")) {
403 show = strstr (response, "Gauge32: ") + 9; 407 show = multiply (strstr (response, "Gauge32: ") + 9);
404 } 408 }
405 else if (strstr (response, "Counter32: ")) { 409 else if (strstr (response, "Counter32: ")) {
406 show = strstr (response, "Counter32: ") + 11; 410 show = strstr (response, "Counter32: ") + 11;
407 is_counter=1; 411 is_counter=1;
408 if(!calculate_rate) 412 if(!calculate_rate)
409 strcpy(type, "c"); 413 strcpy(type, "c");
410 } 414 }
411 else if (strstr (response, "Counter64: ")) { 415 else if (strstr (response, "Counter64: ")) {
@@ -415,7 +419,10 @@ main (int argc, char **argv)
415 strcpy(type, "c"); 419 strcpy(type, "c");
416 } 420 }
417 else if (strstr (response, "INTEGER: ")) { 421 else if (strstr (response, "INTEGER: ")) {
418 show = strstr (response, "INTEGER: ") + 9; 422 show = multiply (strstr (response, "INTEGER: ") + 9);
423 if (fmtstr != "") {
424 conv = fmtstr;
425 }
419 } 426 }
420 else if (strstr (response, "OID: ")) { 427 else if (strstr (response, "OID: ")) {
421 show = strstr (response, "OID: ") + 5; 428 show = strstr (response, "OID: ") + 5;
@@ -468,9 +475,20 @@ main (int argc, char **argv)
468 /* Process this block for numeric comparisons */ 475 /* Process this block for numeric comparisons */
469 /* Make some special values,like Timeticks numeric only if a threshold is defined */ 476 /* Make some special values,like Timeticks numeric only if a threshold is defined */
470 if (thlds[i]->warning || thlds[i]->critical || calculate_rate) { 477 if (thlds[i]->warning || thlds[i]->critical || calculate_rate) {
478 if (verbose > 2) {
479 print_thresholds(" thresholds", thlds[i]);
480 }
471 ptr = strpbrk (show, "-0123456789"); 481 ptr = strpbrk (show, "-0123456789");
472 if (ptr == NULL) 482 if (ptr == NULL){
473 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show); 483 if (nulloid == 3)
484 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show);
485 else if (nulloid == 0)
486 die (STATE_OK,_("No valid data returned (%s)\n"), show);
487 else if (nulloid == 1)
488 die (STATE_WARNING,_("No valid data returned (%s)\n"), show);
489 else if (nulloid == 2)
490 die (STATE_CRITICAL,_("No valid data returned (%s)\n"), show);
491 }
474 while (i >= response_size) { 492 while (i >= response_size) {
475 response_size += OID_COUNT_STEP; 493 response_size += OID_COUNT_STEP;
476 response_value = realloc(response_value, response_size * sizeof(*response_value)); 494 response_value = realloc(response_value, response_size * sizeof(*response_value));
@@ -576,20 +594,23 @@ main (int argc, char **argv)
576 len = sizeof(perfstr)-strlen(perfstr)-1; 594 len = sizeof(perfstr)-strlen(perfstr)-1;
577 strncat(perfstr, show, len>ptr-show ? ptr-show : len); 595 strncat(perfstr, show, len>ptr-show ? ptr-show : len);
578 596
597 if (type)
598 strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
599
579 if (warning_thresholds) { 600 if (warning_thresholds) {
580 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1); 601 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
581 strncat(perfstr, warning_thresholds, sizeof(perfstr)-strlen(perfstr)-1); 602 if(thlds[i]->warning && thlds[i]->warning->text)
603 strncat(perfstr, thlds[i]->warning->text, sizeof(perfstr)-strlen(perfstr)-1);
582 } 604 }
583 605
584 if (critical_thresholds) { 606 if (critical_thresholds) {
585 if (!warning_thresholds) 607 if (!warning_thresholds)
586 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1); 608 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
587 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1); 609 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
588 strncat(perfstr, critical_thresholds, sizeof(perfstr)-strlen(perfstr)-1); 610 if(thlds[i]->critical && thlds[i]->critical->text)
611 strncat(perfstr, thlds[i]->critical->text, sizeof(perfstr)-strlen(perfstr)-1);
589 } 612 }
590 613
591 if (type)
592 strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
593 strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1); 614 strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1);
594 } 615 }
595 } 616 }
@@ -601,7 +622,7 @@ main (int argc, char **argv)
601 state_string=malloc(string_length); 622 state_string=malloc(string_length);
602 if(state_string==NULL) 623 if(state_string==NULL)
603 die(STATE_UNKNOWN, _("Cannot malloc")); 624 die(STATE_UNKNOWN, _("Cannot malloc"));
604 625
605 current_length=0; 626 current_length=0;
606 for(i=0; i<total_oids; i++) { 627 for(i=0; i<total_oids; i++) {
607 xasprintf(&temp_string,"%.0f",response_value[i]); 628 xasprintf(&temp_string,"%.0f",response_value[i]);
@@ -623,7 +644,7 @@ main (int argc, char **argv)
623 state_string[--current_length]='\0'; 644 state_string[--current_length]='\0';
624 if (verbose > 2) 645 if (verbose > 2)
625 printf("State string=%s\n",state_string); 646 printf("State string=%s\n",state_string);
626 647
627 /* This is not strictly the same as time now, but any subtle variations will cancel out */ 648 /* This is not strictly the same as time now, but any subtle variations will cancel out */
628 np_state_write_string(current_time, state_string ); 649 np_state_write_string(current_time, state_string );
629 if(previous_state==NULL) { 650 if(previous_state==NULL) {
@@ -655,6 +676,7 @@ process_arguments (int argc, char **argv)
655 {"oid", required_argument, 0, 'o'}, 676 {"oid", required_argument, 0, 'o'},
656 {"object", required_argument, 0, 'o'}, 677 {"object", required_argument, 0, 'o'},
657 {"delimiter", required_argument, 0, 'd'}, 678 {"delimiter", required_argument, 0, 'd'},
679 {"nulloid", required_argument, 0, 'z'},
658 {"output-delimiter", required_argument, 0, 'D'}, 680 {"output-delimiter", required_argument, 0, 'D'},
659 {"string", required_argument, 0, 's'}, 681 {"string", required_argument, 0, 's'},
660 {"timeout", required_argument, 0, 't'}, 682 {"timeout", required_argument, 0, 't'},
@@ -682,6 +704,8 @@ process_arguments (int argc, char **argv)
682 {"perf-oids", no_argument, 0, 'O'}, 704 {"perf-oids", no_argument, 0, 'O'},
683 {"ipv4", no_argument, 0, '4'}, 705 {"ipv4", no_argument, 0, '4'},
684 {"ipv6", no_argument, 0, '6'}, 706 {"ipv6", no_argument, 0, '6'},
707 {"multiplier", required_argument, 0, 'M'},
708 {"fmtstr", required_argument, 0, 'f'},
685 {0, 0, 0, 0} 709 {0, 0, 0, 0}
686 }; 710 };
687 711
@@ -699,7 +723,7 @@ process_arguments (int argc, char **argv)
699 } 723 }
700 724
701 while (1) { 725 while (1) {
702 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:", 726 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:",
703 longopts, &option); 727 longopts, &option);
704 728
705 if (c == -1 || c == EOF) 729 if (c == -1 || c == EOF)
@@ -810,6 +834,12 @@ process_arguments (int argc, char **argv)
810 eval_method[j+1] |= CRIT_PRESENT; 834 eval_method[j+1] |= CRIT_PRESENT;
811 } 835 }
812 break; 836 break;
837 case 'z': /* Null OID Return Check */
838 if (!is_integer (optarg))
839 usage2 (_("Exit status must be a positive integer"), optarg);
840 else
841 nulloid = atoi(optarg);
842 break;
813 case 's': /* string or substring */ 843 case 's': /* string or substring */
814 strncpy (string_value, optarg, sizeof (string_value) - 1); 844 strncpy (string_value, optarg, sizeof (string_value) - 1);
815 string_value[sizeof (string_value) - 1] = 0; 845 string_value[sizeof (string_value) - 1] = 0;
@@ -931,6 +961,16 @@ process_arguments (int argc, char **argv)
931 if(verbose>2) 961 if(verbose>2)
932 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n"); 962 printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n");
933 break; 963 break;
964 case 'M':
965 if ( strspn( optarg, "0123456789.," ) == strlen( optarg ) ) {
966 multiplier=strtod(optarg,NULL);
967 }
968 break;
969 case 'f':
970 if (multiplier != 1.0) {
971 fmtstr=optarg;
972 }
973 break;
934 } 974 }
935 } 975 }
936 976
@@ -1000,7 +1040,7 @@ validate_arguments ()
1000 contextargs[0] = strdup ("-n"); 1040 contextargs[0] = strdup ("-n");
1001 contextargs[1] = strdup (context); 1041 contextargs[1] = strdup (context);
1002 } 1042 }
1003 1043
1004 if (seclevel == NULL) 1044 if (seclevel == NULL)
1005 xasprintf(&seclevel, "noAuthNoPriv"); 1045 xasprintf(&seclevel, "noAuthNoPriv");
1006 1046
@@ -1121,6 +1161,44 @@ nextarg (char *str)
1121 1161
1122 1162
1123 1163
1164/* multiply result (values 0 < n < 1 work as divider) */
1165char *
1166multiply (char *str)
1167{
1168 char *endptr;
1169 double val;
1170 char *conv = "%f";
1171
1172 if(verbose>2)
1173 printf(" multiply input: %s\n", str);
1174
1175 val = strtod (str, &endptr);
1176 if ((val == 0.0) && (endptr == str)) {
1177 if(multiplier != 1) {
1178 die(STATE_UNKNOWN, _("multiplier set (%.1f), but input is not a number: %s"), multiplier, str);
1179 }
1180 return str;
1181 }
1182
1183 if(verbose>2)
1184 printf(" multiply extracted double: %f\n", val);
1185 val *= multiplier;
1186 if (fmtstr != "") {
1187 conv = fmtstr;
1188 }
1189 if (val == (int)val) {
1190 sprintf(str, "%.0f", val);
1191 } else {
1192 if(verbose>2)
1193 printf(" multiply using format: %s\n", conv);
1194 sprintf(str, conv, val);
1195 }
1196 if(verbose>2)
1197 printf(" multiply result: %s\n", str);
1198 return str;
1199}
1200
1201
1124void 1202void
1125print_help (void) 1203print_help (void)
1126{ 1204{
@@ -1160,7 +1238,7 @@ print_help (void)
1160 printf ("(%s \"%s\")\n", _("default is") ,DEFAULT_COMMUNITY); 1238 printf ("(%s \"%s\")\n", _("default is") ,DEFAULT_COMMUNITY);
1161 printf (" %s\n", "-U, --secname=USERNAME"); 1239 printf (" %s\n", "-U, --secname=USERNAME");
1162 printf (" %s\n", _("SNMPv3 username")); 1240 printf (" %s\n", _("SNMPv3 username"));
1163 printf (" %s\n", "-A, --authpassword=PASSWORD"); 1241 printf (" %s\n", "-A, --authpasswd=PASSWORD");
1164 printf (" %s\n", _("SNMPv3 authentication password")); 1242 printf (" %s\n", _("SNMPv3 authentication password"));
1165 printf (" %s\n", "-X, --privpasswd=PASSWORD"); 1243 printf (" %s\n", "-X, --privpasswd=PASSWORD");
1166 printf (" %s\n", _("SNMPv3 privacy password")); 1244 printf (" %s\n", _("SNMPv3 privacy password"));
@@ -1175,6 +1253,14 @@ print_help (void)
1175 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER); 1253 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER);
1176 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered")); 1254 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered"));
1177 printf (" %s\n", _("to be the data that should be used in the evaluation.")); 1255 printf (" %s\n", _("to be the data that should be used in the evaluation."));
1256 printf (" %s\n", "-z, --nulloid=#");
1257 printf (" %s\n", _("If the check returns a 0 length string or NULL value"));
1258 printf (" %s\n", _("This option allows you to choose what status you want it to exit"));
1259 printf (" %s\n", _("Excluding this option renders the default exit of 3(STATE_UNKNOWN)"));
1260 printf (" %s\n", _("0 = OK"));
1261 printf (" %s\n", _("1 = WARNING"));
1262 printf (" %s\n", _("2 = CRITICAL"));
1263 printf (" %s\n", _("3 = UNKNOWN"));
1178 1264
1179 /* Tests Against Integers */ 1265 /* Tests Against Integers */
1180 printf (" %s\n", "-w, --warning=THRESHOLD(s)"); 1266 printf (" %s\n", "-w, --warning=THRESHOLD(s)");
@@ -1205,6 +1291,10 @@ print_help (void)
1205 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.').")); 1291 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.')."));
1206 printf (" %s\n", "-D, --output-delimiter=STRING"); 1292 printf (" %s\n", "-D, --output-delimiter=STRING");
1207 printf (" %s\n", _("Separates output on multiple OID requests")); 1293 printf (" %s\n", _("Separates output on multiple OID requests"));
1294 printf (" %s\n", "-M, --multiplier=FLOAT");
1295 printf (" %s\n", _("Multiplies current value, 0 < n < 1 works as divider, defaults to 1"));
1296 printf (" %s\n", "-f, --fmtstr=STRING");
1297 printf (" %s\n", _("C-style format string for float values (see option -M)"));
1208 1298
1209 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1299 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
1210 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5")); 1300 printf (" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5"));
@@ -1257,4 +1347,5 @@ print_usage (void)
1257 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n"); 1347 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n");
1258 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n"); 1348 printf ("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n");
1259 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n"); 1349 printf ("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n");
1350 printf ("[-M multiplier [-f format]]\n");
1260} 1351}
diff --git a/plugins/check_swap.c b/plugins/check_swap.c
index 0ff0c77..a607da1 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,6 +34,9 @@ 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>
37 40
38#ifdef HAVE_DECL_SWAPCTL 41#ifdef HAVE_DECL_SWAPCTL
39# ifdef HAVE_SYS_PARAM_H 42# ifdef HAVE_SYS_PARAM_H
@@ -51,16 +54,19 @@ const char *email = "devel@monitoring-plugins.org";
51# define SWAP_CONVERSION 1 54# define SWAP_CONVERSION 1
52#endif 55#endif
53 56
54int check_swap (int usp, float free_swap_mb, float total_swap_mb); 57typedef struct {
58 int is_percentage;
59 uint64_t value;
60} threshold_t;
61
62int check_swap (float free_swap_mb, float total_swap_mb);
55int process_arguments (int argc, char **argv); 63int process_arguments (int argc, char **argv);
56int validate_arguments (void); 64int validate_arguments (void);
57void print_usage (void); 65void print_usage (void);
58void print_help (void); 66void print_help (void);
59 67
60int warn_percent = 0; 68threshold_t warn;
61int crit_percent = 0; 69threshold_t crit;
62float warn_size_bytes = 0;
63float crit_size_bytes = 0;
64int verbose; 70int verbose;
65int allswaps; 71int allswaps;
66int no_swap_state = STATE_CRITICAL; 72int no_swap_state = STATE_CRITICAL;
@@ -68,9 +74,10 @@ int no_swap_state = STATE_CRITICAL;
68int 74int
69main (int argc, char **argv) 75main (int argc, char **argv)
70{ 76{
71 int percent_used, percent; 77 unsigned int percent_used, percent;
72 float total_swap_mb = 0, used_swap_mb = 0, free_swap_mb = 0; 78 uint64_t total_swap_mb = 0, used_swap_mb = 0, free_swap_mb = 0;
73 float dsktotal_mb = 0, dskused_mb = 0, dskfree_mb = 0, tmp_mb = 0; 79 uint64_t dsktotal_mb = 0, dskused_mb = 0, dskfree_mb = 0;
80 uint64_t tmp_KB = 0;
74 int result = STATE_UNKNOWN; 81 int result = STATE_UNKNOWN;
75 char input_buffer[MAX_INPUT_BUFFER]; 82 char input_buffer[MAX_INPUT_BUFFER];
76#ifdef HAVE_PROC_MEMINFO 83#ifdef HAVE_PROC_MEMINFO
@@ -116,10 +123,15 @@ main (int argc, char **argv)
116 } 123 }
117 fp = fopen (PROC_MEMINFO, "r"); 124 fp = fopen (PROC_MEMINFO, "r");
118 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) { 125 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
119 if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%*[:] %f %f %f", &dsktotal_mb, &dskused_mb, &dskfree_mb) == 3) { 126 /*
120 dsktotal_mb = dsktotal_mb / 1048576; /* Apply conversion */ 127 * The following sscanf call looks for a line looking like: "Swap: 123 123 123"
121 dskused_mb = dskused_mb / 1048576; 128 * On which kind of system this format exists, I can not say, but I wanted to
122 dskfree_mb = dskfree_mb / 1048576; 129 * document this for people who are not adapt with sscanf anymore, like me
130 */
131 if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%*[:] %lu %lu %lu", &dsktotal_mb, &dskused_mb, &dskfree_mb) == 3) {
132 dsktotal_mb = dsktotal_mb / (1024 * 1024); /* Apply conversion */
133 dskused_mb = dskused_mb / (1024 * 1024);
134 dskfree_mb = dskfree_mb / (1024 * 1024);
123 total_swap_mb += dsktotal_mb; 135 total_swap_mb += dsktotal_mb;
124 used_swap_mb += dskused_mb; 136 used_swap_mb += dskused_mb;
125 free_swap_mb += dskfree_mb; 137 free_swap_mb += dskfree_mb;
@@ -128,21 +140,29 @@ main (int argc, char **argv)
128 percent=100.0; 140 percent=100.0;
129 else 141 else
130 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb)); 142 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb));
131 result = max_state (result, check_swap (percent, dskfree_mb, dsktotal_mb)); 143 result = max_state (result, check_swap (dskfree_mb, dsktotal_mb));
132 if (verbose) 144 if (verbose)
133 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent); 145 xasprintf (&status, "%s [%lu (%d%%)]", status, dskfree_mb, 100 - percent);
134 } 146 }
135 } 147 }
136 else if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%[TotalFre]%*[:] %f %*[k]%*[B]", str, &tmp_mb)) { 148
149 /*
150 * The following sscanf call looks for lines looking like: "SwapTotal: 123" and "SwapFree: 123"
151 * This format exists at least on Debian Linux with a 5.* kernel
152 */
153 else if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu %*[k]%*[B]", str, &tmp_KB)) {
137 if (verbose >= 3) { 154 if (verbose >= 3) {
138 printf("Got %s with %f\n", str, tmp_mb); 155 printf("Got %s with %lu\n", str, tmp_KB);
139 } 156 }
140 /* I think this part is always in Kb, so convert to mb */ 157 /* I think this part is always in Kb, so convert to mb */
141 if (strcmp ("Total", str) == 0) { 158 if (strcmp ("Total", str) == 0) {
142 dsktotal_mb = tmp_mb / 1024; 159 dsktotal_mb = tmp_KB / 1024;
143 } 160 }
144 else if (strcmp ("Free", str) == 0) { 161 else if (strcmp ("Free", str) == 0) {
145 dskfree_mb = tmp_mb / 1024; 162 dskfree_mb = dskfree_mb + tmp_KB / 1024;
163 }
164 else if (strcmp ("Cached", str) == 0) {
165 dskfree_mb = dskfree_mb + tmp_KB / 1024;
146 } 166 }
147 } 167 }
148 } 168 }
@@ -227,7 +247,7 @@ main (int argc, char **argv)
227 free_swap_mb += dskfree_mb; 247 free_swap_mb += dskfree_mb;
228 if (allswaps) { 248 if (allswaps) {
229 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb)); 249 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb));
230 result = max_state (result, check_swap (percent, dskfree_mb, dsktotal_mb)); 250 result = max_state (result, check_swap (dskfree_mb, dsktotal_mb));
231 if (verbose) 251 if (verbose)
232 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent); 252 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent);
233 } 253 }
@@ -289,7 +309,7 @@ main (int argc, char **argv)
289 309
290 if(allswaps && dsktotal_mb > 0){ 310 if(allswaps && dsktotal_mb > 0){
291 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb)); 311 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb));
292 result = max_state (result, check_swap (percent, dskfree_mb, dsktotal_mb)); 312 result = max_state (result, check_swap (dskfree_mb, dsktotal_mb));
293 if (verbose) { 313 if (verbose) {
294 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent); 314 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent);
295 } 315 }
@@ -328,7 +348,7 @@ main (int argc, char **argv)
328 348
329 if(allswaps && dsktotal_mb > 0){ 349 if(allswaps && dsktotal_mb > 0){
330 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb)); 350 percent = 100 * (((double) dskused_mb) / ((double) dsktotal_mb));
331 result = max_state (result, check_swap (percent, dskfree_mb, dsktotal_mb)); 351 result = max_state (result, check_swap(dskfree_mb, dsktotal_mb));
332 if (verbose) { 352 if (verbose) {
333 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent); 353 xasprintf (&status, "%s [%.0f (%d%%)]", status, dskfree_mb, 100 - percent);
334 } 354 }
@@ -355,41 +375,55 @@ main (int argc, char **argv)
355 status = "- Swap is either disabled, not present, or of zero size. "; 375 status = "- Swap is either disabled, not present, or of zero size. ";
356 } 376 }
357 377
358 result = max_state (result, check_swap (percent_used, free_swap_mb, total_swap_mb)); 378 result = max_state (result, check_swap(free_swap_mb, total_swap_mb));
359 printf (_("SWAP %s - %d%% free (%d MB out of %d MB) %s|"), 379 printf (_("SWAP %s - %d%% free (%dMB out of %dMB) %s|"),
360 state_text (result), 380 state_text (result),
361 (100 - percent_used), (int) free_swap_mb, (int) total_swap_mb, status); 381 (100 - percent_used), (int) free_swap_mb, (int) total_swap_mb, status);
362 382
363 puts (perfdata ("swap", (long) free_swap_mb, "MB", 383 uint64_t warn_print = warn.value;
364 TRUE, (long) max (warn_size_bytes/(1024 * 1024), warn_percent/100.0*total_swap_mb), 384 if (warn.is_percentage) warn_print = warn.value * (total_swap_mb *1024 *1024/100);
365 TRUE, (long) max (crit_size_bytes/(1024 * 1024), crit_percent/100.0*total_swap_mb), 385 uint64_t crit_print = crit.value;
386 if (crit.is_percentage) crit_print = crit.value * (total_swap_mb *1024 *1024/100);
387
388 puts (perfdata_uint64 ("swap", free_swap_mb *1024 *1024, "B",
389 TRUE, warn_print,
390 TRUE, crit_print,
366 TRUE, 0, 391 TRUE, 0,
367 TRUE, (long) total_swap_mb)); 392 TRUE, (long) total_swap_mb * 1024 * 1024));
368 393
369 return result; 394 return result;
370} 395}
371 396
372 397
373
374int 398int
375check_swap (int usp, float free_swap_mb, float total_swap_mb) 399check_swap(float free_swap_mb, float total_swap_mb)
376{ 400{
377 401
378 if (!total_swap_mb) return no_swap_state; 402 if (!total_swap_mb) return no_swap_state;
379 403
380 int result = STATE_UNKNOWN; 404 uint64_t free_swap = free_swap_mb * (1024 * 1024); /* Convert back to bytes as warn and crit specified in bytes */
381 float free_swap = free_swap_mb * (1024 * 1024); /* Convert back to bytes as warn and crit specified in bytes */ 405
382 if (usp >= 0 && crit_percent != 0 && usp >= (100.0 - crit_percent)) 406 if (!crit.is_percentage && crit.value >= free_swap) return STATE_CRITICAL;
383 result = STATE_CRITICAL; 407 if (!warn.is_percentage && warn.value >= free_swap) return STATE_WARNING;
384 else if (crit_size_bytes > 0 && free_swap <= crit_size_bytes) 408
385 result = STATE_CRITICAL; 409
386 else if (usp >= 0 && warn_percent != 0 && usp >= (100.0 - warn_percent)) 410 uint64_t usage_percentage = ((total_swap_mb - free_swap_mb) / total_swap_mb) * 100;
387 result = STATE_WARNING; 411
388 else if (warn_size_bytes > 0 && free_swap <= warn_size_bytes) 412 if (crit.is_percentage &&
389 result = STATE_WARNING; 413 crit.value != 0 &&
390 else if (usp >= 0.0) 414 usage_percentage >= (100 - crit.value))
391 result = STATE_OK; 415 {
392 return result; 416 return STATE_CRITICAL;
417 }
418
419 if (warn.is_percentage &&
420 warn.value != 0 &&
421 usage_percentage >= (100 - warn.value))
422 {
423 return STATE_WARNING;
424 }
425
426 return STATE_OK;
393} 427}
394 428
395 429
@@ -422,42 +456,66 @@ process_arguments (int argc, char **argv)
422 break; 456 break;
423 457
424 switch (c) { 458 switch (c) {
425 case 'w': /* warning size threshold */ 459 case 'w': /* warning size threshold */
426 if (is_intnonneg (optarg)) { 460 {
427 warn_size_bytes = (float) atoi (optarg); 461 /*
428 break; 462 * We expect either a positive integer value without a unit, which means
429 } 463 * the unit is Bytes or a positive integer value and a percentage sign (%),
430 else if (strstr (optarg, ",") && 464 * which means the value must be with 0 and 100 and is relative to the total swap
431 strstr (optarg, "%") && 465 */
432 sscanf (optarg, "%f,%d%%", &warn_size_bytes, &warn_percent) == 2) { 466 size_t length;
433 warn_size_bytes = floorf(warn_size_bytes); 467 length = strlen(optarg);
434 break; 468
435 } 469 if (optarg[length - 1] == '%') {
436 else if (strstr (optarg, "%") && 470 /* It's percentage */
437 sscanf (optarg, "%d%%", &warn_percent) == 1) { 471 warn.is_percentage = 1;
438 break; 472 optarg[length - 1] = '\0';
439 } 473 if (is_uint64(optarg, &warn.value)) {
440 else { 474 if (warn.value > 100) {
441 usage4 (_("Warning threshold must be integer or percentage!")); 475 usage4 (_("Warning threshold percentage must be <= 100!"));
442 } 476 }
443 case 'c': /* critical size threshold */ 477 }
444 if (is_intnonneg (optarg)) { 478 break;
445 crit_size_bytes = (float) atoi (optarg); 479 } else {
446 break; 480 /* It's Bytes */
447 } 481 warn.is_percentage = 0;
448 else if (strstr (optarg, ",") && 482 if (is_uint64(optarg, &warn.value)) {
449 strstr (optarg, "%") && 483 break;
450 sscanf (optarg, "%f,%d%%", &crit_size_bytes, &crit_percent) == 2) { 484 } else {
451 crit_size_bytes = floorf(crit_size_bytes); 485 usage4 (_("Warning threshold be positive integer or percentage!"));
452 break; 486 }
453 } 487 }
454 else if (strstr (optarg, "%") &&
455 sscanf (optarg, "%d%%", &crit_percent) == 1) {
456 break;
457 }
458 else {
459 usage4 (_("Critical threshold must be integer or percentage!"));
460 } 488 }
489 case 'c': /* critical size threshold */
490 {
491 /*
492 * We expect either a positive integer value without a unit, which means
493 * the unit is Bytes or a positive integer value and a percentage sign (%),
494 * which means the value must be with 0 and 100 and is relative to the total swap
495 */
496 size_t length;
497 length = strlen(optarg);
498
499 if (optarg[length - 1] == '%') {
500 /* It's percentage */
501 crit.is_percentage = 1;
502 optarg[length - 1] = '\0';
503 if (is_uint64(optarg, &crit.value)) {
504 if (crit.value> 100) {
505 usage4 (_("Critical threshold percentage must be <= 100!"));
506 }
507 }
508 break;
509 } else {
510 /* It's Bytes */
511 crit.is_percentage = 0;
512 if (is_uint64(optarg, &crit.value)) {
513 break;
514 } else {
515 usage4 (_("Critical threshold be positive integer or percentage!"));
516 }
517 }
518 }
461 case 'a': /* all swap */ 519 case 'a': /* all swap */
462 allswaps = TRUE; 520 allswaps = TRUE;
463 break; 521 break;
@@ -465,6 +523,7 @@ process_arguments (int argc, char **argv)
465 if ((no_swap_state = mp_translate_state(optarg)) == ERROR) { 523 if ((no_swap_state = mp_translate_state(optarg)) == ERROR) {
466 usage4 (_("no-swap result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); 524 usage4 (_("no-swap result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)."));
467 } 525 }
526 break;
468 case 'v': /* verbose */ 527 case 'v': /* verbose */
469 verbose++; 528 verbose++;
470 break; 529 break;
@@ -482,23 +541,6 @@ process_arguments (int argc, char **argv)
482 c = optind; 541 c = optind;
483 if (c == argc) 542 if (c == argc)
484 return validate_arguments (); 543 return validate_arguments ();
485 if (warn_percent == 0 && is_intnonneg (argv[c]))
486 warn_percent = atoi (argv[c++]);
487
488 if (c == argc)
489 return validate_arguments ();
490 if (crit_percent == 0 && is_intnonneg (argv[c]))
491 crit_percent = atoi (argv[c++]);
492
493 if (c == argc)
494 return validate_arguments ();
495 if (warn_size_bytes == 0 && is_intnonneg (argv[c]))
496 warn_size_bytes = (float) atoi (argv[c++]);
497
498 if (c == argc)
499 return validate_arguments ();
500 if (crit_size_bytes == 0 && is_intnonneg (argv[c]))
501 crit_size_bytes = (float) atoi (argv[c++]);
502 544
503 return validate_arguments (); 545 return validate_arguments ();
504} 546}
@@ -508,17 +550,15 @@ process_arguments (int argc, char **argv)
508int 550int
509validate_arguments (void) 551validate_arguments (void)
510{ 552{
511 if (warn_percent == 0 && crit_percent == 0 && warn_size_bytes == 0 553 if (warn.value == 0 && crit.value == 0) {
512 && crit_size_bytes == 0) {
513 return ERROR; 554 return ERROR;
514 } 555 }
515 else if (warn_percent < crit_percent) { 556 else if ((warn.is_percentage == crit.is_percentage) && (warn.value < crit.value)) {
516 usage4 557 /* This is NOT triggered if warn and crit are different units, e.g warn is percentage
517 (_("Warning percentage should be more than critical percentage")); 558 * and crit is absolut. We cannot determine the condition at this point since we
518 } 559 * dont know the value of total swap yet
519 else if (warn_size_bytes < crit_size_bytes) { 560 */
520 usage4 561 usage4(_("Warning should be more than critical"));
521 (_("Warning free space should be more than critical free space"));
522 } 562 }
523 return OK; 563 return OK;
524} 564}
@@ -534,7 +574,7 @@ print_help (void)
534 574
535 printf ("%s\n", _("Check swap space on local machine.")); 575 printf ("%s\n", _("Check swap space on local machine."));
536 576
537 printf ("\n\n"); 577 printf ("\n\n");
538 578
539 print_usage (); 579 print_usage ();
540 580
@@ -542,33 +582,32 @@ print_help (void)
542 printf (UT_EXTRA_OPTS); 582 printf (UT_EXTRA_OPTS);
543 583
544 printf (" %s\n", "-w, --warning=INTEGER"); 584 printf (" %s\n", "-w, --warning=INTEGER");
545 printf (" %s\n", _("Exit with WARNING status if less than INTEGER bytes of swap space are free")); 585 printf (" %s\n", _("Exit with WARNING status if less than INTEGER bytes of swap space are free"));
546 printf (" %s\n", "-w, --warning=PERCENT%%"); 586 printf (" %s\n", "-w, --warning=PERCENT%");
547 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of swap space is free")); 587 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of swap space is free"));
548 printf (" %s\n", "-c, --critical=INTEGER"); 588 printf (" %s\n", "-c, --critical=INTEGER");
549 printf (" %s\n", _("Exit with CRITICAL status if less than INTEGER bytes of swap space are free")); 589 printf (" %s\n", _("Exit with CRITICAL status if less than INTEGER bytes of swap space are free"));
550 printf (" %s\n", "-c, --critical=PERCENT%%"); 590 printf (" %s\n", "-c, --critical=PERCENT%");
551 printf (" %s\n", _("Exit with CRITICAL status if less than PERCENT of swap space is free")); 591 printf (" %s\n", _("Exit with CRITICAL status if less than PERCENT of swap space is free"));
552 printf (" %s\n", "-a, --allswaps"); 592 printf (" %s\n", "-a, --allswaps");
553 printf (" %s\n", _("Conduct comparisons for all swap partitions, one by one")); 593 printf (" %s\n", _("Conduct comparisons for all swap partitions, one by one"));
554 printf (" %s\n", "-n, --no-swap=<ok|warning|critical|unknown>"); 594 printf (" %s\n", "-n, --no-swap=<ok|warning|critical|unknown>");
555 printf (" %s %s\n", _("Resulting state when there is no swap regardless of thresholds. Default:"), state_text(no_swap_state)); 595 printf (" %s %s\n", _("Resulting state when there is no swap regardless of thresholds. Default:"), state_text(no_swap_state));
556 printf (UT_VERBOSE); 596 printf (UT_VERBOSE);
557 597
558 printf ("\n"); 598 printf ("\n");
559 printf ("%s\n", _("Notes:")); 599 printf ("%s\n", _("Notes:"));
560 printf (" %s\n", _("Both INTEGER and PERCENT thresholds can be specified, they are all checked.")); 600 printf (" %s\n", _("Both INTEGER and PERCENT thresholds can be specified, they are all checked."));
561 printf (" %s\n", _("On AIX, if -a is specified, uses lsps -a, otherwise uses lsps -s.")); 601 printf (" %s\n", _("On AIX, if -a is specified, uses lsps -a, otherwise uses lsps -s."));
562 602
563 printf (UT_SUPPORT); 603 printf (UT_SUPPORT);
564} 604}
565 605
566 606
567
568void 607void
569print_usage (void) 608print_usage (void)
570{ 609{
571 printf ("%s\n", _("Usage:")); 610 printf ("%s\n", _("Usage:"));
572 printf (" %s [-av] -w <percent_free>%% -c <percent_free>%%\n",progname); 611 printf (" %s [-av] -w <percent_free>%% -c <percent_free>%%\n",progname);
573 printf (" -w <bytes_free> -c <bytes_free> [-n <state>]\n"); 612 printf (" -w <bytes_free> -c <bytes_free> [-n <state>]\n");
574} 613}
diff --git a/plugins/check_ups.c b/plugins/check_ups.c
index e9e56a5..0de37a2 100644
--- a/plugins/check_ups.c
+++ b/plugins/check_ups.c
@@ -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
diff --git a/plugins/picohttpparser/picohttpparser.c b/plugins/picohttpparser/picohttpparser.c
index 74ccc3e..d9680b7 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,6 +395,7 @@ 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
@@ -400,7 +405,7 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si
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 */
@@ -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/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/NPTest.cache.travis b/plugins/t/NPTest.cache.travis
deleted file mode 100644
index 9b9f805..0000000
--- a/plugins/t/NPTest.cache.travis
+++ /dev/null
@@ -1,54 +0,0 @@
1{
2 'NP_ALLOW_SUDO' => 'yes',
3 'NP_DNS_SERVER' => '8.8.8.8',
4 'NP_GOOD_NTP_SERVICE' => '',
5 'NP_HOST_DHCP_RESPONSIVE' => '',
6 'NP_HOST_HPJD_PORT_INVALID' => '161',
7 'NP_HOST_HPJD_PORT_VALID' => '',
8 'NP_HOSTNAME_INVALID_CIDR' => '130.133.8.39/30',
9 'NP_HOSTNAME_INVALID' => 'nosuchhost',
10 'NP_HOSTNAME_VALID_CIDR' => '130.133.8.41/30',
11 'NP_HOSTNAME_VALID_IP' => '130.133.8.40',
12 'NP_HOSTNAME_VALID' => 'monitoring-plugins.org',
13 'NP_HOSTNAME_VALID_REVERSE' => 'orwell.monitoring-plugins.org.',
14 'NP_HOST_NONRESPONSIVE' => '10.0.0.1',
15 'NP_HOST_RESPONSIVE' => 'localhost',
16 'NP_HOST_SMB' => '',
17 'NP_HOST_SNMP' => '',
18 'NP_HOST_TCP_FTP' => '',
19 'NP_HOST_TCP_HPJD' => '',
20 'NP_HOST_TCP_HTTP2' => 'test.monitoring-plugins.org',
21 'NP_HOST_TCP_HTTP' => 'localhost',
22 'NP_HOST_TCP_IMAP' => 'imap.web.de',
23 'NP_HOST_TCP_JABBER' => 'jabber.org',
24 'NP_HOST_TCP_LDAP' => 'localhost',
25 'NP_HOST_TCP_POP' => 'pop.web.de',
26 'NP_HOST_TCP_PROXY' => 'localhost',
27 'NP_HOST_TCP_SMTP' => 'localhost',
28 'NP_HOST_TCP_SMTP_NOTLS' => '',
29 'NP_HOST_TCP_SMTP_TLS' => '',
30 'NP_HOST_TLS_CERT' => 'localhost,
31 'NP_HOST_TLS_HTTP' => 'localhost',
32 'NP_HOST_UDP_TIME' => 'none',
33 'NP_INTERNET_ACCESS' => 'yes',
34 'NP_LDAP_BASE_DN' => 'cn=admin,dc=nodomain',
35 'NP_MOUNTPOINT2_VALID' => '/media/ramdisk',
36 'NP_MOUNTPOINT_VALID' => '/',
37 'NP_MYSQL_LOGIN_DETAILS' => '-u root -d test',
38 'NP_MYSQL_SERVER' => 'localhost',
39 'NP_MYSQL_SOCKET' => '/var/run/mysqld/mysqld.sock',
40 'NP_MYSQL_WITH_SLAVE' => '',
41 'NP_MYSQL_WITH_SLAVE_LOGIN' => '',
42 'NP_NO_NTP_SERVICE' => 'localhost',
43 'NP_PORT_TCP_PROXY' => '3128',
44 'NP_SMB_SHARE' => '',
45 'NP_SMB_SHARE_DENY' => '',
46 'NP_SMB_SHARE_SPC' => '',
47 'NP_SMB_VALID_USER' => '',
48 'NP_SMB_VALID_USER_PASS' => '',
49 'NP_SNMP_COMMUNITY' => '',
50 'NP_SNMP_USER' => '',
51 'NP_SSH_CONFIGFILE' => '~/.ssh/config',
52 'NP_SSH_HOST' => 'localhost',
53 'NP_SSH_IDENTITY' => '~/.ssh/id_rsa'
54}
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t
index 4bff538..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 => 57; 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,32 +39,41 @@ 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?!)
49cmp_ok( $res->output, 'eq', "HTTP CRITICAL - Invalid HTTP response received from host on port 80: cURL returned 28 - Timeout was reached", "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
57# Is also possible to get a socket timeout if DNS is not responding fast enough 74# Is also possible to get a socket timeout if DNS is not responding fast enough
58# cURL gives us consistent strings from it's own 'lib/strerror.c' 75# cURL gives us consistent strings from it's own 'lib/strerror.c'
59like( $res->output, "/cURL returned 6 - Couldn't resolve host name/", "Output OK"); 76like( $res->output, "/cURL returned 6 - Could not resolve host:/", "Output OK");
60 77
61# host header checks 78# host header checks
62$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http"); 79$res = NPTest->testCmd("./$plugin -v -H $host_tcp_http");
@@ -84,7 +101,7 @@ like( $res->output, '/^Host: testhost:8001\s*$/ms', "Host Header OK" );
84like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" ); 101like( $res->output, '/CURLOPT_URL: http:\/\/'.$host_tcp_http.':80\//ms', "Url OK" );
85 102
86SKIP: { 103SKIP: {
87 skip "No internet access", 3 if $internet_access eq "no"; 104 skip "No internet access", 4 if $internet_access eq "no";
88 105
89 $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -S"); 106 $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -S");
90 like( $res->output, '/^Host: '.$host_tls_http.'\s*$/ms', "Host Header OK" ); 107 like( $res->output, '/^Host: '.$host_tls_http.'\s*$/ms', "Host Header OK" );
@@ -94,6 +111,9 @@ SKIP: {
94 111
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" );
114
115 $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -D -S -p 443");
116 like( $res->output, '/(^Host: '.$host_tls_http.'\s*$)|(cURL returned 60)/ms', "Host Header OK" );
97}; 117};
98 118
99SKIP: { 119SKIP: {
@@ -117,7 +137,7 @@ SKIP: {
117 cmp_ok( $res->return_code, "==", 0, "And also when not found"); 137 cmp_ok( $res->return_code, "==", 0, "And also when not found");
118} 138}
119SKIP: { 139SKIP: {
120 skip "No internet access", 16 if $internet_access eq "no"; 140 skip "No internet access", 28 if $internet_access eq "no";
121 141
122 $res = NPTest->testCmd( 142 $res = NPTest->testCmd(
123 "./$plugin --ssl $host_tls_http" 143 "./$plugin --ssl $host_tls_http"
@@ -185,13 +205,7 @@ SKIP: {
185 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); 205 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
186 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' );
187 207
188 $res = NPTest->testCmd( 208 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f curl" );
189 "./$plugin --ssl -H www.e-paycobalt.com"
190 );
191 cmp_ok( $res->return_code, "==", 0, "Can read https for www.e-paycobalt.com (uses AES certificate)" );
192
193
194 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f follow" );
195 is( $res->return_code, 0, "Redirection based on location is okay"); 209 is( $res->return_code, 0, "Redirection based on location is okay");
196 210
197 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com --extended-perfdata" ); 211 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com --extended-perfdata" );
diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t
index fdd8769..ec527e7 100644
--- a/plugins/t/check_disk.t
+++ b/plugins/t/check_disk.t
@@ -88,8 +88,9 @@ $result = NPTest->testCmd(
88 ); 88 );
89$_ = $result->perf_output; 89$_ = $result->perf_output;
90my ($warn_absth_data, $crit_absth_data, $total_absth_data) = (m/=.[^;]*;(\d+);(\d+);\d+;(\d+)/); 90my ($warn_absth_data, $crit_absth_data, $total_absth_data) = (m/=.[^;]*;(\d+);(\d+);\d+;(\d+)/);
91is ($warn_absth_data, $total_absth_data - 20, "Wrong warning in perf data using absolute thresholds"); 91# default unit is MiB, but perfdata is always bytes
92is ($crit_absth_data, $total_absth_data - 10, "Wrong critical in perf data using absolute thresholds"); 92is ($warn_absth_data, $total_absth_data - (20 * (2 ** 20)), "Wrong warning in perf data using absolute thresholds");
93is ($crit_absth_data, $total_absth_data - (10 * (2 ** 20)), "Wrong critical in perf data using absolute thresholds");
93 94
94# Then check percent thresholds. 95# Then check percent thresholds.
95$result = NPTest->testCmd( 96$result = NPTest->testCmd(
@@ -119,7 +120,7 @@ like ( $result->only_output, qr/$more_free/, "Have disk name in text");
119$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free -p $less_free" ); 120$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free -p $less_free" );
120cmp_ok( $result->return_code, '==', 0, "At least 1 MB available on $more_free and $less_free"); 121cmp_ok( $result->return_code, '==', 0, "At least 1 MB available on $more_free and $less_free");
121$_ = $result->output; 122$_ = $result->output;
122my ($free_mb_on_mp1, $free_mb_on_mp2) = (m/(\d+) MB .* (\d+) MB /g); 123my ($free_mb_on_mp1, $free_mb_on_mp2) = (m/(\d+)MiB .* (\d+)MiB /g);
123my $free_mb_on_all = $free_mb_on_mp1 + $free_mb_on_mp2; 124my $free_mb_on_all = $free_mb_on_mp1 + $free_mb_on_mp2;
124 125
125 126
diff --git a/plugins/t/check_dns.t b/plugins/t/check_dns.t
index cdfbe60..afb2062 100644
--- a/plugins/t/check_dns.t
+++ b/plugins/t/check_dns.t
@@ -10,7 +10,7 @@ use NPTest;
10 10
11plan skip_all => "check_dns not compiled" unless (-x "check_dns"); 11plan skip_all => "check_dns not compiled" unless (-x "check_dns");
12 12
13plan tests => 19; 13plan tests => 23;
14 14
15my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/'; 15my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/';
16 16
@@ -105,3 +105,11 @@ cmp_ok( $res->return_code, '==', 0, "Got expected address");
105$res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5"); 105$res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5");
106cmp_ok( $res->return_code, '==', 2, "Got wrong address"); 106cmp_ok( $res->return_code, '==', 2, "Got wrong address");
107like ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK"); 107like ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK");
108
109$res = NPTest->testCmd("./check_dns -H $hostname_valid -n");
110cmp_ok( $res->return_code, '==', 2, "Found $hostname_valid");
111like ( $res->output, "/^DNS CRITICAL.*Domain '$hostname_valid' was found by the server:/", "Output OK");
112
113$res = NPTest->testCmd("./check_dns -H $hostname_invalid -n");
114cmp_ok( $res->return_code, '==', 0, "Did not find $hostname_invalid");
115like ( $res->output, $successOutput, "Output OK" );
diff --git a/plugins/t/check_fping.t b/plugins/t/check_fping.t
index 342b0a7..67b357b 100644
--- a/plugins/t/check_fping.t
+++ b/plugins/t/check_fping.t
@@ -5,34 +5,30 @@
5# 5#
6 6
7use strict; 7use strict;
8use Test; 8use Test::More;
9use NPTest; 9use NPTest;
10 10
11use vars qw($tests);
12
13BEGIN {$tests = 4; plan tests => $tests}
14
15my $successOutput = '/^FPING OK - /';
16my $failureOutput = '/^FPING CRITICAL - /';
17
18my $host_responsive = getTestParameter("NP_HOST_RESPONSIVE", "The hostname of system responsive to network requests", "localhost"); 11my $host_responsive = getTestParameter("NP_HOST_RESPONSIVE", "The hostname of system responsive to network requests", "localhost");
19my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1"); 12my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1");
20my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); 13my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost");
21 14
22my $t; 15my $res;
23 16
24my $fping = qx(which fping 2> /dev/null); 17my $fping = qx(which fping 2> /dev/null);
25chomp($fping); 18chomp($fping);
26if( ! -x "./check_fping") { 19if( ! -x "./check_fping") {
27 $t += skipMissingCmd( "./check_fping", $tests ); 20 plan skip_all => "check_fping not found, skipping tests";
28} 21}
29elsif ( $> != 0 && (!$fping || ! -u $fping)) { 22elsif ( !$fping || !-x $fping ) {
30 $t += skipMsg( "./check_fping", $tests ); 23 plan skip_all => "fping not found or cannot be executed, skipping tests";
31} else { 24} else {
32 $t += checkCmd( "./check_fping $host_responsive", 0, $successOutput ); 25 plan tests => 3;
33 $t += checkCmd( "./check_fping $host_nonresponsive", [ 1, 2 ] ); 26 $res = NPTest->testCmd( "./check_fping $host_responsive" );
34 $t += checkCmd( "./check_fping $hostname_invalid", [ 1, 2 ] ); 27 cmp_ok( $res->return_code, '==', 0, "Responsive host returns OK");
35} 28
29 $res = NPTest->testCmd( "./check_fping $host_nonresponsive" );
30 cmp_ok( $res->return_code, '==', 2, "Non-Responsive host returns Critical");
36 31
37exit(0) if defined($Test::Harness::VERSION); 32 $res = NPTest->testCmd( "./check_fping $hostname_invalid" );
38exit($tests - $t); 33 cmp_ok( $res->return_code, '==', 3, "Invalid host returns Unknown");
34}
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t
index e92681e..1ca52f6 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", 16 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"
@@ -135,7 +135,7 @@ SKIP: {
135 135
136 # run some certificate checks with faketime 136 # run some certificate checks with faketime
137 SKIP: { 137 SKIP: {
138 skip "No faketime binary found", 12 if !$faketime; 138 skip "No faketime binary found", 7 if !$faketime;
139 $res = NPTest->testCmd("LC_TIME=C TZ=UTC ./$plugin -C 1 $host_tls_http"); 139 $res = NPTest->testCmd("LC_TIME=C TZ=UTC ./$plugin -C 1 $host_tls_http");
140 like($res->output, qr/OK - Certificate '$host_tls_cert' will expire on/, "Catch cert output"); 140 like($res->output, qr/OK - Certificate '$host_tls_cert' will expire on/, "Catch cert output");
141 is( $res->return_code, 0, "Catch cert output exit code" ); 141 is( $res->return_code, 0, "Catch cert output exit code" );
@@ -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
diff --git a/plugins/t/check_load.t b/plugins/t/check_load.t
index 55f6f75..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 = "/^OK - load average: $loadValue, $loadValue, $loadValue/"; 14my $successOutput = "/^LOAD OK - total load average: $loadValue, $loadValue, $loadValue/";
15my $failureOutput = "/^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_swap.t b/plugins/t/check_swap.t
index e44adc9..de9e0f0 100644
--- a/plugins/t/check_swap.t
+++ b/plugins/t/check_swap.t
@@ -8,9 +8,9 @@ use strict;
8use Test::More tests => 8; 8use Test::More tests => 8;
9use NPTest; 9use NPTest;
10 10
11my $successOutput = '/^SWAP OK - [0-9]+\% free \([0-9]+ MB out of [0-9]+ MB\)/'; 11my $successOutput = '/^SWAP OK - [0-9]+\% free \([0-9]+MB out of [0-9]+MB\)/';
12my $failureOutput = '/^SWAP CRITICAL - [0-9]+\% free \([0-9]+ MB out of [0-9]+ MB\)/'; 12my $failureOutput = '/^SWAP CRITICAL - [0-9]+\% free \([0-9]+MB out of [0-9]+MB\)/';
13my $warnOutput = '/^SWAP WARNING - [0-9]+\% free \([0-9]+ MB out of [0-9]+ MB\)/'; 13my $warnOutput = '/^SWAP WARNING - [0-9]+\% free \([0-9]+MB out of [0-9]+MB\)/';
14 14
15my $result; 15my $result;
16 16
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 1afbe4b..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 = 70; 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;";
@@ -126,8 +126,6 @@ if ($pid) {
126 exit; 126 exit;
127 } 127 }
128 } 128 }
129 # give our webservers some time to startup
130 sleep(1);
131} else { 129} else {
132 # Child 130 # Child
133 #print "child\n"; 131 #print "child\n";
@@ -140,6 +138,9 @@ if ($pid) {
140 exit; 138 exit;
141} 139}
142 140
141# give our webservers some time to startup
142sleep(3);
143
143# Run the same server on http and https 144# Run the same server on http and https
144sub run_server { 145sub run_server {
145 my $d = shift; 146 my $d = shift;
@@ -188,11 +189,25 @@ sub run_server {
188 $c->send_basic_header; 189 $c->send_basic_header;
189 $c->send_header('foo'); 190 $c->send_header('foo');
190 $c->send_crlf; 191 $c->send_crlf;
192 } elsif ($r->url->path eq "/header_broken_check") {
193 $c->send_basic_header;
194 $c->send_header('foo');
195 print $c "Test1:: broken\n";
196 print $c " Test2: leading whitespace\n";
197 $c->send_crlf;
191 } elsif ($r->url->path eq "/virtual_port") { 198 } elsif ($r->url->path eq "/virtual_port") {
192 # return sent Host header 199 # return sent Host header
193 $c->send_basic_header; 200 $c->send_basic_header;
194 $c->send_crlf; 201 $c->send_crlf;
195 $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 }));
196 } else { 211 } else {
197 $c->send_error(HTTP::Status->RC_FORBIDDEN); 212 $c->send_error(HTTP::Status->RC_FORBIDDEN);
198 } 213 }
@@ -221,23 +236,25 @@ SKIP: {
221 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};
222 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 237 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
223 238
239 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
240
224 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 241 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
225 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" );
226 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" );
227 244
228 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 245 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
229 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" );
230 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" );
231 248
232 # Expired cert tests 249 # Expired cert tests
233 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 250 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
234 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" );
235 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" );
236 253
237 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 254 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
238 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" );
239 is( $result->output, 256 is( $result->output,
240 '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.',
241 "output ok" ); 258 "output ok" );
242 259
243} 260}
@@ -247,7 +264,7 @@ my $cmd;
247# advanced checks with virtual hostname and virtual port 264# advanced checks with virtual hostname and virtual port
248SKIP: { 265SKIP: {
249 skip "libcurl version is smaller than $required_version", 6 unless $use_advanced_checks; 266 skip "libcurl version is smaller than $required_version", 6 unless $use_advanced_checks;
250 267
251 # http without virtual port 268 # http without virtual port
252 $cmd = "./$plugin -H $virtual_host -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host:$port_http\$"; 269 $cmd = "./$plugin -H $virtual_host -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host:$port_http\$";
253 $result = NPTest->testCmd( $cmd ); 270 $result = NPTest->testCmd( $cmd );
@@ -259,7 +276,7 @@ SKIP: {
259 $result = NPTest->testCmd( $cmd ); 276 $result = NPTest->testCmd( $cmd );
260 is( $result->return_code, 0, $cmd); 277 is( $result->return_code, 0, $cmd);
261 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); 278 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
262 279
263 # http with virtual port (80) 280 # http with virtual port (80)
264 $cmd = "./$plugin -H $virtual_host:80 -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host\$"; 281 $cmd = "./$plugin -H $virtual_host:80 -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host\$";
265 $result = NPTest->testCmd( $cmd ); 282 $result = NPTest->testCmd( $cmd );
@@ -321,6 +338,10 @@ sub run_common_tests {
321 is( $result->return_code, 2, "Missing header string check"); 338 is( $result->return_code, 2, "Missing header string check");
322 like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location"); 339 like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location");
323 340
341 $result = NPTest->testCmd( "$command -u /header_broken_check" );
342 is( $result->return_code, 0, "header_check search for string");
343 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 138 bytes in [\d\.]+ second/', "Output correct" );
344
324 my $cmd; 345 my $cmd;
325 $cmd = "$command -u /slow"; 346 $cmd = "$command -u /slow";
326 $result = NPTest->testCmd( $cmd ); 347 $result = NPTest->testCmd( $cmd );
@@ -459,7 +480,8 @@ sub run_common_tests {
459 local $SIG{ALRM} = sub { die "alarm\n" }; 480 local $SIG{ALRM} = sub { die "alarm\n" };
460 alarm(2); 481 alarm(2);
461 $result = NPTest->testCmd( $cmd ); 482 $result = NPTest->testCmd( $cmd );
462 alarm(0); }; 483 };
484 alarm(0);
463 isnt( $@, "alarm\n", $cmd ); 485 isnt( $@, "alarm\n", $cmd );
464 is( $result->return_code, 0, $cmd ); 486 is( $result->return_code, 0, $cmd );
465 487
@@ -469,7 +491,8 @@ sub run_common_tests {
469 local $SIG{ALRM} = sub { die "alarm\n" }; 491 local $SIG{ALRM} = sub { die "alarm\n" };
470 alarm(2); 492 alarm(2);
471 $result = NPTest->testCmd( $cmd ); 493 $result = NPTest->testCmd( $cmd );
472 alarm(0); }; 494 };
495 alarm(0);
473 isnt( $@, "alarm\n", $cmd ); 496 isnt( $@, "alarm\n", $cmd );
474 isnt( $result->return_code, 0, $cmd ); 497 isnt( $result->return_code, 0, $cmd );
475 498
@@ -495,4 +518,9 @@ sub run_common_tests {
495 }; 518 };
496 is( $@, "", $cmd ); 519 is( $@, "", $cmd );
497 520
521 $cmd = "$command -u /chunked -s 'chunkedencodingtest' -d 'Transfer-Encoding: chunked'";
522 eval {
523 $result = NPTest->testCmd( $cmd, 5 );
524 };
525 is( $@, "", $cmd );
498} 526}
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 2f051fa..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,124 +52,217 @@ $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 my $d = HTTP::Daemon::SSL->new(
95 LocalPort => $port_https,
96 LocalAddr => "127.0.0.1",
97 SSL_cert_file => "$Bin/certs/server-cert.pem",
98 SSL_key_file => "$Bin/certs/server-key.pem",
99 ) || die;
100 print "Please contact https at: <URL:", $d->url, ">\n";
101 run_server( $d );
102 exit;
103 }
104 }
105 # give our webservers some time to startup
106 sleep(1);
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";
117} 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;
159}
160
161# give our webservers some time to startup
162sleep(3);
118 163
119# Run the same server on http and https 164# Run the same server on http and https
120sub run_server { 165sub run_server {
121 my $d = shift; 166 my $d = shift;
122 MAINLOOP: while (my $c = $d->accept ) { 167 while (1) {
123 while (my $r = $c->get_request) { 168 MAINLOOP: while (my $c = $d->accept) {
124 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) { 169 while (my $r = $c->get_request) {
125 $c->send_basic_header($1); 170 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) {
126 $c->send_crlf; 171 $c->send_basic_header($1);
127 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) { 172 $c->send_crlf;
128 $c->send_basic_header; 173 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) {
129 $c->send_crlf; 174 $c->send_basic_header;
130 $c->send_file_response("$Bin/var/$1"); 175 $c->send_crlf;
131 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") { 176 $c->send_file_response("$Bin/var/$1");
132 $c->send_basic_header; 177 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") {
133 $c->send_crlf; 178 $c->send_basic_header;
134 sleep 1; 179 $c->send_crlf;
135 $c->send_response("slow"); 180 sleep 1;
136 } elsif ($r->url->path eq "/method") { 181 $c->send_response("slow");
137 if ($r->method eq "DELETE") { 182 } elsif ($r->url->path eq "/method") {
138 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED); 183 if ($r->method eq "DELETE") {
139 } elsif ($r->method eq "foo") { 184 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED);
140 $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 }));
141 } else { 226 } else {
142 $c->send_status_line(200, $r->method); 227 $c->send_error(HTTP::Status->RC_FORBIDDEN);
143 } 228 }
144 } elsif ($r->url->path eq "/postdata") { 229 $c->close;
145 $c->send_basic_header;
146 $c->send_crlf;
147 $c->send_response($r->method.":".$r->content);
148 } elsif ($r->url->path eq "/redirect") {
149 $c->send_redirect( "/redirect2" );
150 } elsif ($r->url->path eq "/redir_external") {
151 $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" );
152 } elsif ($r->url->path eq "/redirect2") {
153 $c->send_basic_header;
154 $c->send_crlf;
155 $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' ));
156 } elsif ($r->url->path eq "/redir_timeout") {
157 $c->send_redirect( "/timeout" );
158 } elsif ($r->url->path eq "/timeout") {
159 # Keep $c from being destroyed, but prevent severe leaks
160 unshift @persist, $c;
161 delete($persist[1000]);
162 next MAINLOOP;
163 } elsif ($r->url->path eq "/header_check") {
164 $c->send_basic_header;
165 $c->send_header('foo');
166 $c->send_crlf;
167 } elsif ($r->url->path eq "/virtual_port") {
168 # return sent Host header
169 $c->send_basic_header;
170 $c->send_crlf;
171 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
172 } else {
173 $c->send_error(HTTP::Status->RC_FORBIDDEN);
174 } 230 }
175 $c->close;
176 } 231 }
177 } 232 }
178} 233}
179 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
180END { 266END {
181 foreach my $pid (@pids) { 267 foreach my $pid (@pids) {
182 if ($pid) { print "Killing $pid\n"; kill "INT", $pid } 268 if ($pid) { print "Killing $pid\n"; kill "INT", $pid }
@@ -192,30 +278,50 @@ if ($ARGV[0] && $ARGV[0] eq "-d") {
192my $result; 278my $result;
193my $command = "./$plugin -H 127.0.0.1"; 279my $command = "./$plugin -H 127.0.0.1";
194 280
281run_chunked_encoding_special_test( {command => "$command -p $port_hacked_http"});
195run_common_tests( { command => "$command -p $port_http" } ); 282run_common_tests( { command => "$command -p $port_http" } );
196SKIP: { 283SKIP: {
197 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};
198 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 285 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
199 286
287 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
288
200 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 289 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
201 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" );
202 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" );
203 292
204 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 293 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
205 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" );
206 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" );
207 296
208 # Expired cert tests 297 # Expired cert tests
209 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 298 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
210 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" );
211 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" );
212 301
213 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 302 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
214 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" );
215 is( $result->output, 304 is( $result->output,
216 '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.',
217 "output ok" ); 306 "output ok" );
218 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 );
219} 325}
220 326
221my $cmd; 327my $cmd;
@@ -414,22 +520,24 @@ sub run_common_tests {
414 520
415 # stickyport - on full urlS port is set back to 80 otherwise 521 # stickyport - on full urlS port is set back to 80 otherwise
416 $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected"; 522 $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected";
523 alarm(2);
417 eval { 524 eval {
418 local $SIG{ALRM} = sub { die "alarm\n" }; 525 local $SIG{ALRM} = sub { die "alarm\n" };
419 alarm(2);
420 $result = NPTest->testCmd( $cmd ); 526 $result = NPTest->testCmd( $cmd );
421 alarm(0); }; 527 };
422 isnt( $@, "alarm\n", $cmd ); 528 isnt( $@, "alarm\n", $cmd );
529 alarm(0);
423 is( $result->return_code, 0, $cmd ); 530 is( $result->return_code, 0, $cmd );
424 531
425 # Let's hope there won't be any web server on :80 returning "redirected"! 532 # Let's hope there won't be any web server on :80 returning "redirected"!
426 $cmd = "$command -f sticky -u /redir_external -t 5 -s redirected"; 533 $cmd = "$command -f sticky -u /redir_external -t 5 -s redirected";
534 alarm(2);
427 eval { 535 eval {
428 local $SIG{ALRM} = sub { die "alarm\n" }; 536 local $SIG{ALRM} = sub { die "alarm\n" };
429 alarm(2);
430 $result = NPTest->testCmd( $cmd ); 537 $result = NPTest->testCmd( $cmd );
431 alarm(0); }; 538 };
432 isnt( $@, "alarm\n", $cmd ); 539 isnt( $@, "alarm\n", $cmd );
540 alarm(0);
433 isnt( $result->return_code, 0, $cmd ); 541 isnt( $result->return_code, 0, $cmd );
434 542
435 # Test an external address - timeout 543 # Test an external address - timeout
@@ -454,4 +562,20 @@ sub run_common_tests {
454 }; 562 };
455 is( $@, "", $cmd ); 563 is( $@, "", $cmd );
456 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 );
457} 581}
diff --git a/plugins/tests/check_procs.t b/plugins/tests/check_procs.t
index 54d43d9..3af218f 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 => 52;
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" );
@@ -69,9 +70,21 @@ SKIP: {
69 like( $result->output, '/^PROCS OK: 0 processes with UID = -2 \(nobody\), args \'UsB\'/', "Output correct" ); 70 like( $result->output, '/^PROCS OK: 0 processes with UID = -2 \(nobody\), args \'UsB\'/', "Output correct" );
70}; 71};
71 72
72$result = NPTest->testCmd( "$command --ereg-argument-array='mdworker.*501'" ); 73SKIP: {
73is( $result->return_code, 0, "Checking regexp search of arguments" ); 74 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" ); 75
76 $result = NPTest->testCmd( "$command --ereg-argument-array='mdworker.*501'" );
77 is( $result->return_code, 0, "Checking regexp search of arguments" );
78 is( $result->output, "PROCS OK: 1 process with regex args 'mdworker.*501' | procs=1;;;0;", "Output correct" );
79}
80
81SKIP: {
82 skip 'check_procs is compiled without etime format support', 2 if `$cmd_etime -vvv` !~ m/etime/mx;
83
84 $result = NPTest->testCmd( "$cmd_etime -m ELAPSED -C apache2 -w 1000 -c 2000" );
85 is( $result->return_code, 2, "Checking elapsed time threshold" );
86 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" );
87}
75 88
76$result = NPTest->testCmd( "$command --vsz 1000000" ); 89$result = NPTest->testCmd( "$command --vsz 1000000" );
77is( $result->return_code, 0, "Checking filter by VSZ" ); 90is( $result->return_code, 0, "Checking filter by VSZ" );
@@ -83,7 +96,7 @@ is( $result->output, 'PROCS OK: 3 processes with RSS >= 100000 | procs=3;;;0;',
83 96
84$result = NPTest->testCmd( "$command -s S" ); 97$result = NPTest->testCmd( "$command -s S" );
85is( $result->return_code, 0, "Checking filter for sleeping processes" ); 98is( $result->return_code, 0, "Checking filter for sleeping processes" );
86like( $result->output, '/^PROCS OK: 44 processes with STATE = S/', "Output correct" ); 99like( $result->output, '/^PROCS OK: 88 processes with STATE = S/', "Output correct" );
87 100
88$result = NPTest->testCmd( "$command -s Z" ); 101$result = NPTest->testCmd( "$command -s Z" );
89is( $result->return_code, 0, "Checking filter for zombies" ); 102is( $result->return_code, 0, "Checking filter for zombies" );
@@ -129,4 +142,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)'" ); 142$result = NPTest->testCmd( "$command --ereg-argument-array='(nosuchname|nosuch2name)'" );
130is( $result->return_code, 0, "Checking no pipe symbol in output" ); 143is( $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" ); 144is( $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..bc03ec6 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;
@@ -57,9 +57,9 @@ if ($pid) {
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
@@ -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 348ec02..b4214c6 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -27,6 +27,8 @@
27#include "utils_base.h" 27#include "utils_base.h"
28#include <stdarg.h> 28#include <stdarg.h>
29#include <limits.h> 29#include <limits.h>
30#include <string.h>
31#include <errno.h>
30 32
31#include <arpa/inet.h> 33#include <arpa/inet.h>
32 34
@@ -239,6 +241,46 @@ is_intnonneg (char *number)
239 return FALSE; 241 return FALSE;
240} 242}
241 243
244/*
245 * Checks whether the number in the string _number_ can be put inside a int64_t
246 * On success the number will be written to the _target_ address, if _target_ is not set
247 * to NULL.
248 */
249int is_int64(char *number, int64_t *target) {
250 errno = 0;
251 uint64_t tmp = strtoll(number, NULL, 10);
252 if (errno != 0) {
253 return 0;
254 }
255 if (tmp < INT64_MIN || tmp > INT64_MAX) {
256 return 0;
257 }
258 if (target != NULL) {
259 *target = tmp;
260 }
261 return 1;
262}
263
264/*
265 * Checks whether the number in the string _number_ can be put inside a uint64_t
266 * On success the number will be written to the _target_ address, if _target_ is not set
267 * to NULL.
268 */
269int is_uint64(char *number, uint64_t *target) {
270 errno = 0;
271 uint64_t tmp = strtoll(number, NULL, 10);
272 if (errno != 0) {
273 return 0;
274 }
275 if (tmp < 0 || tmp > UINT64_MAX) {
276 return 0;
277 }
278 if (target != NULL) {
279 *target = tmp;
280 }
281 return 1;
282}
283
242int 284int
243is_intpercent (char *number) 285is_intpercent (char *number)
244{ 286{
@@ -547,10 +589,94 @@ char *perfdata (const char *label,
547 xasprintf (&data, "%s;", data); 589 xasprintf (&data, "%s;", data);
548 590
549 if (minp) 591 if (minp)
550 xasprintf (&data, "%s%ld", data, minv); 592 xasprintf (&data, "%s%ld;", data, minv);
593 else
594 xasprintf (&data, "%s;", data);
595
596 if (maxp)
597 xasprintf (&data, "%s%ld", data, maxv);
598
599 return data;
600}
601
602
603char *perfdata_uint64 (const char *label,
604 uint64_t val,
605 const char *uom,
606 int warnp, /* Warning present */
607 uint64_t warn,
608 int critp, /* Critical present */
609 uint64_t crit,
610 int minp, /* Minimum present */
611 uint64_t minv,
612 int maxp, /* Maximum present */
613 uint64_t maxv)
614{
615 char *data = NULL;
616
617 if (strpbrk (label, "'= "))
618 xasprintf (&data, "'%s'=%" PRIu64 "%s;", label, val, uom);
619 else
620 xasprintf (&data, "%s=%" PRIu64 "%s;", label, val, uom);
621
622 if (warnp)
623 xasprintf (&data, "%s%" PRIu64 ";", data, warn);
624 else
625 xasprintf (&data, "%s;", data);
626
627 if (critp)
628 xasprintf (&data, "%s%" PRIu64 ";", data, crit);
629 else
630 xasprintf (&data, "%s;", data);
631
632 if (minp)
633 xasprintf (&data, "%s%" PRIu64 ";", data, minv);
634 else
635 xasprintf (&data, "%s;", data);
636
637 if (maxp)
638 xasprintf (&data, "%s%" PRIu64, data, maxv);
639
640 return data;
641}
642
643
644char *perfdata_int64 (const char *label,
645 int64_t val,
646 const char *uom,
647 int warnp, /* Warning present */
648 int64_t warn,
649 int critp, /* Critical present */
650 int64_t crit,
651 int minp, /* Minimum present */
652 int64_t minv,
653 int maxp, /* Maximum present */
654 int64_t maxv)
655{
656 char *data = NULL;
657
658 if (strpbrk (label, "'= "))
659 xasprintf (&data, "'%s'=%" PRId64 "%s;", label, val, uom);
660 else
661 xasprintf (&data, "%s=%" PRId64 "%s;", label, val, uom);
662
663 if (warnp)
664 xasprintf (&data, "%s%" PRId64 ";", data, warn);
665 else
666 xasprintf (&data, "%s;", data);
667
668 if (critp)
669 xasprintf (&data, "%s%" PRId64 ";", data, crit);
670 else
671 xasprintf (&data, "%s;", data);
672
673 if (minp)
674 xasprintf (&data, "%s%" PRId64 ";", data, minv);
675 else
676 xasprintf (&data, "%s;", data);
551 677
552 if (maxp) 678 if (maxp)
553 xasprintf (&data, "%s;%ld", data, maxv); 679 xasprintf (&data, "%s%" PRId64, data, maxv);
554 680
555 return data; 681 return data;
556} 682}
diff --git a/plugins/utils.h b/plugins/utils.h
index 33a2054..5b54da3 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -16,6 +16,7 @@ suite of plugins. */
16/* now some functions etc are being defined in ../lib/utils_base.c */ 16/* now some functions etc are being defined in ../lib/utils_base.c */
17#include "utils_base.h" 17#include "utils_base.h"
18 18
19
19#ifdef NP_EXTRA_OPTS 20#ifdef NP_EXTRA_OPTS
20/* Include extra-opts functions if compiled in */ 21/* Include extra-opts functions if compiled in */
21#include "extra_opts.h" 22#include "extra_opts.h"
@@ -38,6 +39,8 @@ int is_intpos (char *);
38int is_intneg (char *); 39int is_intneg (char *);
39int is_intnonneg (char *); 40int is_intnonneg (char *);
40int is_intpercent (char *); 41int is_intpercent (char *);
42int is_uint64(char *number, uint64_t *target);
43int is_int64(char *number, int64_t *target);
41 44
42int is_numeric (char *); 45int is_numeric (char *);
43int is_positive (char *); 46int is_positive (char *);
@@ -88,6 +91,12 @@ void usage_va(const char *fmt, ...) __attribute__((noreturn));
88char *perfdata (const char *, long int, const char *, int, long int, 91char *perfdata (const char *, long int, const char *, int, long int,
89 int, long int, int, long int, int, long int); 92 int, long int, int, long int, int, long int);
90 93
94char *perfdata_uint64 (const char *, uint64_t , const char *, int, uint64_t,
95 int, uint64_t, int, uint64_t, int, uint64_t);
96
97char *perfdata_int64 (const char *, int64_t, const char *, int, int64_t,
98 int, int64_t, int, int64_t, int, int64_t);
99
91char *fperfdata (const char *, double, const char *, int, double, 100char *fperfdata (const char *, double, const char *, int, double,
92 int, double, int, double, int, double); 101 int, double, int, double, int, double);
93 102