summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/codeql-analysis.yml5
-rw-r--r--configure.ac1
-rw-r--r--doc/developer-guidelines.sgml146
-rw-r--r--plugins-root/check_icmp.c83
-rw-r--r--plugins-root/t/check_icmp.t13
-rw-r--r--[-rwxr-xr-x]plugins-scripts/check_disk_smb.pl21
-rwxr-xr-xplugins-scripts/check_mailq.pl18
-rwxr-xr-xplugins-scripts/check_uptime.pl17
-rw-r--r--plugins-scripts/t/check_uptime.t22
-rw-r--r--plugins/check_by_ssh.c32
-rw-r--r--plugins/check_curl.c48
-rw-r--r--plugins/check_disk.c8
-rw-r--r--plugins/check_fping.c37
-rw-r--r--plugins/check_http.c42
-rw-r--r--plugins/check_pgsql.c17
-rw-r--r--plugins/check_ping.c55
-rw-r--r--plugins/check_procs.c2
-rw-r--r--plugins/check_snmp.c32
-rw-r--r--plugins/check_swap.c24
-rw-r--r--plugins/picohttpparser/picohttpparser.c30
-rw-r--r--plugins/picohttpparser/picohttpparser.h4
-rw-r--r--plugins/sslutils.c2
-rw-r--r--plugins/t/check_curl.t7
-rw-r--r--plugins/t/check_http.t8
-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.t10
-rwxr-xr-xplugins/tests/check_http.t256
41 files changed, 972 insertions, 442 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 9de367e..afe6ab4 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -53,6 +53,7 @@ jobs:
53 53
54 - name: Install packages 54 - name: Install packages
55 run: | 55 run: |
56 sudo apt update
56 sudo apt-get install -y --no-install-recommends m4 gettext automake autoconf make build-essential 57 sudo apt-get install -y --no-install-recommends m4 gettext automake autoconf make build-essential
57 sudo apt-get install -y --no-install-recommends perl autotools-dev libdbi-dev libldap2-dev libpq-dev \ 58 sudo apt-get install -y --no-install-recommends perl autotools-dev libdbi-dev libldap2-dev libpq-dev \
58 libmysqlclient-dev libradcli-dev libkrb5-dev libdbi0-dev \ 59 libmysqlclient-dev libradcli-dev libkrb5-dev libdbi0-dev \
@@ -62,10 +63,10 @@ jobs:
62 run: | 63 run: |
63 ./tools/setup 64 ./tools/setup
64 ./configure --enable-libtap 65 ./configure --enable-libtap
65 66
66 - name: Build 67 - name: Build
67 run: | 68 run: |
68 make 69 make
69 70
70 - name: Perform CodeQL Analysis 71 - name: Perform CodeQL Analysis
71 uses: github/codeql-action/analyze@v1 72 uses: github/codeql-action/analyze@v2
diff --git a/configure.ac b/configure.ac
index dfc37b5..8c5ca70 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,6 +5,7 @@ AC_CONFIG_SRCDIR(NPTest.pm)
5AC_CONFIG_FILES([gl/Makefile]) 5AC_CONFIG_FILES([gl/Makefile])
6AC_CONFIG_AUX_DIR(build-aux) 6AC_CONFIG_AUX_DIR(build-aux)
7AM_INIT_AUTOMAKE([1.8.3]) 7AM_INIT_AUTOMAKE([1.8.3])
8AM_SILENT_RULES([yes])
8AM_MAINTAINER_MODE([enable]) 9AM_MAINTAINER_MODE([enable])
9AC_CONFIG_HEADERS([config.h]) 10AC_CONFIG_HEADERS([config.h])
10AC_CANONICAL_HOST 11AC_CANONICAL_HOST
diff --git a/doc/developer-guidelines.sgml b/doc/developer-guidelines.sgml
index 6f31f36..28674e0 100644
--- a/doc/developer-guidelines.sgml
+++ b/doc/developer-guidelines.sgml
@@ -13,7 +13,7 @@
13 13
14 <pubdate>2013</pubdate> 14 <pubdate>2013</pubdate>
15 <title>Monitoring Plugins Development Guidelines</title> 15 <title>Monitoring Plugins Development Guidelines</title>
16 16
17 <revhistory> 17 <revhistory>
18 <revision> 18 <revision>
19 <revnumber>1796</revnumber> 19 <revnumber>1796</revnumber>
@@ -72,14 +72,14 @@
72</section> 72</section>
73 73
74<section id="PlugOutput"><title>Plugin Output for Nagios</title> 74<section id="PlugOutput"><title>Plugin Output for Nagios</title>
75 75
76 <para>You should always print something to STDOUT that tells if the 76 <para>You should always print something to STDOUT that tells if the
77 service is working or why it is failing. Try to keep the output short - 77 service is working or why it is failing. Try to keep the output short -
78 probably less that 80 characters. Remember that you ideally would like 78 probably less that 80 characters. Remember that you ideally would like
79 the entire output to appear in a pager message, which will get chopped 79 the entire output to appear in a pager message, which will get chopped
80 off after a certain length.</para> 80 off after a certain length.</para>
81 81
82 <para>As Nagios does not capture stderr output, you should only output to 82 <para>As Nagios does not capture stderr output, you should only output to
83 STDOUT and not print to STDERR.</para> 83 STDOUT and not print to STDERR.</para>
84 84
85 <section><title>Print only one line of text</title> 85 <section><title>Print only one line of text</title>
@@ -101,7 +101,7 @@
101 SERVICE STATUS: Information text 101 SERVICE STATUS: Information text
102 </literallayout> 102 </literallayout>
103 <para>However, note that this is not a requirement of the API, so you cannot depend on this 103 <para>However, note that this is not a requirement of the API, so you cannot depend on this
104 being an accurate reflection of the status of the service - the status should always 104 being an accurate reflection of the status of the service - the status should always
105 be determined by the return code.</para> 105 be determined by the return code.</para>
106 </section> 106 </section>
107 107
@@ -148,7 +148,7 @@
148 <para>Code and output should try to respect the 80x25 size of a 148 <para>Code and output should try to respect the 80x25 size of a
149 crt (remember when fixing stuff in the server room!)</para> 149 crt (remember when fixing stuff in the server room!)</para>
150 </section> 150 </section>
151 151
152 <section><title>Plugin Return Codes</title> 152 <section><title>Plugin Return Codes</title>
153 <para>The return codes below are based on the POSIX spec of returning 153 <para>The return codes below are based on the POSIX spec of returning
154 a positive value. Netsaint prior to v0.0.7 supported non-POSIX 154 a positive value. Netsaint prior to v0.0.7 supported non-POSIX
@@ -157,11 +157,11 @@
157 157
158 <para>Note: Some plugins will on occasion print on STDOUT that an error 158 <para>Note: Some plugins will on occasion print on STDOUT that an error
159 occurred and error code is 138 or 255 or some such number. These 159 occurred and error code is 138 or 255 or some such number. These
160 are usually caused by plugins using system commands and having not 160 are usually caused by plugins using system commands and having not
161 enough checks to catch unexpected output. Developers should include a 161 enough checks to catch unexpected output. Developers should include a
162 default catch-all for system command output that returns an UNKNOWN 162 default catch-all for system command output that returns an UNKNOWN
163 return code.</para> 163 return code.</para>
164 164
165 <table id="ReturnCodes"><title>Plugin Return Codes</title> 165 <table id="ReturnCodes"><title>Plugin Return Codes</title>
166 <tgroup cols="3"> 166 <tgroup cols="3">
167 <thead> 167 <thead>
@@ -175,20 +175,20 @@
175 <row> 175 <row>
176 <entry align="center"><para>0</para></entry> 176 <entry align="center"><para>0</para></entry>
177 <entry valign="middle"><para>OK</para></entry> 177 <entry valign="middle"><para>OK</para></entry>
178 <entry><para>The plugin was able to check the service and it 178 <entry><para>The plugin was able to check the service and it
179 appeared to be functioning properly</para></entry> 179 appeared to be functioning properly</para></entry>
180 </row> 180 </row>
181 <row> 181 <row>
182 <entry align="center"><para>1</para></entry> 182 <entry align="center"><para>1</para></entry>
183 <entry valign="middle"><para>Warning</para></entry> 183 <entry valign="middle"><para>Warning</para></entry>
184 <entry><para>The plugin was able to check the service, but it 184 <entry><para>The plugin was able to check the service, but it
185 appeared to be above some "warning" threshold or did not appear 185 appeared to be above some "warning" threshold or did not appear
186 to be working properly</para></entry> 186 to be working properly</para></entry>
187 </row> 187 </row>
188 <row> 188 <row>
189 <entry align="center"><para>2</para></entry> 189 <entry align="center"><para>2</para></entry>
190 <entry valign="middle"><para>Critical</para></entry> 190 <entry valign="middle"><para>Critical</para></entry>
191 <entry><para>The plugin detected that either the service was not 191 <entry><para>The plugin detected that either the service was not
192 running or it was above some "critical" threshold</para></entry> 192 running or it was above some "critical" threshold</para></entry>
193 </row> 193 </row>
194 <row> 194 <row>
@@ -207,7 +207,7 @@
207 </tgroup> 207 </tgroup>
208 </table> 208 </table>
209 209
210 210
211 </section> 211 </section>
212 212
213 <section id="thresholdformat"><title>Threshold and ranges</title> 213 <section id="thresholdformat"><title>Threshold and ranges</title>
@@ -218,7 +218,7 @@
218 set_thresholds(thresholds *, char *, char *) function to set the thresholds. 218 set_thresholds(thresholds *, char *, char *) function to set the thresholds.
219 </para> 219 </para>
220 <para>The theory is that the plugin will do some sort of check which returns 220 <para>The theory is that the plugin will do some sort of check which returns
221 back a numerical value, or metric, which is then compared to the warning and 221 back a numerical value, or metric, which is then compared to the warning and
222 critical thresholds. Use the get_status(double, thresholds *) function to 222 critical thresholds. Use the get_status(double, thresholds *) function to
223 compare the value against the thresholds.</para> 223 compare the value against the thresholds.</para>
224 <para>This is the generalised format for ranges:</para> 224 <para>This is the generalised format for ranges:</para>
@@ -226,14 +226,14 @@
226 <literallayout> 226 <literallayout>
227 [@]start:end 227 [@]start:end
228 </literallayout> 228 </literallayout>
229 229
230 <para>Notes:</para> 230 <para>Notes:</para>
231 <orderedlist> 231 <orderedlist>
232 <listitem><para>start &le; end</para> 232 <listitem><para>start &le; end</para>
233 </listitem> 233 </listitem>
234 <listitem><para>start and ":" is not required if start=0</para> 234 <listitem><para>start and ":" is not required if start=0</para>
235 </listitem> 235 </listitem>
236 <listitem><para>if range is of format "start:" and end is not specified, 236 <listitem><para>if range is of format "start:" and end is not specified,
237 assume end is infinity</para> 237 assume end is infinity</para>
238 </listitem> 238 </listitem>
239 <listitem><para>to specify negative infinity, use "~"</para> 239 <listitem><para>to specify negative infinity, use "~"</para>
@@ -245,7 +245,7 @@
245 (inclusive of endpoints)</para> 245 (inclusive of endpoints)</para>
246 </listitem> 246 </listitem>
247 </orderedlist> 247 </orderedlist>
248 248
249 <para>Note: Not all plugins are coded to expect ranges in this format yet. 249 <para>Note: Not all plugins are coded to expect ranges in this format yet.
250 There will be some work in providing multiple metrics.</para> 250 There will be some work in providing multiple metrics.</para>
251 251
@@ -344,7 +344,7 @@
344 </listitem> 344 </listitem>
345 <listitem><para>label can contain any characters except the equals sign or single quote (')</para> 345 <listitem><para>label can contain any characters except the equals sign or single quote (')</para>
346 </listitem> 346 </listitem>
347 <listitem><para>the single quotes for the label are optional. Required if 347 <listitem><para>the single quotes for the label are optional. Required if
348 spaces are in the label</para> 348 spaces are in the label</para>
349 </listitem> 349 </listitem>
350 <listitem><para>label length is arbitrary, but ideally the first 19 characters 350 <listitem><para>label length is arbitrary, but ideally the first 19 characters
@@ -353,7 +353,7 @@
353 </listitem> 353 </listitem>
354 <listitem><para>to specify a quote character, use two single quotes</para> 354 <listitem><para>to specify a quote character, use two single quotes</para>
355 </listitem> 355 </listitem>
356 <listitem><para>warn, crit, min or max may be null (for example, if the threshold is 356 <listitem><para>warn, crit, min or max may be null (for example, if the threshold is
357 not defined or min and max do not apply). Trailing unfilled semicolons can be 357 not defined or min and max do not apply). Trailing unfilled semicolons can be
358 dropped</para> 358 dropped</para>
359 </listitem> 359 </listitem>
@@ -363,12 +363,12 @@
363 same UOM. value may be a literal "U" instead, this would indicate that the 363 same UOM. value may be a literal "U" instead, this would indicate that the
364 actual value couldn't be determined</para> 364 actual value couldn't be determined</para>
365 </listitem> 365 </listitem>
366 <listitem><para>warn and crit are in the range format (see 366 <listitem><para>warn and crit are in the range format (see
367 <xref linkend="thresholdformat">). Must be the same UOM</para> 367 <xref linkend="thresholdformat">). Must be the same UOM</para>
368 </listitem> 368 </listitem>
369 <listitem><para>UOM (unit of measurement) is one of:</para> 369 <listitem><para>UOM (unit of measurement) is one of:</para>
370 <orderedlist> 370 <orderedlist>
371 <listitem><para>no unit specified - assume a number (int or float) 371 <listitem><para>no unit specified - assume a number (int or float)
372 of things (eg, users, processes, load averages)</para> 372 of things (eg, users, processes, load averages)</para>
373 </listitem> 373 </listitem>
374 <listitem><para>s - seconds (also us, ms)</para></listitem> 374 <listitem><para>s - seconds (also us, ms)</para></listitem>
@@ -385,9 +385,9 @@
385 </section> 385 </section>
386 386
387 <section><title>Translations</title> 387 <section><title>Translations</title>
388 <para>If possible, use translation tools for all output to respect the user's language 388 <para>If possible, use translation tools for all output to respect the user's language
389 settings. See <xref linkend="translationsdevelopers"> for guidelines 389 settings. See <xref linkend="translationsdevelopers"> for guidelines
390 for the core plugins. 390 for the core plugins.
391 </para> 391 </para>
392 </section> 392 </section>
393</section> 393</section>
@@ -436,7 +436,7 @@
436 </section> 436 </section>
437 437
438</section> 438</section>
439 439
440 440
441 441
442 442
@@ -447,17 +447,17 @@
447 Perl Nagios (ePN) requires stricter use of the some of Perl's features. 447 Perl Nagios (ePN) requires stricter use of the some of Perl's features.
448 This section outlines some of the steps needed to use ePN 448 This section outlines some of the steps needed to use ePN
449 effectively.</para> 449 effectively.</para>
450 450
451 <orderedlist> 451 <orderedlist>
452 452
453 <listitem><para> Do not use BEGIN and END blocks since they will be called 453 <listitem><para> Do not use BEGIN and END blocks since they will be called
454 only once (when Nagios starts and shuts down) with Embedded Perl (ePN). In 454 only once (when Nagios starts and shuts down) with Embedded Perl (ePN). In
455 particular, do not use BEGIN blocks to initialize variables.</para> 455 particular, do not use BEGIN blocks to initialize variables.</para>
456 </listitem> 456 </listitem>
457 457
458 <listitem><para>To use utils.pm, you need to provide a full path to the 458 <listitem><para>To use utils.pm, you need to provide a full path to the
459 module in order for it to work.</para> 459 module in order for it to work.</para>
460 460
461 <literallayout> 461 <literallayout>
462 e.g. 462 e.g.
463 use lib "/usr/local/nagios/libexec"; 463 use lib "/usr/local/nagios/libexec";
@@ -467,24 +467,24 @@
467 467
468 <listitem><para>Perl scripts should be called with "-w"</para> 468 <listitem><para>Perl scripts should be called with "-w"</para>
469 </listitem> 469 </listitem>
470 470
471 <listitem><para>All Perl plugins must compile cleanly under "use strict" - i.e. at 471 <listitem><para>All Perl plugins must compile cleanly under "use strict" - i.e. at
472 least explicitly package names as in "$main::x" or predeclare every 472 least explicitly package names as in "$main::x" or predeclare every
473 variable. </para> 473 variable. </para>
474 474
475 475
476 <para>Explicitly initialize each variable in use. Otherwise with 476 <para>Explicitly initialize each variable in use. Otherwise with
477 caching enabled, the plugin will not be recompiled each time, and 477 caching enabled, the plugin will not be recompiled each time, and
478 therefore Perl will not reinitialize all the variables. All old 478 therefore Perl will not reinitialize all the variables. All old
479 variable values will still be in effect.</para> 479 variable values will still be in effect.</para>
480 </listitem> 480 </listitem>
481 481
482 <listitem><para>Do not use &gt;DATA&lt; handles (these simply do not compile under ePN).</para> 482 <listitem><para>Do not use &gt;DATA&lt; handles (these simply do not compile under ePN).</para>
483 </listitem> 483 </listitem>
484 484
485 <listitem><para>Do not use global variables in named subroutines. This is bad practise anyway, but with ePN the 485 <listitem><para>Do not use global variables in named subroutines. This is bad practise anyway, but with ePN the
486 compiler will report an error "&lt;global_var&gt; will not stay shared ..". Values used by 486 compiler will report an error "&lt;global_var&gt; will not stay shared ..". Values used by
487 subroutines should be passed in the argument list.</para> 487 subroutines should be passed in the argument list.</para>
488 </listitem> 488 </listitem>
489 489
490 <listitem><para>If writing to a file (perhaps recording 490 <listitem><para>If writing to a file (perhaps recording
@@ -492,8 +492,8 @@
492 calls <emphasis role="strong">exit</emphasis>; that is caught by 492 calls <emphasis role="strong">exit</emphasis>; that is caught by
493 p1.pl, so output streams are never closed.</para> 493 p1.pl, so output streams are never closed.</para>
494 </listitem> 494 </listitem>
495 495
496 <listitem><para>As in <xref linkend="runtime"> all plugins need 496 <listitem><para>As in <xref linkend="runtime"> all plugins need
497 to monitor their runtime, specially if they are using network 497 to monitor their runtime, specially if they are using network
498 resources. Use of the <emphasis>alarm</emphasis> is recommended 498 resources. Use of the <emphasis>alarm</emphasis> is recommended
499 noting that some Perl modules (eg LWP) manage timers, so that an alarm 499 noting that some Perl modules (eg LWP) manage timers, so that an alarm
@@ -507,9 +507,9 @@
507 and then "exit $ERRORS{'OK'}" rather than "exit 0" 507 and then "exit $ERRORS{'OK'}" rather than "exit 0"
508 </para> 508 </para>
509 </listitem> 509 </listitem>
510 510
511 </orderedlist> 511 </orderedlist>
512 512
513</section> 513</section>
514 514
515<section id="runtime"><title>Runtime Timeouts</title> 515<section id="runtime"><title>Runtime Timeouts</title>
@@ -524,14 +524,14 @@
524 df could lock up like that. Plus, it should just be more error 524 df could lock up like that. Plus, it should just be more error
525 resistant to be able to time out rather than consume 525 resistant to be able to time out rather than consume
526 resources.</para> 526 resources.</para>
527 527
528 <section><title>Use DEFAULT_SOCKET_TIMEOUT</title> 528 <section><title>Use DEFAULT_SOCKET_TIMEOUT</title>
529 529
530 <para>All network plugins should use DEFAULT_SOCKET_TIMEOUT to timeout</para> 530 <para>All network plugins should use DEFAULT_SOCKET_TIMEOUT to timeout</para>
531 531
532 </section> 532 </section>
533 533
534 534
535 <section><title>Add alarms to network plugins</title> 535 <section><title>Add alarms to network plugins</title>
536 536
537 <para>If you write a plugin which communicates with another 537 <para>If you write a plugin which communicates with another
@@ -543,16 +543,16 @@
543 543
544 </section> 544 </section>
545 545
546 546
547 547
548</section> 548</section>
549 549
550<section id="PlugOptions"><title>Plugin Options</title> 550<section id="PlugOptions"><title>Plugin Options</title>
551 551
552 <para>A well written plugin should have --help as a way to get 552 <para>A well written plugin should have --help as a way to get
553 verbose help. Code and output should try to respect the 80x25 size of a 553 verbose help. Code and output should try to respect the 80x25 size of a
554 crt (remember when fixing stuff in the server room!)</para> 554 crt (remember when fixing stuff in the server room!)</para>
555 555
556 <section><title>Option Processing</title> 556 <section><title>Option Processing</title>
557 557
558 <para>For plugins written in C, we recommend the C standard 558 <para>For plugins written in C, we recommend the C standard
@@ -585,11 +585,11 @@
585 -p port or password (--port or --passwd/--password)monitors operational 585 -p port or password (--port or --passwd/--password)monitors operational
586 -u url or username (--url or --username) 586 -u url or username (--url or --username)
587 </literallayout> 587 </literallayout>
588 588
589 <para>Look at check_pgsql and check_procs to see how I currently 589 <para>Look at check_pgsql and check_procs to see how I currently
590 think this can work. Standard options are:</para> 590 think this can work. Standard options are:</para>
591 591
592 592
593 <para>The option -V or --version should be present in all 593 <para>The option -V or --version should be present in all
594 plugins. For C plugins it should result in a call to print_revision, a 594 plugins. For C plugins it should result in a call to print_revision, a
595 function in utils.c which takes two character arguments, the 595 function in utils.c which takes two character arguments, the
@@ -603,7 +603,7 @@
603 603
604 <para>The option -h or --help should be present in all plugins. 604 <para>The option -h or --help should be present in all plugins.
605 In C plugins, it should result in a call to print_help (or 605 In C plugins, it should result in a call to print_help (or
606 equivalent). The function print_help should call print_revision, 606 equivalent). The function print_help should call print_revision,
607 then print_usage, then should provide detailed 607 then print_usage, then should provide detailed
608 help. Help text should fit on an 80-character width display, but 608 help. Help text should fit on an 80-character width display, but
609 may run as many lines as needed.</para> 609 may run as many lines as needed.</para>
@@ -666,7 +666,7 @@
666 666
667 <para>As always, comments are welcome - making this consistent 667 <para>As always, comments are welcome - making this consistent
668 without a host of long options was quite a hassle, and I would 668 without a host of long options was quite a hassle, and I would
669 suspect that there are flaws in this strategy. 669 suspect that there are flaws in this strategy.
670 </para> 670 </para>
671 </section> 671 </section>
672</section> 672</section>
@@ -678,7 +678,7 @@ create and update test cases where possible.
678</para> 678</para>
679 679
680<para> 680<para>
681To run a test, from the top level directory, run "make test". This will run 681To run a test, from the top level directory, run "make test". This will run
682all the current tests and report an overall success rate. 682all the current tests and report an overall success rate.
683</para> 683</para>
684 684
@@ -697,7 +697,7 @@ This runs the test in a summary format.
697</para> 697</para>
698 698
699<para> 699<para>
700For a good and amusing tutorial on using Test::More, see this 700For a good and amusing tutorial on using Test::More, see this
701<ulink url="http://search.cpan.org/dist/Test-Simple/lib/Test/Tutorial.pod"> 701<ulink url="http://search.cpan.org/dist/Test-Simple/lib/Test/Tutorial.pod">
702link</ulink> 702link</ulink>
703</para> 703</para>
@@ -706,16 +706,16 @@ link</ulink>
706 706
707<section><title>Testing the C library functions</title> 707<section><title>Testing the C library functions</title>
708<para> 708<para>
709We use <ulink url="http://jc.ngo.org.uk/trac-bin/trac.cgi/wiki/LibTap">the libtap library</ulink>, which gives 709We use <ulink url="http://jc.ngo.org.uk/trac-bin/trac.cgi/wiki/LibTap">the libtap library</ulink>, which gives
710perl's TAP 710perl's TAP
711(Test Anything Protocol) output. This is used by the FreeBSD team for their regression testing. 711(Test Anything Protocol) output. This is used by the FreeBSD team for their regression testing.
712</para> 712</para>
713 713
714<para> 714<para>
715To run tests using the libtap library, download the latest tar ball and extract. 715To run tests using the libtap library, download the latest tar ball and extract.
716There is a problem with tap-1.01 where 716There is a problem with tap-1.01 where
717<ulink url="http://jc.ngo.org.uk/trac-bin/trac.cgi/ticket/25">pthread support doesn't appear to work</ulink> 717<ulink url="http://jc.ngo.org.uk/trac-bin/trac.cgi/ticket/25">pthread support doesn't appear to work</ulink>
718properly on non-FreeBSD systems. Install with 'CPPFLAGS="-UHAVE_LIBPTHREAD" ./configure && make && make check && make install'. 718properly on non-FreeBSD systems. Install with 'CPPFLAGS="-UHAVE_LIBPTHREAD" ./configure && make && make check && make install'.
719</para> 719</para>
720 720
721<para> 721<para>
@@ -729,8 +729,8 @@ setup the tests. Run "make test" to run all the tests.
729 <para>See <ulink url="http://www.gnu.org/prep/standards_toc.html">GNU 729 <para>See <ulink url="http://www.gnu.org/prep/standards_toc.html">GNU
730 Coding standards</ulink> for general guidelines.</para> 730 Coding standards</ulink> for general guidelines.</para>
731 <section><title>C coding</title> 731 <section><title>C coding</title>
732 732
733 <para>Variables should be declared at the beginning of code blocks and 733 <para>Variables should be declared at the beginning of code blocks and
734 not inline because of portability with older compilers.</para> 734 not inline because of portability with older compilers.</para>
735 735
736 <para>You should use /* */ for comments and not // as some compilers 736 <para>You should use /* */ for comments and not // as some compilers
@@ -745,8 +745,8 @@ setup the tests. Run "make test" to run all the tests.
745 <para>If you have copied a routine from another source, make sure the licence 745 <para>If you have copied a routine from another source, make sure the licence
746 from your source allows this. Add a comment referencing the ACKNOWLEDGEMENTS 746 from your source allows this. Add a comment referencing the ACKNOWLEDGEMENTS
747 file, where you can put more detail about the source.</para> 747 file, where you can put more detail about the source.</para>
748 <para>For contributed code, do not add any named credits in the source code 748 <para>For contributed code, do not add any named credits in the source code
749 - contributors should be added into the THANKS.in file instead. 749 - contributors should be added into the THANKS.in file instead.
750 </para> 750 </para>
751 </section> 751 </section>
752 752
@@ -809,11 +809,11 @@ setup the tests. Run "make test" to run all the tests.
809 809
810 810
811 <section id="Contributedplugins"><title>Contributed plugins</title> 811 <section id="Contributedplugins"><title>Contributed plugins</title>
812 <para>Plugins that have been contributed to the project and 812 <para>Plugins that have been contributed to the project and
813 distributed with the Monitoring Plugins files are held in the contrib/ directory and are not installed 813 distributed with the Monitoring Plugins files are held in the contrib/ directory and are not installed
814 by default. These plugins are not officially supported by the team. 814 by default. These plugins are not officially supported by the team.
815 The current policy is that these plugins should be owned and maintained by the original 815 The current policy is that these plugins should be owned and maintained by the original
816 contributor, preferably hosted on <ulink url="http://monitoringexchange.org">Monitoring Exchange</ulink>. 816 contributor, preferably hosted on <ulink url="https://exchange.icinga.com/">Icinga Exchange</ulink>.
817 </para> 817 </para>
818 <para>If patches or bugs are raised to an contributed plugin, we will start communications with the 818 <para>If patches or bugs are raised to an contributed plugin, we will start communications with the
819 original contributor, but seek to remove the plugin from our distribution. 819 original contributor, but seek to remove the plugin from our distribution.
@@ -824,11 +824,11 @@ setup the tests. Run "make test" to run all the tests.
824 824
825 <section id="Newplugins"><title>New plugins</title> 825 <section id="Newplugins"><title>New plugins</title>
826 <para>If you would like others to use your plugins, please add it to 826 <para>If you would like others to use your plugins, please add it to
827 the official 3rd party plugin repository, 827 the official 3rd party plugin repository,
828 <ulink url="http://monitoringexchange.org">Monitoring Exchange</ulink>. 828 <ulink url="https://exchange.icinga.com/">Icinga Exchange</ulink>.
829 </para> 829 </para>
830 830
831 <para>We are not accepting requests for inclusion of plugins into 831 <para>We are not accepting requests for inclusion of plugins into
832 our distribution at the moment, but when we do, these are the minimum 832 our distribution at the moment, but when we do, these are the minimum
833 requirements: 833 requirements:
834 </para> 834 </para>
@@ -843,9 +843,9 @@ setup the tests. Run "make test" to run all the tests.
843 --timeout, --warning, --critical)</para> 843 --timeout, --warning, --critical)</para>
844 </listitem> 844 </listitem>
845 <listitem> 845 <listitem>
846 <para>It is determined to be not redundant (for instance, we would not 846 <para>It is determined to be not redundant (for instance, we would not
847 add a new version of check_disk just because someone had provide 847 add a new version of check_disk just because someone had provide
848 a plugin that had perf checking - we would incorporate the features 848 a plugin that had perf checking - we would incorporate the features
849 into an exisiting plugin)</para> 849 into an exisiting plugin)</para>
850 </listitem> 850 </listitem>
851 <listitem> 851 <listitem>
@@ -857,7 +857,7 @@ setup the tests. Run "make test" to run all the tests.
857utils (perl or c or sh) rather than using its own</para> 857utils (perl or c or sh) rather than using its own</para>
858 </listitem> 858 </listitem>
859 <listitem> 859 <listitem>
860 <para>Includes patches to configure.in if required (via the EXTRAS list if 860 <para>Includes patches to configure.in if required (via the EXTRAS list if
861 it will only work on some platforms)</para> 861 it will only work on some platforms)</para>
862 </listitem> 862 </listitem>
863 <listitem> 863 <listitem>
@@ -870,5 +870,5 @@ utils (perl or c or sh) rather than using its own</para>
870 870
871</section> 871</section>
872</article> 872</article>
873 873
874</book> 874</book>
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 01ae174..f8f1535 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -50,19 +50,11 @@ const char *email = "devel@monitoring-plugins.org";
50#if HAVE_SYS_SOCKIO_H 50#if HAVE_SYS_SOCKIO_H
51#include <sys/sockio.h> 51#include <sys/sockio.h>
52#endif 52#endif
53#include <sys/ioctl.h> 53
54#include <sys/time.h> 54#include <sys/time.h>
55#include <sys/types.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <stdarg.h>
59#include <unistd.h>
60#include <stddef.h>
61#include <errno.h> 55#include <errno.h>
62#include <string.h> 56#include <signal.h>
63#include <ctype.h> 57#include <ctype.h>
64#include <netdb.h>
65#include <sys/socket.h>
66#include <net/if.h> 58#include <net/if.h>
67#include <netinet/in_systm.h> 59#include <netinet/in_systm.h>
68#include <netinet/in.h> 60#include <netinet/in.h>
@@ -71,8 +63,6 @@ const char *email = "devel@monitoring-plugins.org";
71#include <netinet/ip_icmp.h> 63#include <netinet/ip_icmp.h>
72#include <netinet/icmp6.h> 64#include <netinet/icmp6.h>
73#include <arpa/inet.h> 65#include <arpa/inet.h>
74#include <signal.h>
75#include <float.h>
76 66
77 67
78/** sometimes undefined system macros (quite a few, actually) **/ 68/** sometimes undefined system macros (quite a few, actually) **/
@@ -207,7 +197,7 @@ static int add_target(char *);
207static int add_target_ip(char *, struct sockaddr_storage *); 197static int add_target_ip(char *, struct sockaddr_storage *);
208static int handle_random_icmp(unsigned char *, struct sockaddr_storage *); 198static int handle_random_icmp(unsigned char *, struct sockaddr_storage *);
209static void parse_address(struct sockaddr_storage *, char *, int); 199static void parse_address(struct sockaddr_storage *, char *, int);
210static unsigned short icmp_checksum(unsigned short *, int); 200static unsigned short icmp_checksum(uint16_t *, size_t);
211static void finish(int); 201static void finish(int);
212static void crash(const char *, ...); 202static void crash(const char *, ...);
213 203
@@ -223,7 +213,7 @@ static int mode, protocols, sockets, debug = 0, timeout = 10;
223static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE; 213static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE;
224static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN; 214static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN;
225 215
226static unsigned int icmp_sent = 0, icmp_recv = 0, icmp_lost = 0; 216static unsigned int icmp_sent = 0, icmp_recv = 0, icmp_lost = 0, ttl = 0;
227#define icmp_pkts_en_route (icmp_sent - (icmp_recv + icmp_lost)) 217#define icmp_pkts_en_route (icmp_sent - (icmp_recv + icmp_lost))
228static unsigned short targets_down = 0, targets = 0, packets = 0; 218static unsigned short targets_down = 0, targets = 0, packets = 0;
229#define targets_alive (targets - targets_down) 219#define targets_alive (targets - targets_down)
@@ -233,7 +223,6 @@ static pid_t pid;
233static struct timezone tz; 223static struct timezone tz;
234static struct timeval prog_start; 224static struct timeval prog_start;
235static unsigned long long max_completion_time = 0; 225static unsigned long long max_completion_time = 0;
236static unsigned char ttl = 0; /* outgoing ttl */
237static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values */ 226static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values */
238static int min_hosts_alive = -1; 227static int min_hosts_alive = -1;
239float pkt_backoff_factor = 1.5; 228float pkt_backoff_factor = 1.5;
@@ -410,6 +399,7 @@ main(int argc, char **argv)
410#ifdef SO_TIMESTAMP 399#ifdef SO_TIMESTAMP
411 int on = 1; 400 int on = 1;
412#endif 401#endif
402 char *source_ip = NULL;
413 char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:64"; 403 char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:64";
414 404
415 setlocale (LC_ALL, ""); 405 setlocale (LC_ALL, "");
@@ -464,7 +454,6 @@ main(int argc, char **argv)
464 /* Parse protocol arguments first */ 454 /* Parse protocol arguments first */
465 for(i = 1; i < argc; i++) { 455 for(i = 1; i < argc; i++) {
466 while((arg = getopt(argc, argv, opts_str)) != EOF) { 456 while((arg = getopt(argc, argv, opts_str)) != EOF) {
467 unsigned short size;
468 switch(arg) { 457 switch(arg) {
469 case '4': 458 case '4':
470 if (address_family != -1) 459 if (address_family != -1)
@@ -487,10 +476,10 @@ main(int argc, char **argv)
487 /* Reset argument scanning */ 476 /* Reset argument scanning */
488 optind = 1; 477 optind = 1;
489 478
479 unsigned short size;
490 /* parse the arguments */ 480 /* parse the arguments */
491 for(i = 1; i < argc; i++) { 481 for(i = 1; i < argc; i++) {
492 while((arg = getopt(argc, argv, opts_str)) != EOF) { 482 while((arg = getopt(argc, argv, opts_str)) != EOF) {
493 unsigned short size;
494 switch(arg) { 483 switch(arg) {
495 case 'v': 484 case 'v':
496 debug++; 485 debug++;
@@ -530,7 +519,7 @@ main(int argc, char **argv)
530 add_target(optarg); 519 add_target(optarg);
531 break; 520 break;
532 case 'l': 521 case 'l':
533 ttl = (unsigned char)strtoul(optarg, NULL, 0); 522 ttl = (int)strtoul(optarg, NULL, 0);
534 break; 523 break;
535 case 'm': 524 case 'm':
536 min_hosts_alive = (int)strtoul(optarg, NULL, 0); 525 min_hosts_alive = (int)strtoul(optarg, NULL, 0);
@@ -542,7 +531,7 @@ main(int argc, char **argv)
542 } 531 }
543 break; 532 break;
544 case 's': /* specify source IP address */ 533 case 's': /* specify source IP address */
545 set_source_ip(optarg); 534 source_ip = optarg;
546 break; 535 break;
547 case 'V': /* version */ 536 case 'V': /* version */
548 print_revision (progname, NP_VERSION); 537 print_revision (progname, NP_VERSION);
@@ -597,6 +586,8 @@ main(int argc, char **argv)
597 sockets |= HAVE_ICMP; 586 sockets |= HAVE_ICMP;
598 else icmp_sockerrno = errno; 587 else icmp_sockerrno = errno;
599 588
589 if( source_ip )
590 set_source_ip(source_ip);
600 591
601#ifdef SO_TIMESTAMP 592#ifdef SO_TIMESTAMP
602 if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) 593 if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
@@ -717,7 +708,7 @@ main(int argc, char **argv)
717static void 708static void
718run_checks() 709run_checks()
719{ 710{
720 u_int i, t, result; 711 u_int i, t;
721 u_int final_wait, time_passed; 712 u_int final_wait, time_passed;
722 713
723 /* this loop might actually violate the pkt_interval or target_interval 714 /* this loop might actually violate the pkt_interval or target_interval
@@ -735,9 +726,9 @@ run_checks()
735 726
736 /* we're still in the game, so send next packet */ 727 /* we're still in the game, so send next packet */
737 (void)send_icmp_ping(icmp_sock, table[t]); 728 (void)send_icmp_ping(icmp_sock, table[t]);
738 result = wait_for_reply(icmp_sock, target_interval); 729 wait_for_reply(icmp_sock, target_interval);
739 } 730 }
740 result = wait_for_reply(icmp_sock, pkt_interval * targets); 731 wait_for_reply(icmp_sock, pkt_interval * targets);
741 } 732 }
742 733
743 if(icmp_pkts_en_route && targets_alive) { 734 if(icmp_pkts_en_route && targets_alive) {
@@ -757,7 +748,7 @@ run_checks()
757 * haven't yet */ 748 * haven't yet */
758 if(debug) printf("Waiting for %u micro-seconds (%0.3f msecs)\n", 749 if(debug) printf("Waiting for %u micro-seconds (%0.3f msecs)\n",
759 final_wait, (float)final_wait / 1000); 750 final_wait, (float)final_wait / 1000);
760 result = wait_for_reply(icmp_sock, final_wait); 751 wait_for_reply(icmp_sock, final_wait);
761 } 752 }
762} 753}
763 754
@@ -776,7 +767,7 @@ static int
776wait_for_reply(int sock, u_int t) 767wait_for_reply(int sock, u_int t)
777{ 768{
778 int n, hlen; 769 int n, hlen;
779 static unsigned char buf[4096]; 770 static unsigned char buf[65536];
780 struct sockaddr_storage resp_addr; 771 struct sockaddr_storage resp_addr;
781 union ip_hdr *ip; 772 union ip_hdr *ip;
782 union icmp_packet packet; 773 union icmp_packet packet;
@@ -913,9 +904,27 @@ wait_for_reply(int sock, u_int t)
913 if(debug) { 904 if(debug) {
914 char address[INET6_ADDRSTRLEN]; 905 char address[INET6_ADDRSTRLEN];
915 parse_address(&resp_addr, address, sizeof(address)); 906 parse_address(&resp_addr, address, sizeof(address));
916 printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n", 907
917 (float)tdiff / 1000, address, 908 switch(address_family) {
918 ttl, ip->ip.ip_ttl, (float)host->rtmax / 1000, (float)host->rtmin / 1000); 909 case AF_INET: {
910 printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n",
911 (float)tdiff / 1000,
912 address,
913 ttl,
914 ip->ip.ip_ttl,
915 (float)host->rtmax / 1000,
916 (float)host->rtmin / 1000);
917 break;
918 };
919 case AF_INET6: {
920 printf("%0.3f ms rtt from %s, outgoing ttl: %u, max: %0.3f, min: %0.3f\n",
921 (float)tdiff / 1000,
922 address,
923 ttl,
924 (float)host->rtmax / 1000,
925 (float)host->rtmin / 1000);
926 };
927 }
919 } 928 }
920 929
921 /* if we're in hostcheck mode, exit with limited printouts */ 930 /* if we're in hostcheck mode, exit with limited printouts */
@@ -938,6 +947,7 @@ static int
938send_icmp_ping(int sock, struct rta_host *host) 947send_icmp_ping(int sock, struct rta_host *host)
939{ 948{
940 long int len; 949 long int len;
950 size_t addrlen;
941 struct icmp_ping_data data; 951 struct icmp_ping_data data;
942 struct msghdr hdr; 952 struct msghdr hdr;
943 struct iovec iov; 953 struct iovec iov;
@@ -969,6 +979,7 @@ send_icmp_ping(int sock, struct rta_host *host)
969 979
970 if (address_family == AF_INET) { 980 if (address_family == AF_INET) {
971 struct icmp *icp = (struct icmp*)buf; 981 struct icmp *icp = (struct icmp*)buf;
982 addrlen = sizeof(struct sockaddr_in);
972 983
973 memcpy(&icp->icmp_data, &data, sizeof(data)); 984 memcpy(&icp->icmp_data, &data, sizeof(data));
974 985
@@ -977,7 +988,7 @@ send_icmp_ping(int sock, struct rta_host *host)
977 icp->icmp_cksum = 0; 988 icp->icmp_cksum = 0;
978 icp->icmp_id = htons(pid); 989 icp->icmp_id = htons(pid);
979 icp->icmp_seq = htons(host->id++); 990 icp->icmp_seq = htons(host->id++);
980 icp->icmp_cksum = icmp_checksum((unsigned short*)buf, icmp_pkt_size); 991 icp->icmp_cksum = icmp_checksum((uint16_t*)buf, (size_t)icmp_pkt_size);
981 992
982 if (debug > 2) 993 if (debug > 2)
983 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", 994 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n",
@@ -985,7 +996,10 @@ send_icmp_ping(int sock, struct rta_host *host)
985 } 996 }
986 else { 997 else {
987 struct icmp6_hdr *icp6 = (struct icmp6_hdr*)buf; 998 struct icmp6_hdr *icp6 = (struct icmp6_hdr*)buf;
999 addrlen = sizeof(struct sockaddr_in6);
1000
988 memcpy(&icp6->icmp6_dataun.icmp6_un_data8[4], &data, sizeof(data)); 1001 memcpy(&icp6->icmp6_dataun.icmp6_un_data8[4], &data, sizeof(data));
1002
989 icp6->icmp6_type = ICMP6_ECHO_REQUEST; 1003 icp6->icmp6_type = ICMP6_ECHO_REQUEST;
990 icp6->icmp6_code = 0; 1004 icp6->icmp6_code = 0;
991 icp6->icmp6_cksum = 0; 1005 icp6->icmp6_cksum = 0;
@@ -1006,7 +1020,7 @@ send_icmp_ping(int sock, struct rta_host *host)
1006 1020
1007 memset(&hdr, 0, sizeof(hdr)); 1021 memset(&hdr, 0, sizeof(hdr));
1008 hdr.msg_name = (struct sockaddr *)&host->saddr_in; 1022 hdr.msg_name = (struct sockaddr *)&host->saddr_in;
1009 hdr.msg_namelen = sizeof(struct sockaddr_storage); 1023 hdr.msg_namelen = addrlen;
1010 hdr.msg_iov = &iov; 1024 hdr.msg_iov = &iov;
1011 hdr.msg_iovlen = 1; 1025 hdr.msg_iovlen = 1;
1012 1026
@@ -1514,18 +1528,19 @@ get_threshold(char *str, threshold *th)
1514} 1528}
1515 1529
1516unsigned short 1530unsigned short
1517icmp_checksum(unsigned short *p, int n) 1531icmp_checksum(uint16_t *p, size_t n)
1518{ 1532{
1519 unsigned short cksum; 1533 unsigned short cksum;
1520 long sum = 0; 1534 long sum = 0;
1521 1535
1522 while(n > 2) { 1536 /* sizeof(uint16_t) == 2 */
1523 sum += *p++; 1537 while(n >= 2) {
1524 n -= sizeof(unsigned short); 1538 sum += *(p++);
1539 n -= 2;
1525 } 1540 }
1526 1541
1527 /* mop up the occasional odd byte */ 1542 /* mop up the occasional odd byte */
1528 if(n == 1) sum += (unsigned char)*p; 1543 if(n == 1) sum += *((uint8_t *)p -1);
1529 1544
1530 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 1545 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1531 sum += (sum >> 16); /* add carry */ 1546 sum += (sum >> 16); /* add carry */
diff --git a/plugins-root/t/check_icmp.t b/plugins-root/t/check_icmp.t
index e043d4e..f6aa681 100644
--- a/plugins-root/t/check_icmp.t
+++ b/plugins-root/t/check_icmp.t
@@ -12,7 +12,7 @@ my $allow_sudo = getTestParameter( "NP_ALLOW_SUDO",
12 "no" ); 12 "no" );
13 13
14if ($allow_sudo eq "yes" or $> == 0) { 14if ($allow_sudo eq "yes" or $> == 0) {
15 plan tests => 16; 15 plan tests => 20;
16} else { 16} else {
17 plan skip_all => "Need sudo to test check_icmp"; 17 plan skip_all => "Need sudo to test check_icmp";
18} 18}
@@ -83,3 +83,14 @@ $res = NPTest->testCmd(
83is( $res->return_code, 2, "One of two host nonresponsive - two required" ); 83is( $res->return_code, 2, "One of two host nonresponsive - two required" );
84like( $res->output, $failureOutput, "Output OK" ); 84like( $res->output, $failureOutput, "Output OK" );
85 85
86$res = NPTest->testCmd(
87 "$sudo ./check_icmp -H $host_responsive -s 127.0.15.15 -w 10000ms,100% -c 10000ms,100% -n 1 -m 2"
88 );
89is( $res->return_code, 0, "IPv4 source_ip accepted" );
90like( $res->output, $successOutput, "Output OK" );
91
92$res = NPTest->testCmd(
93 "$sudo ./check_icmp -H $host_responsive -b 65507"
94 );
95is( $res->return_code, 0, "Try max paket size" );
96like( $res->output, $successOutput, "Output OK - Didn't overflow" );
diff --git a/plugins-scripts/check_disk_smb.pl b/plugins-scripts/check_disk_smb.pl
index 28c49e8..15d1634 100755..100644
--- a/plugins-scripts/check_disk_smb.pl
+++ b/plugins-scripts/check_disk_smb.pl
@@ -22,7 +22,7 @@ require 5.004;
22use POSIX qw(setsid); 22use POSIX qw(setsid);
23use strict; 23use strict;
24use Getopt::Long; 24use Getopt::Long;
25use vars qw($opt_P $opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $verbose); 25use vars qw($opt_P $opt_V $opt_h $opt_H $opt_s $opt_W $opt_u $opt_p $opt_w $opt_c $opt_a $opt_C $opt_t $verbose);
26use vars qw($PROGNAME); 26use vars qw($PROGNAME);
27use FindBin; 27use FindBin;
28use lib "$FindBin::Bin"; 28use lib "$FindBin::Bin";
@@ -43,6 +43,7 @@ $ENV{'ENV'}='';
43Getopt::Long::Configure('bundling'); 43Getopt::Long::Configure('bundling');
44GetOptions 44GetOptions
45 ("v" => \$verbose, "verbose" => \$verbose, 45 ("v" => \$verbose, "verbose" => \$verbose,
46 "t=i" => \$opt_t, "timeout=i" => \$opt_t,
46 "P=s" => \$opt_P, "port=s" => \$opt_P, 47 "P=s" => \$opt_P, "port=s" => \$opt_P,
47 "V" => \$opt_V, "version" => \$opt_V, 48 "V" => \$opt_V, "version" => \$opt_V,
48 "h" => \$opt_h, "help" => \$opt_h, 49 "h" => \$opt_h, "help" => \$opt_h,
@@ -53,7 +54,8 @@ GetOptions
53 "s=s" => \$opt_s, "share=s" => \$opt_s, 54 "s=s" => \$opt_s, "share=s" => \$opt_s,
54 "W=s" => \$opt_W, "workgroup=s" => \$opt_W, 55 "W=s" => \$opt_W, "workgroup=s" => \$opt_W,
55 "H=s" => \$opt_H, "hostname=s" => \$opt_H, 56 "H=s" => \$opt_H, "hostname=s" => \$opt_H,
56 "a=s" => \$opt_a, "address=s" => \$opt_a); 57 "a=s" => \$opt_a, "address=s" => \$opt_a,
58 "C=s" => \$opt_C, "configfile=s" => \$opt_C);
57 59
58if ($opt_V) { 60if ($opt_V) {
59 print_revision($PROGNAME,'@NP_VERSION@'); #' 61 print_revision($PROGNAME,'@NP_VERSION@'); #'
@@ -91,6 +93,12 @@ my $warn = $1 if ($opt_w =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
91my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/); 93my $crit = $1 if ($opt_c =~ /^([0-9]{1,2}\%?|100\%?|[0-9]+[kMG])$/);
92($crit) || usage("Invalid critical threshold: $opt_c\n"); 94($crit) || usage("Invalid critical threshold: $opt_c\n");
93 95
96($opt_C) || ($opt_C = shift @ARGV) || ($opt_C = "");
97my $configfile = $opt_C if ($opt_C);
98usage("Unable to read config file $configfile\n") if ($configfile) && (! -r $configfile);
99
100if ($opt_t && $opt_t =~ /^([0-9]+)$/) { $TIMEOUT = $1; }
101
94# Execute the given command line and return anything it writes to STDOUT and/or 102# Execute the given command line and return anything it writes to STDOUT and/or
95# STDERR. (This might be useful for other plugins, too, so it should possibly 103# STDERR. (This might be useful for other plugins, too, so it should possibly
96# be moved to utils.pm.) 104# be moved to utils.pm.)
@@ -193,6 +201,7 @@ my @cmd = (
193 defined($workgroup) ? ("-W", $workgroup) : (), 201 defined($workgroup) ? ("-W", $workgroup) : (),
194 defined($address) ? ("-I", $address) : (), 202 defined($address) ? ("-I", $address) : (),
195 defined($opt_P) ? ("-p", $opt_P) : (), 203 defined($opt_P) ? ("-p", $opt_P) : (),
204 defined($configfile) ? ("-s", $configfile) : (),
196 "-c", "du" 205 "-c", "du"
197); 206);
198 207
@@ -292,7 +301,8 @@ exit $ERRORS{$state};
292 301
293sub print_usage () { 302sub print_usage () {
294 print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password> 303 print "Usage: $PROGNAME -H <host> -s <share> -u <user> -p <password>
295 -w <warn> -c <crit> [-W <workgroup>] [-P <port>] [-a <IP>]\n"; 304 -w <warn> -c <crit> [-W <workgroup>] [-P <port>] [-a <IP>] [-t timeout]
305 [-C <configfile>]\n";
296} 306}
297 307
298sub print_help () { 308sub print_help () {
@@ -318,11 +328,14 @@ Perl Check SMB Disk plugin for monitoring
318 Password to log in to server. (Defaults to an empty password) 328 Password to log in to server. (Defaults to an empty password)
319-w, --warning=INTEGER or INTEGER[kMG] 329-w, --warning=INTEGER or INTEGER[kMG]
320 Percent of used space at which a warning will be generated (Default: 85%) 330 Percent of used space at which a warning will be generated (Default: 85%)
321
322-c, --critical=INTEGER or INTEGER[kMG] 331-c, --critical=INTEGER or INTEGER[kMG]
323 Percent of used space at which a critical will be generated (Defaults: 95%) 332 Percent of used space at which a critical will be generated (Defaults: 95%)
333-t, --timeout=INTEGER
334 Seconds before connection times out (Default: 15)
324-P, --port=INTEGER 335-P, --port=INTEGER
325 Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default) 336 Port to be used to connect to. Some Windows boxes use 139, others 445 (Defaults to smbclient default)
337-C, --configfile=STRING
338 Path to configfile which should be used by smbclient (Defaults to smb.conf of your smb installation)
326 339
327 If thresholds are followed by either a k, M, or G then check to see if that 340 If thresholds are followed by either a k, M, or G then check to see if that
328 much disk space is available (kilobytes, Megabytes, Gigabytes) 341 much disk space is available (kilobytes, Megabytes, Gigabytes)
diff --git a/plugins-scripts/check_mailq.pl b/plugins-scripts/check_mailq.pl
index 3914f4a..4c72332 100755
--- a/plugins-scripts/check_mailq.pl
+++ b/plugins-scripts/check_mailq.pl
@@ -567,17 +567,17 @@ exit $state;
567 567
568sub process_arguments(){ 568sub process_arguments(){
569 GetOptions 569 GetOptions
570 ("V" => \$opt_V, "version" => \$opt_V, 570 ("V" => \$opt_V, "version" => \$opt_V,
571 "v" => \$opt_v, "verbose" => \$opt_v, 571 "v" => \$opt_v, "verbose" => \$opt_v,
572 "h" => \$opt_h, "help" => \$opt_h, 572 "h" => \$opt_h, "help" => \$opt_h,
573 "M:s" => \$opt_M, "mailserver:s" => \$opt_M, # mailserver (default sendmail) 573 "M:s" => \$opt_M, "mailserver:s" => \$opt_M, # mailserver (default sendmail)
574 "w=i" => \$opt_w, "warning=i" => \$opt_w, # warning if above this number 574 "w=i" => \$opt_w, "warning=i" => \$opt_w, # warning if above this number
575 "c=i" => \$opt_c, "critical=i" => \$opt_c, # critical if above this number 575 "c=i" => \$opt_c, "critical=i" => \$opt_c, # critical if above this number
576 "W=i" => \$opt_W, "warning-domain=i" => \$opt_W, # Warning if above this number
577 "C=i" => \$opt_C, "critical-domain=i" => \$opt_C, # Critical if above this number
576 "t=i" => \$opt_t, "timeout=i" => \$opt_t, 578 "t=i" => \$opt_t, "timeout=i" => \$opt_t,
577 "s" => \$opt_s, "sudo" => \$opt_s, 579 "s" => \$opt_s, "sudo" => \$opt_s,
578 "d:s" => \$opt_d, "configdir:s" => \$opt_d, 580 "d:s" => \$opt_d, "configdir:s" => \$opt_d,
579 "W=i" => \$opt_W, # warning if above this number
580 "C=i" => \$opt_C, # critical if above this number
581 ); 581 );
582 582
583 if ($opt_V) { 583 if ($opt_V) {
@@ -671,15 +671,15 @@ sub print_help () {
671 print " Feedback/patches to support non-sendmail mailqueue welcome\n\n"; 671 print " Feedback/patches to support non-sendmail mailqueue welcome\n\n";
672 print "-w (--warning) = Min. number of messages in queue to generate warning\n"; 672 print "-w (--warning) = Min. number of messages in queue to generate warning\n";
673 print "-c (--critical) = Min. number of messages in queue to generate critical alert ( w < c )\n"; 673 print "-c (--critical) = Min. number of messages in queue to generate critical alert ( w < c )\n";
674 print "-W = Min. number of messages for same domain in queue to generate warning\n"; 674 print "-W (--warning-domain) = Min. number of messages for same domain in queue to generate warning\n";
675 print "-C = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n"; 675 print "-C (--critical-domain) = Min. number of messages for same domain in queue to generate critical alert ( W < C )\n";
676 print "-t (--timeout) = Plugin timeout in seconds (default = $utils::TIMEOUT)\n"; 676 print "-t (--timeout) = Plugin timeout in seconds (default = $utils::TIMEOUT)\n";
677 print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer ] (default = autodetect)\n"; 677 print "-M (--mailserver) = [ sendmail | qmail | postfix | exim | nullmailer ] (default = autodetect)\n";
678 print "-s (--sudo) = Use sudo to call the mailq command\n"; 678 print "-s (--sudo) = Use sudo to call the mailq command\n";
679 print "-d (--configdir) = Config file or directory\n"; 679 print "-d (--configdir) = Config file or directory\n";
680 print "-h (--help)\n"; 680 print "-h (--help)\n";
681 print "-V (--version)\n"; 681 print "-V (--version)\n";
682 print "-v (--verbose) = debugging output\n"; 682 print "-v (--verbose) = debugging output\n";
683 print "\n\n"; 683 print "\n\n";
684 print "Note: -w and -c are required arguments. -W and -C are optional.\n"; 684 print "Note: -w and -c are required arguments. -W and -C are optional.\n";
685 print " -W and -C are applied to domains listed on the queues - both FROM and TO. (sendmail)\n"; 685 print " -W and -C are applied to domains listed on the queues - both FROM and TO. (sendmail)\n";
diff --git a/plugins-scripts/check_uptime.pl b/plugins-scripts/check_uptime.pl
index 4c9f22d..f954287 100755
--- a/plugins-scripts/check_uptime.pl
+++ b/plugins-scripts/check_uptime.pl
@@ -25,7 +25,7 @@ use POSIX;
25use strict; 25use strict;
26use Getopt::Long; 26use Getopt::Long;
27use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c 27use vars qw($opt_V $opt_h $opt_v $verbose $PROGNAME $opt_w $opt_c
28 $opt_f $opt_s 28 $opt_f $opt_s $opt_d
29 $lower_warn_threshold $upper_warn_threshold 29 $lower_warn_threshold $upper_warn_threshold
30 $lower_crit_threshold $upper_crit_threshold 30 $lower_crit_threshold $upper_crit_threshold
31 $status $state $msg); 31 $status $state $msg);
@@ -137,9 +137,20 @@ if ( $uptime_seconds > $upper_crit_threshold ) {
137 $state_str = "OK"; 137 $state_str = "OK";
138} 138}
139 139
140# Prepare uptime value (seconds or days)
141my $uptime_text = "";
142my $uptime_unit = "";
143if ( $opt_d ) {
144 $uptime_text = floor($uptime_seconds / 60 / 60 / 24);
145 $uptime_unit = "days";
146} else {
147 $uptime_text = $uptime_seconds;
148 $uptime_unit = "seconds";
149}
150
140$msg = "$state_str: "; 151$msg = "$state_str: ";
141 152
142$msg .= "uptime is $uptime_seconds seconds. "; 153$msg .= "Uptime is $uptime_text $uptime_unit. ";
143$msg .= "Exceeds $out_of_bounds_text threshold. " if $out_of_bounds_text; 154$msg .= "Exceeds $out_of_bounds_text threshold. " if $out_of_bounds_text;
144$msg .= "Running for $pretty_uptime. " if $opt_f; 155$msg .= "Running for $pretty_uptime. " if $opt_f;
145if ( $opt_s ) { 156if ( $opt_s ) {
@@ -167,6 +178,7 @@ sub process_arguments(){
167 "c=s" => \$opt_c, "critical=s" => \$opt_c, # critical if above this number 178 "c=s" => \$opt_c, "critical=s" => \$opt_c, # critical if above this number
168 "f" => \$opt_f, "for" => \$opt_f, # show "running for ..." 179 "f" => \$opt_f, "for" => \$opt_f, # show "running for ..."
169 "s" => \$opt_s, "since" => \$opt_s, # show "running since ..." 180 "s" => \$opt_s, "since" => \$opt_s, # show "running since ..."
181 "d" => \$opt_d, "days" => \$opt_d, # report uptime in days
170 ); 182 );
171 183
172 if ($opt_V) { 184 if ($opt_V) {
@@ -262,6 +274,7 @@ sub print_help () {
262 print "-c (--critical) = Min. number of uptime to generate critical alert ( w < c )\n"; 274 print "-c (--critical) = Min. number of uptime to generate critical alert ( w < c )\n";
263 print "-f (--for) = Show uptime in a pretty format (Running for x weeks, x days, ...)\n"; 275 print "-f (--for) = Show uptime in a pretty format (Running for x weeks, x days, ...)\n";
264 print "-s (--since) = Show last boot in yyyy-mm-dd HH:MM:SS format (output from 'uptime -s')\n"; 276 print "-s (--since) = Show last boot in yyyy-mm-dd HH:MM:SS format (output from 'uptime -s')\n";
277 print "-d (--days) = Show uptime in days\n";
265 print "-h (--help)\n"; 278 print "-h (--help)\n";
266 print "-V (--version)\n"; 279 print "-V (--version)\n";
267 print "-v (--verbose) = debugging output\n"; 280 print "-v (--verbose) = debugging output\n";
diff --git a/plugins-scripts/t/check_uptime.t b/plugins-scripts/t/check_uptime.t
index c395307..6e81db3 100644
--- a/plugins-scripts/t/check_uptime.t
+++ b/plugins-scripts/t/check_uptime.t
@@ -5,7 +5,7 @@
5# 5#
6 6
7use strict; 7use strict;
8use Test::More tests => 40; 8use Test::More tests => 42;
9use NPTest; 9use NPTest;
10 10
11my $result; 11my $result;
@@ -46,29 +46,35 @@ cmp_ok( $result->return_code, '==', 2, "Uptime higher than 2 seconds" );
46like ( $result->output, '/Running since \d+/', "Output for the s parameter correct" ); 46like ( $result->output, '/Running since \d+/', "Output for the s parameter correct" );
47 47
48$result = NPTest->testCmd( 48$result = NPTest->testCmd(
49 "./check_uptime -d -w 1 -c 2"
50 );
51cmp_ok( $result->return_code, '==', 2, "Uptime higher than 2 seconds" );
52like ( $result->output, '/CRITICAL: Uptime is \d+ days/', "Output for the d parameter correct" );
53
54$result = NPTest->testCmd(
49 "./check_uptime -w 1 -c 2" 55 "./check_uptime -w 1 -c 2"
50 ); 56 );
51cmp_ok( $result->return_code, '==', 2, "Uptime higher than 2 seconds" ); 57cmp_ok( $result->return_code, '==', 2, "Uptime higher than 2 seconds" );
52like ( $result->output, '/^CRITICAL: uptime is \d+ seconds/', "Output for uptime higher than 2 seconds correct" ); 58like ( $result->output, '/^CRITICAL: Uptime is \d+ seconds/', "Output for uptime higher than 2 seconds correct" );
53 59
54$result = NPTest->testCmd( 60$result = NPTest->testCmd(
55 "./check_uptime -w 1 -c 9999w" 61 "./check_uptime -w 1 -c 9999w"
56 ); 62 );
57cmp_ok( $result->return_code, '==', 1, "Uptime lower than 9999 weeks" ); 63cmp_ok( $result->return_code, '==', 1, "Uptime lower than 9999 weeks" );
58like ( $result->output, '/^WARNING: uptime is \d+ seconds/', "Output for uptime lower than 9999 weeks correct" ); 64like ( $result->output, '/^WARNING: Uptime is \d+ seconds/', "Output for uptime lower than 9999 weeks correct" );
59 65
60$result = NPTest->testCmd( 66$result = NPTest->testCmd(
61 "./check_uptime -w 9998w -c 9999w" 67 "./check_uptime -w 9998w -c 9999w"
62 ); 68 );
63cmp_ok( $result->return_code, '==', 0, "Uptime lower than 9998 weeks" ); 69cmp_ok( $result->return_code, '==', 0, "Uptime lower than 9998 weeks" );
64like ( $result->output, '/^OK: uptime is \d+ seconds/', "Output for uptime lower than 9998 weeks correct" ); 70like ( $result->output, '/^OK: Uptime is \d+ seconds/', "Output for uptime lower than 9998 weeks correct" );
65like ( $result->output, '/\|uptime=[0-9]+s;6046790400;6047395200;/', "Checking for performance output" ); 71like ( $result->output, '/\|uptime=[0-9]+s;6046790400;6047395200;/', "Checking for performance output" );
66 72
67$result = NPTest->testCmd( 73$result = NPTest->testCmd(
68 "./check_uptime -w 111222d -c 222333d" 74 "./check_uptime -w 111222d -c 222333d"
69 ); 75 );
70cmp_ok( $result->return_code, '==', 0, "Uptime lower than 111222 days" ); 76cmp_ok( $result->return_code, '==', 0, "Uptime lower than 111222 days" );
71like ( $result->output, '/^OK: uptime is \d+ seconds/', "Output for uptime lower than 111222 days correct" ); 77like ( $result->output, '/^OK: Uptime is \d+ seconds/', "Output for uptime lower than 111222 days correct" );
72like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" ); 78like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
73 79
74# Same as before, hopefully uptime is higher than 2 seconds so no warning 80# Same as before, hopefully uptime is higher than 2 seconds so no warning
@@ -76,7 +82,7 @@ $result = NPTest->testCmd(
76 "./check_uptime -w 2:111222d -c 1:222333d" 82 "./check_uptime -w 2:111222d -c 1:222333d"
77 ); 83 );
78cmp_ok( $result->return_code, '==', 0, "Uptime lower than 111222 days, and higher 2 seconds" ); 84cmp_ok( $result->return_code, '==', 0, "Uptime lower than 111222 days, and higher 2 seconds" );
79like ( $result->output, '/^OK: uptime is \d+ seconds/', "Output for uptime lower than 111222 days, and higher 2 seconds correct" ); 85like ( $result->output, '/^OK: Uptime is \d+ seconds/', "Output for uptime lower than 111222 days, and higher 2 seconds correct" );
80like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" ); 86like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
81 87
82# Same as before, now the low warning should trigger 88# Same as before, now the low warning should trigger
@@ -84,7 +90,7 @@ $result = NPTest->testCmd(
84 "./check_uptime -w 111221d:111222d -c 1:222333d" 90 "./check_uptime -w 111221d:111222d -c 1:222333d"
85 ); 91 );
86cmp_ok( $result->return_code, '==', 1, "Uptime lower than 111221 days raises warning" ); 92cmp_ok( $result->return_code, '==', 1, "Uptime lower than 111221 days raises warning" );
87like ( $result->output, '/^WARNING: uptime is \d+ seconds/', "Output for uptime lower than 111221 days correct" ); 93like ( $result->output, '/^WARNING: Uptime is \d+ seconds/', "Output for uptime lower than 111221 days correct" );
88like ( $result->output, '/Exceeds lower warn threshold/', "Exceeds text correct" ); 94like ( $result->output, '/Exceeds lower warn threshold/', "Exceeds text correct" );
89like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" ); 95like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
90 96
@@ -93,7 +99,7 @@ $result = NPTest->testCmd(
93 "./check_uptime -w 111221d:111222d -c 111220d:222333d" 99 "./check_uptime -w 111221d:111222d -c 111220d:222333d"
94 ); 100 );
95cmp_ok( $result->return_code, '==', 2, "Uptime lower than 111220 days raises critical" ); 101cmp_ok( $result->return_code, '==', 2, "Uptime lower than 111220 days raises critical" );
96like ( $result->output, '/^CRITICAL: uptime is \d+ seconds/', "Output for uptime lower than 111220 days correct" ); 102like ( $result->output, '/^CRITICAL: Uptime is \d+ seconds/', "Output for uptime lower than 111220 days correct" );
97like ( $result->output, '/Exceeds lower crit threshold/', "Exceeds text correct" ); 103like ( $result->output, '/Exceeds lower crit threshold/', "Exceeds text correct" );
98like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" ); 104like ( $result->output, '/\|uptime=[0-9]+s;9609580800;19209571200;/', "Checking for performance output" );
99 105
diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c
index 485bf3b..1ad547e 100644
--- a/plugins/check_by_ssh.c
+++ b/plugins/check_by_ssh.c
@@ -49,6 +49,8 @@ unsigned int commands = 0;
49unsigned int services = 0; 49unsigned int services = 0;
50int skip_stdout = 0; 50int skip_stdout = 0;
51int skip_stderr = 0; 51int skip_stderr = 0;
52int warn_on_stderr = 0;
53bool unknown_timeout = FALSE;
52char *remotecmd = NULL; 54char *remotecmd = NULL;
53char **commargv = NULL; 55char **commargv = NULL;
54int commargc = 0; 56int commargc = 0;
@@ -100,6 +102,13 @@ main (int argc, char **argv)
100 102
101 result = cmd_run_array (commargv, &chld_out, &chld_err, 0); 103 result = cmd_run_array (commargv, &chld_out, &chld_err, 0);
102 104
105 /* SSH returns 255 if connection attempt fails; include the first line of error output */
106 if (result == 255 && unknown_timeout) {
107 printf (_("SSH connection failed: %s\n"),
108 chld_err.lines > 0 ? chld_err.line[0] : "(no error output)");
109 return STATE_UNKNOWN;
110 }
111
103 if (verbose) { 112 if (verbose) {
104 for(i = 0; i < chld_out.lines; i++) 113 for(i = 0; i < chld_out.lines; i++)
105 printf("stdout: %s\n", chld_out.line[i]); 114 printf("stdout: %s\n", chld_out.line[i]);
@@ -116,7 +125,10 @@ main (int argc, char **argv)
116 if(chld_err.lines > skip_stderr) { 125 if(chld_err.lines > skip_stderr) {
117 printf (_("Remote command execution failed: %s\n"), 126 printf (_("Remote command execution failed: %s\n"),
118 chld_err.line[skip_stderr]); 127 chld_err.line[skip_stderr]);
119 return max_state_alt(result, STATE_UNKNOWN); 128 if ( warn_on_stderr )
129 return max_state_alt(result, STATE_WARNING);
130 else
131 return max_state_alt(result, STATE_UNKNOWN);
120 } 132 }
121 133
122 /* this is simple if we're not supposed to be passive. 134 /* this is simple if we're not supposed to be passive.
@@ -176,6 +188,7 @@ process_arguments (int argc, char **argv)
176 {"verbose", no_argument, 0, 'v'}, 188 {"verbose", no_argument, 0, 'v'},
177 {"fork", no_argument, 0, 'f'}, 189 {"fork", no_argument, 0, 'f'},
178 {"timeout", required_argument, 0, 't'}, 190 {"timeout", required_argument, 0, 't'},
191 {"unknown-timeout", no_argument, 0, 'U'},
179 {"host", required_argument, 0, 'H'}, /* backward compatibility */ 192 {"host", required_argument, 0, 'H'}, /* backward compatibility */
180 {"hostname", required_argument, 0, 'H'}, 193 {"hostname", required_argument, 0, 'H'},
181 {"port", required_argument,0,'p'}, 194 {"port", required_argument,0,'p'},
@@ -189,6 +202,7 @@ process_arguments (int argc, char **argv)
189 {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */ 202 {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */
190 {"skip-stdout", optional_argument, 0, 'S'}, 203 {"skip-stdout", optional_argument, 0, 'S'},
191 {"skip-stderr", optional_argument, 0, 'E'}, 204 {"skip-stderr", optional_argument, 0, 'E'},
205 {"warn-on-stderr", no_argument, 0, 'W'},
192 {"proto1", no_argument, 0, '1'}, 206 {"proto1", no_argument, 0, '1'},
193 {"proto2", no_argument, 0, '2'}, 207 {"proto2", no_argument, 0, '2'},
194 {"use-ipv4", no_argument, 0, '4'}, 208 {"use-ipv4", no_argument, 0, '4'},
@@ -207,7 +221,7 @@ process_arguments (int argc, char **argv)
207 strcpy (argv[c], "-t"); 221 strcpy (argv[c], "-t");
208 222
209 while (1) { 223 while (1) {
210 c = getopt_long (argc, argv, "Vvh1246fqt:H:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, 224 c = getopt_long (argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts,
211 &option); 225 &option);
212 226
213 if (c == -1 || c == EOF) 227 if (c == -1 || c == EOF)
@@ -229,6 +243,9 @@ process_arguments (int argc, char **argv)
229 else 243 else
230 timeout_interval = atoi (optarg); 244 timeout_interval = atoi (optarg);
231 break; 245 break;
246 case 'U':
247 unknown_timeout = TRUE;
248 break;
232 case 'H': /* host */ 249 case 'H': /* host */
233 hostname = optarg; 250 hostname = optarg;
234 break; 251 break;
@@ -307,6 +324,9 @@ process_arguments (int argc, char **argv)
307 else 324 else
308 skip_stderr = atoi (optarg); 325 skip_stderr = atoi (optarg);
309 break; 326 break;
327 case 'W': /* exit with warning if there is an output on stderr */
328 warn_on_stderr = 1;
329 break;
310 case 'o': /* Extra options for the ssh command */ 330 case 'o': /* Extra options for the ssh command */
311 comm_append("-o"); 331 comm_append("-o");
312 comm_append(optarg); 332 comm_append(optarg);
@@ -413,6 +433,8 @@ print_help (void)
413 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]")); 433 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]"));
414 printf (" %s\n", "-E, --skip-stderr[=n]"); 434 printf (" %s\n", "-E, --skip-stderr[=n]");
415 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]")); 435 printf (" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]"));
436 printf (" %s\n", "-W, --warn-on-stderr]");
437 printf (" %s\n", _("Exit with an warning, if there is an output on STDERR"));
416 printf (" %s\n", "-f"); 438 printf (" %s\n", "-f");
417 printf (" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed")); 439 printf (" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed"));
418 printf (" %s\n","-C, --command='COMMAND STRING'"); 440 printf (" %s\n","-C, --command='COMMAND STRING'");
@@ -435,6 +457,8 @@ print_help (void)
435 printf (" %s\n", _("Tell ssh to suppress warning and diagnostic messages [optional]")); 457 printf (" %s\n", _("Tell ssh to suppress warning and diagnostic messages [optional]"));
436 printf (UT_WARN_CRIT); 458 printf (UT_WARN_CRIT);
437 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 459 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
460 printf (" %s\n","-U, --unknown-timeout");
461 printf (" %s\n", _("Make connection problems return UNKNOWN instead of CRITICAL"));
438 printf (UT_VERBOSE); 462 printf (UT_VERBOSE);
439 printf("\n"); 463 printf("\n");
440 printf (" %s\n", _("The most common mode of use is to refer to a local identity file with")); 464 printf (" %s\n", _("The most common mode of use is to refer to a local identity file with"));
@@ -464,8 +488,8 @@ void
464print_usage (void) 488print_usage (void)
465{ 489{
466 printf ("%s\n", _("Usage:")); 490 printf ("%s\n", _("Usage:"));
467 printf (" %s -H <host> -C <command> [-fqv] [-1|-2] [-4|-6]\n" 491 printf (" %s -H <host> -C <command> [-fqvU] [-1|-2] [-4|-6]\n"
468 " [-S [lines]] [-E [lines]] [-t timeout] [-i identity]\n" 492 " [-S [lines]] [-E [lines]] [-W] [-t timeout] [-i identity]\n"
469 " [-l user] [-n name] [-s servicelist] [-O outputfile]\n" 493 " [-l user] [-n name] [-s servicelist] [-O outputfile]\n"
470 " [-p port] [-o ssh-option] [-F configfile]\n", 494 " [-p port] [-o ssh-option] [-F configfile]\n",
471 progname); 495 progname);
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 14cc846..a69854a 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -66,13 +66,13 @@ const char *email = "devel@monitoring-plugins.org";
66#define DEFAULT_BUFFER_SIZE 2048 66#define DEFAULT_BUFFER_SIZE 2048
67#define DEFAULT_SERVER_URL "/" 67#define DEFAULT_SERVER_URL "/"
68#define HTTP_EXPECT "HTTP/" 68#define HTTP_EXPECT "HTTP/"
69#define DEFAULT_MAX_REDIRS 15
70#define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN 69#define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN
71enum { 70enum {
72 MAX_IPV4_HOSTLENGTH = 255, 71 MAX_IPV4_HOSTLENGTH = 255,
73 HTTP_PORT = 80, 72 HTTP_PORT = 80,
74 HTTPS_PORT = 443, 73 HTTPS_PORT = 443,
75 MAX_PORT = 65535 74 MAX_PORT = 65535,
75 DEFAULT_MAX_REDIRS = 15
76}; 76};
77 77
78enum { 78enum {
@@ -193,6 +193,7 @@ int followsticky = STICKY_NONE;
193int use_ssl = FALSE; 193int use_ssl = FALSE;
194int use_sni = TRUE; 194int use_sni = TRUE;
195int check_cert = FALSE; 195int check_cert = FALSE;
196int continue_after_check_cert = FALSE;
196typedef union { 197typedef union {
197 struct curl_slist* to_info; 198 struct curl_slist* to_info;
198 struct curl_certinfo* to_certinfo; 199 struct curl_certinfo* to_certinfo;
@@ -754,7 +755,9 @@ check_http (void)
754 * and we actually have OpenSSL in the monitoring tools 755 * and we actually have OpenSSL in the monitoring tools
755 */ 756 */
756 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 757 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
757 return result; 758 if (continue_after_check_cert == FALSE) {
759 return result;
760 }
758#else /* USE_OPENSSL */ 761#else /* USE_OPENSSL */
759 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); 762 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n");
760#endif /* USE_OPENSSL */ 763#endif /* USE_OPENSSL */
@@ -794,13 +797,17 @@ GOT_FIRST_CERT:
794 } 797 }
795 BIO_free (cert_BIO); 798 BIO_free (cert_BIO);
796 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 799 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
797 return result; 800 if (continue_after_check_cert == FALSE) {
801 return result;
802 }
798#else /* USE_OPENSSL */ 803#else /* USE_OPENSSL */
799 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, 804 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal,
800 * so we use the libcurl CURLINFO data 805 * so we use the libcurl CURLINFO data
801 */ 806 */
802 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); 807 result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit);
803 return result; 808 if (continue_after_check_cert == FALSE) {
809 return result;
810 }
804#endif /* USE_OPENSSL */ 811#endif /* USE_OPENSSL */
805 } else { 812 } else {
806 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"), 813 snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"),
@@ -1054,7 +1061,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1054 char *new_url; 1061 char *new_url;
1055 1062
1056 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 1063 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
1057 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 1064 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
1058 headers, &nof_headers, 0); 1065 headers, &nof_headers, 0);
1059 1066
1060 location = get_header_value (headers, nof_headers, "location"); 1067 location = get_header_value (headers, nof_headers, "location");
@@ -1210,6 +1217,8 @@ process_arguments (int argc, char **argv)
1210 enum { 1217 enum {
1211 INVERT_REGEX = CHAR_MAX + 1, 1218 INVERT_REGEX = CHAR_MAX + 1,
1212 SNI_OPTION, 1219 SNI_OPTION,
1220 MAX_REDIRS_OPTION,
1221 CONTINUE_AFTER_CHECK_CERT,
1213 CA_CERT_OPTION, 1222 CA_CERT_OPTION,
1214 HTTP_VERSION_OPTION, 1223 HTTP_VERSION_OPTION,
1215 AUTOMATIC_DECOMPRESSION 1224 AUTOMATIC_DECOMPRESSION
@@ -1243,6 +1252,7 @@ process_arguments (int argc, char **argv)
1243 {"private-key", required_argument, 0, 'K'}, 1252 {"private-key", required_argument, 0, 'K'},
1244 {"ca-cert", required_argument, 0, CA_CERT_OPTION}, 1253 {"ca-cert", required_argument, 0, CA_CERT_OPTION},
1245 {"verify-cert", no_argument, 0, 'D'}, 1254 {"verify-cert", no_argument, 0, 'D'},
1255 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
1246 {"useragent", required_argument, 0, 'A'}, 1256 {"useragent", required_argument, 0, 'A'},
1247 {"header", required_argument, 0, 'k'}, 1257 {"header", required_argument, 0, 'k'},
1248 {"no-body", no_argument, 0, 'N'}, 1258 {"no-body", no_argument, 0, 'N'},
@@ -1254,6 +1264,7 @@ process_arguments (int argc, char **argv)
1254 {"use-ipv6", no_argument, 0, '6'}, 1264 {"use-ipv6", no_argument, 0, '6'},
1255 {"extended-perfdata", no_argument, 0, 'E'}, 1265 {"extended-perfdata", no_argument, 0, 'E'},
1256 {"show-body", no_argument, 0, 'B'}, 1266 {"show-body", no_argument, 0, 'B'},
1267 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
1257 {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, 1268 {"http-version", required_argument, 0, HTTP_VERSION_OPTION},
1258 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, 1269 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION},
1259 {0, 0, 0, 0} 1270 {0, 0, 0, 0}
@@ -1401,6 +1412,11 @@ process_arguments (int argc, char **argv)
1401 check_cert = TRUE; 1412 check_cert = TRUE;
1402 goto enable_ssl; 1413 goto enable_ssl;
1403#endif 1414#endif
1415 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
1416#ifdef HAVE_SSL
1417 continue_after_check_cert = TRUE;
1418 break;
1419#endif
1404 case 'J': /* use client certificate */ 1420 case 'J': /* use client certificate */
1405#ifdef LIBCURL_FEATURE_SSL 1421#ifdef LIBCURL_FEATURE_SSL
1406 test_file(optarg); 1422 test_file(optarg);
@@ -1512,6 +1528,13 @@ process_arguments (int argc, char **argv)
1512 use_sni = TRUE; 1528 use_sni = TRUE;
1513 break; 1529 break;
1514#endif /* LIBCURL_FEATURE_SSL */ 1530#endif /* LIBCURL_FEATURE_SSL */
1531 case MAX_REDIRS_OPTION:
1532 if (!is_intnonneg (optarg))
1533 usage2 (_("Invalid max_redirs count"), optarg);
1534 else {
1535 max_depth = atoi (optarg);
1536 }
1537 break;
1515 case 'f': /* onredirect */ 1538 case 'f': /* onredirect */
1516 if (!strcmp (optarg, "ok")) 1539 if (!strcmp (optarg, "ok"))
1517 onredirect = STATE_OK; 1540 onredirect = STATE_OK;
@@ -1791,7 +1814,11 @@ print_help (void)
1791#endif 1814#endif
1792 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1815 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1793 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1816 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1794 printf (" %s\n", _("(when this option is used the URL is not checked.)")); 1817 printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use"));
1818 printf (" %s\n", _(" --continue-after-certificate to override this behavior)"));
1819 printf (" %s\n", "--continue-after-certificate");
1820 printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check."));
1821 printf (" %s\n", _("Does nothing unless -C is used."));
1795 printf (" %s\n", "-J, --client-cert=FILE"); 1822 printf (" %s\n", "-J, --client-cert=FILE");
1796 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); 1823 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1797 printf (" %s\n", _("to be used in establishing the SSL session")); 1824 printf (" %s\n", _("to be used in establishing the SSL session"));
@@ -1854,6 +1881,9 @@ print_help (void)
1854 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); 1881 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same."));
1855 printf (" %s\n", _("follow uses the old redirection algorithm of check_http.")); 1882 printf (" %s\n", _("follow uses the old redirection algorithm of check_http."));
1856 printf (" %s\n", _("curl uses CURL_FOLLOWLOCATION built into libcurl.")); 1883 printf (" %s\n", _("curl uses CURL_FOLLOWLOCATION built into libcurl."));
1884 printf (" %s\n", "--max-redirs=INTEGER");
1885 printf (" %s", _("Maximal number of redirects (default: "));
1886 printf ("%d)\n", DEFAULT_MAX_REDIRS);
1857 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 1887 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
1858 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); 1888 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
1859 printf ("\n"); 1889 printf ("\n");
@@ -2188,7 +2218,7 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA
2188 size_t msglen; 2218 size_t msglen;
2189 2219
2190 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2220 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2191 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2221 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2192 headers, &nof_headers, 0); 2222 headers, &nof_headers, 0);
2193 2223
2194 server_date = get_header_value (headers, nof_headers, "date"); 2224 server_date = get_header_value (headers, nof_headers, "date");
@@ -2246,7 +2276,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri
2246 curlhelp_statusline status_line; 2276 curlhelp_statusline status_line;
2247 2277
2248 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2278 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2249 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2279 &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2250 headers, &nof_headers, 0); 2280 headers, &nof_headers, 0);
2251 2281
2252 content_length_s = get_header_value (headers, nof_headers, "content-length"); 2282 content_length_s = get_header_value (headers, nof_headers, "content-length");
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 54befca..66c5dd3 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -230,8 +230,10 @@ main (int argc, char **argv)
230 /* Process for every path in list */ 230 /* Process for every path in list */
231 for (path = path_select_list; path; path=path->name_next) { 231 for (path = path_select_list; path; path=path->name_next) {
232 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) 232 if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL)
233 printf("Thresholds(pct) for %s warn: %f crit %f\n",path->name, path->freespace_percent->warning->end, 233 printf("Thresholds(pct) for %s warn: %f crit %f\n",
234 path->freespace_percent->critical->end); 234 path->name,
235 path->freespace_percent->warning->end,
236 path->freespace_percent->critical->end);
235 237
236 if (verbose >= 3 && path->group != NULL) 238 if (verbose >= 3 && path->group != NULL)
237 printf("Group of %s: %s\n",path->name,path->group); 239 printf("Group of %s: %s\n",path->name,path->group);
@@ -959,7 +961,7 @@ print_help (void)
959 printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); 961 printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems"));
960 printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); 962 printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)"));
961 printf (" %s\n", "-M, --mountpoint"); 963 printf (" %s\n", "-M, --mountpoint");
962 printf (" %s\n", _("Display the mountpoint instead of the partition")); 964 printf (" %s\n", _("Display the (block) device instead of the mount point"));
963 printf (" %s\n", "-m, --megabytes"); 965 printf (" %s\n", "-m, --megabytes");
964 printf (" %s\n", _("Same as '--units MB'")); 966 printf (" %s\n", _("Same as '--units MB'"));
965 printf (" %s\n", "-A, --all"); 967 printf (" %s\n", "-A, --all");
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index 521d0fe..be9362a 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 successfull 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_http.c b/plugins/check_http.c
index 34fb4f0..f8ec853 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -52,11 +52,13 @@ enum {
52 MAX_IPV4_HOSTLENGTH = 255, 52 MAX_IPV4_HOSTLENGTH = 255,
53 HTTP_PORT = 80, 53 HTTP_PORT = 80,
54 HTTPS_PORT = 443, 54 HTTPS_PORT = 443,
55 MAX_PORT = 65535 55 MAX_PORT = 65535,
56 DEFAULT_MAX_REDIRS = 15
56}; 57};
57 58
58#ifdef HAVE_SSL 59#ifdef HAVE_SSL
59int check_cert = FALSE; 60int check_cert = FALSE;
61int continue_after_check_cert = FALSE;
60int ssl_version = 0; 62int ssl_version = 0;
61int days_till_exp_warn, days_till_exp_crit; 63int days_till_exp_warn, days_till_exp_crit;
62char *randbuff; 64char *randbuff;
@@ -125,7 +127,7 @@ int sd;
125int min_page_len = 0; 127int min_page_len = 0;
126int max_page_len = 0; 128int max_page_len = 0;
127int redir_depth = 0; 129int redir_depth = 0;
128int max_depth = 15; 130int max_depth = DEFAULT_MAX_REDIRS;
129char *http_method; 131char *http_method;
130char *http_method_proxy; 132char *http_method_proxy;
131char *http_post_data; 133char *http_post_data;
@@ -203,7 +205,9 @@ process_arguments (int argc, char **argv)
203 205
204 enum { 206 enum {
205 INVERT_REGEX = CHAR_MAX + 1, 207 INVERT_REGEX = CHAR_MAX + 1,
206 SNI_OPTION 208 SNI_OPTION,
209 MAX_REDIRS_OPTION,
210 CONTINUE_AFTER_CHECK_CERT
207 }; 211 };
208 212
209 int option = 0; 213 int option = 0;
@@ -231,6 +235,7 @@ process_arguments (int argc, char **argv)
231 {"certificate", required_argument, 0, 'C'}, 235 {"certificate", required_argument, 0, 'C'},
232 {"client-cert", required_argument, 0, 'J'}, 236 {"client-cert", required_argument, 0, 'J'},
233 {"private-key", required_argument, 0, 'K'}, 237 {"private-key", required_argument, 0, 'K'},
238 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
234 {"useragent", required_argument, 0, 'A'}, 239 {"useragent", required_argument, 0, 'A'},
235 {"header", required_argument, 0, 'k'}, 240 {"header", required_argument, 0, 'k'},
236 {"no-body", no_argument, 0, 'N'}, 241 {"no-body", no_argument, 0, 'N'},
@@ -242,6 +247,7 @@ process_arguments (int argc, char **argv)
242 {"use-ipv6", no_argument, 0, '6'}, 247 {"use-ipv6", no_argument, 0, '6'},
243 {"extended-perfdata", no_argument, 0, 'E'}, 248 {"extended-perfdata", no_argument, 0, 'E'},
244 {"show-body", no_argument, 0, 'B'}, 249 {"show-body", no_argument, 0, 'B'},
250 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
245 {0, 0, 0, 0} 251 {0, 0, 0, 0}
246 }; 252 };
247 253
@@ -329,6 +335,11 @@ process_arguments (int argc, char **argv)
329 check_cert = TRUE; 335 check_cert = TRUE;
330 goto enable_ssl; 336 goto enable_ssl;
331#endif 337#endif
338 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
339#ifdef HAVE_SSL
340 continue_after_check_cert = TRUE;
341 break;
342#endif
332 case 'J': /* use client certificate */ 343 case 'J': /* use client certificate */
333#ifdef HAVE_SSL 344#ifdef HAVE_SSL
334 test_file(optarg); 345 test_file(optarg);
@@ -373,6 +384,13 @@ process_arguments (int argc, char **argv)
373 case SNI_OPTION: 384 case SNI_OPTION:
374 use_sni = TRUE; 385 use_sni = TRUE;
375 break; 386 break;
387 case MAX_REDIRS_OPTION:
388 if (!is_intnonneg (optarg))
389 usage2 (_("Invalid max_redirs count"), optarg);
390 else {
391 max_depth = atoi (optarg);
392 }
393 break;
376 case 'f': /* onredirect */ 394 case 'f': /* onredirect */
377 if (!strcmp (optarg, "stickyport")) 395 if (!strcmp (optarg, "stickyport"))
378 onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT; 396 onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT;
@@ -971,9 +989,11 @@ check_http (void)
971 elapsed_time_ssl = (double)microsec_ssl / 1.0e6; 989 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
972 if (check_cert == TRUE) { 990 if (check_cert == TRUE) {
973 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 991 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
974 if (sd) close(sd); 992 if (continue_after_check_cert == FALSE) {
975 np_net_ssl_cleanup(); 993 if (sd) close(sd);
976 return result; 994 np_net_ssl_cleanup();
995 return result;
996 }
977 } 997 }
978 } 998 }
979#endif /* HAVE_SSL */ 999#endif /* HAVE_SSL */
@@ -1598,7 +1618,11 @@ print_help (void)
1598 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 1618 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
1599 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1619 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1600 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1620 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1601 printf (" %s\n", _("(when this option is used the URL is not checked.)")); 1621 printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use"));
1622 printf (" %s\n", _(" --continue-after-certificate to override this behavior)"));
1623 printf (" %s\n", "--continue-after-certificate");
1624 printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check."));
1625 printf (" %s\n", _("Does nothing unless -C is used."));
1602 printf (" %s\n", "-J, --client-cert=FILE"); 1626 printf (" %s\n", "-J, --client-cert=FILE");
1603 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); 1627 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1604 printf (" %s\n", _("to be used in establishing the SSL session")); 1628 printf (" %s\n", _("to be used in establishing the SSL session"));
@@ -1657,9 +1681,11 @@ print_help (void)
1657 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); 1681 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>");
1658 printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); 1682 printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the"));
1659 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); 1683 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same."));
1684 printf (" %s\n", "--max-redirs=INTEGER");
1685 printf (" %s", _("Maximal number of redirects (default: "));
1686 printf ("%d)\n", DEFAULT_MAX_REDIRS);
1660 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 1687 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
1661 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); 1688 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
1662
1663 printf (UT_WARN_CRIT); 1689 printf (UT_WARN_CRIT);
1664 1690
1665 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1691 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index b8fc5f1..c893386 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -85,6 +85,8 @@ char *pgparams = NULL;
85double twarn = (double)DEFAULT_WARN; 85double twarn = (double)DEFAULT_WARN;
86double tcrit = (double)DEFAULT_CRIT; 86double tcrit = (double)DEFAULT_CRIT;
87char *pgquery = NULL; 87char *pgquery = NULL;
88#define OPTID_QUERYNAME -1000
89char *pgqueryname = NULL;
88char *query_warning = NULL; 90char *query_warning = NULL;
89char *query_critical = NULL; 91char *query_critical = NULL;
90thresholds *qthresholds = NULL; 92thresholds *qthresholds = NULL;
@@ -285,6 +287,7 @@ process_arguments (int argc, char **argv)
285 {"database", required_argument, 0, 'd'}, 287 {"database", required_argument, 0, 'd'},
286 {"option", required_argument, 0, 'o'}, 288 {"option", required_argument, 0, 'o'},
287 {"query", required_argument, 0, 'q'}, 289 {"query", required_argument, 0, 'q'},
290 {"queryname", required_argument, 0, OPTID_QUERYNAME},
288 {"query_critical", required_argument, 0, 'C'}, 291 {"query_critical", required_argument, 0, 'C'},
289 {"query_warning", required_argument, 0, 'W'}, 292 {"query_warning", required_argument, 0, 'W'},
290 {"verbose", no_argument, 0, 'v'}, 293 {"verbose", no_argument, 0, 'v'},
@@ -368,6 +371,9 @@ process_arguments (int argc, char **argv)
368 case 'q': 371 case 'q':
369 pgquery = optarg; 372 pgquery = optarg;
370 break; 373 break;
374 case OPTID_QUERYNAME:
375 pgqueryname = optarg;
376 break;
371 case 'v': 377 case 'v':
372 verbose++; 378 verbose++;
373 break; 379 break;
@@ -529,6 +535,9 @@ print_help (void)
529 535
530 printf (" %s\n", "-q, --query=STRING"); 536 printf (" %s\n", "-q, --query=STRING");
531 printf (" %s\n", _("SQL query to run. Only first column in first row will be read")); 537 printf (" %s\n", _("SQL query to run. Only first column in first row will be read"));
538 printf (" %s\n", "--queryname=STRING");
539 printf (" %s\n", _("A name for the query, this string is used instead of the query"));
540 printf (" %s\n", _("in the long output of the plugin"));
532 printf (" %s\n", "-W, --query-warning=RANGE"); 541 printf (" %s\n", "-W, --query-warning=RANGE");
533 printf (" %s\n", _("SQL query value to result in warning status (double)")); 542 printf (" %s\n", _("SQL query value to result in warning status (double)"));
534 printf (" %s\n", "-C, --query-critical=RANGE"); 543 printf (" %s\n", "-C, --query-critical=RANGE");
@@ -642,7 +651,13 @@ do_query (PGconn *conn, char *query)
642 : (my_status == STATE_CRITICAL) 651 : (my_status == STATE_CRITICAL)
643 ? _("CRITICAL") 652 ? _("CRITICAL")
644 : _("UNKNOWN")); 653 : _("UNKNOWN"));
645 printf (_("'%s' returned %f"), query, value); 654 if(pgqueryname) {
655 printf (_("%s returned %f"), pgqueryname, value);
656 }
657 else {
658 printf (_("'%s' returned %f"), query, value);
659 }
660
646 printf ("|query=%f;%s;%s;;\n", value, 661 printf ("|query=%f;%s;%s;;\n", value,
647 query_warning ? query_warning : "", 662 query_warning ? query_warning : "",
648 query_critical ? query_critical : ""); 663 query_critical ? query_critical : "");
diff --git a/plugins/check_ping.c b/plugins/check_ping.c
index ba7af37..741f732 100644
--- a/plugins/check_ping.c
+++ b/plugins/check_ping.c
@@ -140,7 +140,7 @@ main (int argc, char **argv)
140 if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) { 140 if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) {
141 printf ("%s\n", cmd); 141 printf ("%s\n", cmd);
142 die (STATE_UNKNOWN, 142 die (STATE_UNKNOWN,
143 _("CRITICAL - Could not interpret output from ping command\n")); 143 _("CRITICAL - Could not interpret output from ping command\n"));
144 } 144 }
145 145
146 if (pl >= cpl || rta >= crta || rta < 0) 146 if (pl >= cpl || rta >= crta || rta < 0)
@@ -527,12 +527,13 @@ int
527error_scan (char buf[MAX_INPUT_BUFFER], const char *addr) 527error_scan (char buf[MAX_INPUT_BUFFER], const char *addr)
528{ 528{
529 if (strstr (buf, "Network is unreachable") || 529 if (strstr (buf, "Network is unreachable") ||
530 strstr (buf, "Destination Net Unreachable") 530 strstr (buf, "Destination Net Unreachable") ||
531 strstr (buf, "No route")
531 ) 532 )
532 die (STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr); 533 die (STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr);
533 else if (strstr (buf, "Destination Host Unreachable")) 534 else if (strstr (buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable"))
534 die (STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr); 535 die (STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr);
535 else if (strstr (buf, "Destination Port Unreachable")) 536 else if (strstr (buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable"))
536 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr); 537 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr);
537 else if (strstr (buf, "Destination Protocol Unreachable")) 538 else if (strstr (buf, "Destination Protocol Unreachable"))
538 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr); 539 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr);
@@ -540,11 +541,11 @@ error_scan (char buf[MAX_INPUT_BUFFER], const char *addr)
540 die (STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr); 541 die (STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr);
541 else if (strstr (buf, "Destination Host Prohibited")) 542 else if (strstr (buf, "Destination Host Prohibited"))
542 die (STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr); 543 die (STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr);
543 else if (strstr (buf, "Packet filtered")) 544 else if (strstr (buf, "Packet filtered") || strstr(buf, "Administratively prohibited"))
544 die (STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr); 545 die (STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr);
545 else if (strstr (buf, "unknown host" )) 546 else if (strstr (buf, "unknown host" ))
546 die (STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr); 547 die (STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr);
547 else if (strstr (buf, "Time to live exceeded")) 548 else if (strstr (buf, "Time to live exceeded") || strstr(buf, "Time exceeded"))
548 die (STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr); 549 die (STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr);
549 else if (strstr (buf, "Destination unreachable: ")) 550 else if (strstr (buf, "Destination unreachable: "))
550 die (STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr); 551 die (STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr);
@@ -553,7 +554,7 @@ error_scan (char buf[MAX_INPUT_BUFFER], const char *addr)
553 if (warn_text == NULL) 554 if (warn_text == NULL)
554 warn_text = strdup (_(WARN_DUPLICATES)); 555 warn_text = strdup (_(WARN_DUPLICATES));
555 else if (! strstr (warn_text, _(WARN_DUPLICATES)) && 556 else if (! strstr (warn_text, _(WARN_DUPLICATES)) &&
556 xasprintf (&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) 557 xasprintf (&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1)
557 die (STATE_UNKNOWN, _("Unable to realloc warn_text\n")); 558 die (STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
558 return (STATE_WARNING); 559 return (STATE_WARNING);
559 } 560 }
@@ -573,7 +574,7 @@ print_help (void)
573 574
574 printf (_("Use ping to check connection statistics for a remote host.")); 575 printf (_("Use ping to check connection statistics for a remote host."));
575 576
576 printf ("\n\n"); 577 printf ("\n\n");
577 578
578 print_usage (); 579 print_usage ();
579 580
@@ -583,29 +584,29 @@ print_help (void)
583 printf (UT_IPv46); 584 printf (UT_IPv46);
584 585
585 printf (" %s\n", "-H, --hostname=HOST"); 586 printf (" %s\n", "-H, --hostname=HOST");
586 printf (" %s\n", _("host to ping")); 587 printf (" %s\n", _("host to ping"));
587 printf (" %s\n", "-w, --warning=THRESHOLD"); 588 printf (" %s\n", "-w, --warning=THRESHOLD");
588 printf (" %s\n", _("warning threshold pair")); 589 printf (" %s\n", _("warning threshold pair"));
589 printf (" %s\n", "-c, --critical=THRESHOLD"); 590 printf (" %s\n", "-c, --critical=THRESHOLD");
590 printf (" %s\n", _("critical threshold pair")); 591 printf (" %s\n", _("critical threshold pair"));
591 printf (" %s\n", "-p, --packets=INTEGER"); 592 printf (" %s\n", "-p, --packets=INTEGER");
592 printf (" %s ", _("number of ICMP ECHO packets to send")); 593 printf (" %s ", _("number of ICMP ECHO packets to send"));
593 printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS); 594 printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
594 printf (" %s\n", "-L, --link"); 595 printf (" %s\n", "-L, --link");
595 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)"));
596 597
597 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 598 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
598 599
599 printf ("\n"); 600 printf ("\n");
600 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"));
601 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"));
602 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."));
603 604
604 printf ("\n"); 605 printf ("\n");
605 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"));
606 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"));
607 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"));
608 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/"));
609 610
610 printf (UT_SUPPORT); 611 printf (UT_SUPPORT);
611} 612}
@@ -613,7 +614,7 @@ print_help (void)
613void 614void
614print_usage (void) 615print_usage (void)
615{ 616{
616 printf ("%s\n", _("Usage:")); 617 printf ("%s\n", _("Usage:"));
617 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);
618 printf (" [-p packets] [-t timeout] [-4|-6]\n"); 619 printf (" [-p packets] [-t timeout] [-4|-6]\n");
619} 620}
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index 4872340..a025ee8 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -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_snmp.c b/plugins/check_snmp.c
index abe54cf..2601ccd 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -113,6 +113,7 @@ char *authproto = NULL;
113char *privproto = NULL; 113char *privproto = NULL;
114char *authpasswd = NULL; 114char *authpasswd = NULL;
115char *privpasswd = NULL; 115char *privpasswd = NULL;
116int nulloid = STATE_UNKNOWN;
116char **oids = NULL; 117char **oids = NULL;
117size_t oids_size = 0; 118size_t oids_size = 0;
118char *label; 119char *label;
@@ -375,7 +376,7 @@ main (int argc, char **argv)
375 } 376 }
376 } 377 }
377 378
378 for (line=0, i=0; line < chld_out.lines; line++, i++) { 379 for (line=0, i=0; line < chld_out.lines && i < numoids ; line++, i++) {
379 if(calculate_rate) 380 if(calculate_rate)
380 conv = "%.10g"; 381 conv = "%.10g";
381 else 382 else
@@ -472,8 +473,16 @@ main (int argc, char **argv)
472 print_thresholds(" thresholds", thlds[i]); 473 print_thresholds(" thresholds", thlds[i]);
473 } 474 }
474 ptr = strpbrk (show, "-0123456789"); 475 ptr = strpbrk (show, "-0123456789");
475 if (ptr == NULL) 476 if (ptr == NULL){
476 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show); 477 if (nulloid == 3)
478 die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show);
479 else if (nulloid == 0)
480 die (STATE_OK,_("No valid data returned (%s)\n"), show);
481 else if (nulloid == 1)
482 die (STATE_WARNING,_("No valid data returned (%s)\n"), show);
483 else if (nulloid == 2)
484 die (STATE_CRITICAL,_("No valid data returned (%s)\n"), show);
485 }
477 while (i >= response_size) { 486 while (i >= response_size) {
478 response_size += OID_COUNT_STEP; 487 response_size += OID_COUNT_STEP;
479 response_value = realloc(response_value, response_size * sizeof(*response_value)); 488 response_value = realloc(response_value, response_size * sizeof(*response_value));
@@ -661,6 +670,7 @@ process_arguments (int argc, char **argv)
661 {"oid", required_argument, 0, 'o'}, 670 {"oid", required_argument, 0, 'o'},
662 {"object", required_argument, 0, 'o'}, 671 {"object", required_argument, 0, 'o'},
663 {"delimiter", required_argument, 0, 'd'}, 672 {"delimiter", required_argument, 0, 'd'},
673 {"nulloid", required_argument, 0, 'z'},
664 {"output-delimiter", required_argument, 0, 'D'}, 674 {"output-delimiter", required_argument, 0, 'D'},
665 {"string", required_argument, 0, 's'}, 675 {"string", required_argument, 0, 's'},
666 {"timeout", required_argument, 0, 't'}, 676 {"timeout", required_argument, 0, 't'},
@@ -705,7 +715,7 @@ process_arguments (int argc, char **argv)
705 } 715 }
706 716
707 while (1) { 717 while (1) {
708 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:", 718 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:z:",
709 longopts, &option); 719 longopts, &option);
710 720
711 if (c == -1 || c == EOF) 721 if (c == -1 || c == EOF)
@@ -816,6 +826,12 @@ process_arguments (int argc, char **argv)
816 eval_method[j+1] |= CRIT_PRESENT; 826 eval_method[j+1] |= CRIT_PRESENT;
817 } 827 }
818 break; 828 break;
829 case 'z': /* Null OID Return Check */
830 if (!is_integer (optarg))
831 usage2 (_("Exit status must be a positive integer"), optarg);
832 else
833 nulloid = atoi(optarg);
834 break;
819 case 's': /* string or substring */ 835 case 's': /* string or substring */
820 strncpy (string_value, optarg, sizeof (string_value) - 1); 836 strncpy (string_value, optarg, sizeof (string_value) - 1);
821 string_value[sizeof (string_value) - 1] = 0; 837 string_value[sizeof (string_value) - 1] = 0;
@@ -1181,6 +1197,14 @@ print_help (void)
1181 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER); 1197 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER);
1182 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered")); 1198 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered"));
1183 printf (" %s\n", _("to be the data that should be used in the evaluation.")); 1199 printf (" %s\n", _("to be the data that should be used in the evaluation."));
1200 printf (" %s\n", "-z, --nulloid=#");
1201 printf (" %s\n", _("If the check returns a 0 length string or NULL value"));
1202 printf (" %s\n", _("This option allows you to choose what status you want it to exit"));
1203 printf (" %s\n", _("Excluding this option renders the default exit of 3(STATE_UNKNOWN)"));
1204 printf (" %s\n", _("0 = OK"));
1205 printf (" %s\n", _("1 = WARNING"));
1206 printf (" %s\n", _("2 = CRITICAL"));
1207 printf (" %s\n", _("3 = UNKNOWN"));
1184 1208
1185 /* Tests Against Integers */ 1209 /* Tests Against Integers */
1186 printf (" %s\n", "-w, --warning=THRESHOLD(s)"); 1210 printf (" %s\n", "-w, --warning=THRESHOLD(s)");
diff --git a/plugins/check_swap.c b/plugins/check_swap.c
index bb854be..ff58b15 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";
@@ -150,7 +150,7 @@ main (int argc, char **argv)
150 * The following sscanf call looks for lines looking like: "SwapTotal: 123" and "SwapFree: 123" 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 151 * This format exists at least on Debian Linux with a 5.* kernel
152 */ 152 */
153 else if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %f %*[k]%*[B]", str, &tmp_KB)) { 153 else if (sscanf (input_buffer, "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu %*[k]%*[B]", str, &tmp_KB)) {
154 if (verbose >= 3) { 154 if (verbose >= 3) {
155 printf("Got %s with %lu\n", str, tmp_KB); 155 printf("Got %s with %lu\n", str, tmp_KB);
156 } 156 }
@@ -389,7 +389,7 @@ main (int argc, char **argv)
389 TRUE, warn_print, 389 TRUE, warn_print,
390 TRUE, crit_print, 390 TRUE, crit_print,
391 TRUE, 0, 391 TRUE, 0,
392 TRUE, (long) total_swap_mb)); 392 TRUE, (long) total_swap_mb * 1024 * 1024));
393 393
394 return result; 394 return result;
395} 395}
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..286273f 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -134,7 +134,7 @@ 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 SSL_CTX_use_certificate_chain_file(c, cert);
138 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM); 138 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
139#ifdef USE_OPENSSL 139#ifdef USE_OPENSSL
140 if (!SSL_CTX_check_private_key(c)) { 140 if (!SSL_CTX_check_private_key(c)) {
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t
index ada6a04..693f4b2 100644
--- a/plugins/t/check_curl.t
+++ b/plugins/t/check_curl.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 => 58; 12plan tests => 57;
13 13
14my $successOutput = '/OK.*HTTP.*second/'; 14my $successOutput = '/OK.*HTTP.*second/';
15 15
@@ -188,11 +188,6 @@ SKIP: {
188 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); 188 like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' );
189 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); 189 like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' );
190 190
191 $res = NPTest->testCmd(
192 "./$plugin --ssl -H www.e-paycobalt.com"
193 );
194 cmp_ok( $res->return_code, "==", 0, "Can read https for www.e-paycobalt.com (uses AES certificate)" );
195
196 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f curl" ); 191 $res = NPTest->testCmd( "./$plugin -H www.mozilla.com -u /firefox -f curl" );
197 is( $res->return_code, 0, "Redirection based on location is okay"); 192 is( $res->return_code, 0, "Redirection based on location is okay");
198 193
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t
index c137f7b..0c86622 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
@@ -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/tests/certs/.gitignore b/plugins/tests/certs/.gitignore
new file mode 100644
index 0000000..79acaaa
--- /dev/null
+++ b/plugins/tests/certs/.gitignore
@@ -0,0 +1,2 @@
1/*.csr
2/*.srl
diff --git a/plugins/tests/certs/client-cert.pem b/plugins/tests/certs/client-cert.pem
new file mode 100644
index 0000000..5709750
--- /dev/null
+++ b/plugins/tests/certs/client-cert.pem
@@ -0,0 +1,22 @@
1-----BEGIN CERTIFICATE-----
2MIIDtDCCApwCAQIwDQYJKoZIhvcNAQELBQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYD
3VQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3Jp
4bmcgUGx1Z2luczEkMCIGA1UEAwwbTW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENB
5MSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMB4X
6DTIxMDIyODIxMDIxMloXDTMwMTEyODIxMDIxMlowgZ4xCzAJBgNVBAYTAkRFMRAw
7DgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0
8b3JpbmcgUGx1Z2luczEiMCAGA1UEAwwZTW9uaXRvcmluZyBQbHVnaW5zIENsaWVu
9dDErMCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9yZzCC
10ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM3EiqfFPomm5dZQPGYG5SrF
11rPvyqseXTzCkwUIUzGf+Sfm3s13zx7e3ije/04yKhTXgK59EQ793q7E2aWhSOz3s
12hwKKdylFkOIyc5jgbAfF1/pLZMK209rLt/mMRksXCRXYrHdTjRMx1ev4C2407+8Y
138qkf77DuYQmUqCQe7DPOvqLeagdw9JcLGmQNTKHg3fl6wyRl5K1Bsy+qXu2XvEjZ
140Ng7n8LHjOUkTqUEJndOxci9gL5cHU5ttul/GW34dKOtTuMU/pQX6/ywYusOGVOx
15RYI76OolRqj5BqbNctDIB/obe2RLo+UVx74/0jAxtH4XS23pYjO7NUpJcytsVG8C
16AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYfaY5n4pCq0NWPCdeVVRr4nr+GAfv1TC
17/PKcGuEoJZKt7TQT+OOA5yeZMZb53OvtA49D1r9aoJzWe946KElWOEBqxDRi5Cdr
18wkqpwGcPT2RfAqA3/cvQZ1XsquboXrCf7ajdl5OC64bs2jkqCFh9gnxuI140g8Ar
19Njol8BFxRPaYWOnwuQwmh/2t0FJqr3WSD85HrNqtxUSNGbTdSsvCfgF0v7QVkvLG
203/cbx6z5hxzj2JUjhMnCvn+EbasoJt4xyBFvg67Q2229SMwu9YNqS63GVoKUqhCB
214Gl5v31qx8dAFKuRvnez3ze/6oohwmakZkst4hcQdgZocHhzesvKlg==
22-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/client-key.pem b/plugins/tests/certs/client-key.pem
new file mode 100644
index 0000000..09b6761
--- /dev/null
+++ b/plugins/tests/certs/client-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDNxIqnxT6JpuXW
3UDxmBuUqxaz78qrHl08wpMFCFMxn/kn5t7Nd88e3t4o3v9OMioU14CufREO/d6ux
4NmloUjs97IcCincpRZDiMnOY4GwHxdf6S2TCttPay7f5jEZLFwkV2Kx3U40TMdXr
5+AtuNO/vGPKpH++w7mEJlKgkHuwzzr6i3moHcPSXCxpkDUyh4N35esMkZeStQbMv
6ql7tl7xI2dDYO5/Cx4zlJE6lBCZ3TsXIvYC+XB1Obbbpfxlt+HSjrU7jFP6UF+v8
7sGLrDhlTsUWCO+jqJUao+QamzXLQyAf6G3tkS6PlFce+P9IwMbR+F0tt6WIzuzVK
8SXMrbFRvAgMBAAECggEBALtc2pB3p0E6KpAiEU0pvCRdSO1FgsIpAd+eNadRPur2
9fi+XWQkUwGeGBaJL1npja3aqP65PP40pj7nWfNaUAgOZyznCEU0QXiPJor6yo0vU
10l5v+aKpwRao107i0RRF80TYGTMx+1LeEqnCqNOZN56gERHlBbkTiWpOZvBzf1143
11oegTcyM6+Ee6+FYNhHaDyIYD0md1S2wGR+IBPet6HwWiakLNKahFPa7lOLIKfmmD
12iTtifcbf4724wSe44a0uTeP4JrquZSeIKakm8MEmffmYqpycnaakYefd0Xc5UEsH
13+VbhKpOWGY3d8FKHqUsTa+6QyXb2uFPo6A+yWm0pdJECgYEA7Prd5sbWACvXOcHT
14ONDBAgyfAVDQwOXi3D4dk6D5mg+/jxl5ZQY5slszJrwsLFtoEzXtYpNfTy3cpNOp
15JLbBDZYnqty+5tD8t3/Zv2IBXCAgvuk5CgfJWP5FNAfiyUEE6Vbp6J/5/vAnODsa
16fxZryN5UsH0X8ew7AlbfcVNyj4kCgYEA3khetIgn+GR6sv9jFRdCT6aJbp0xMsms
176F4v3L5FG4Kp+SwDHL1bVOhieJ5g8odYp9hDbgTEEqbJfNmyCOu9+OQmZ/mztku7
186reU8HhYBIvi+hFeJmvqKpdIgU0Zveg4Bst5QordmhPk8AHjBC4xvQ++uh7rwYKd
19WVsS08bGDjcCgYEAlAuNARUKsASzakOqHv5a9VrJIttH7povBYRQmd+gzxwzgcRa
20UEB5XvEWnYZE2lkoRYgVCtYiXqa6BsasDmGVbVV25okNQckhd8mJUMR7MQBpNJsi
21pR+EK/J9bSnYBf52gQdpDYiTdy60ca6KuQZaw5wRsEgV426+1pFK+dM16HECgYBY
22cTsdYb9lmbUoW201CxgbUQwFsw3MQ2pE2pT4o8wjcg3nUpe6a61XT08+5uV0Gl4w
23CmBp+gN52Fr7DjNEUWg5C64sWLIkqmWOspTUSU3cITyiex6W8wEtCRyUNfU0Fp2U
24Nol87HvXvmqtBFMraqXnr8gXjg4H5MxurUoEcWaEaQKBgCT4iIGZwW0Qf2rkFC7B
25xObzVGefivVVbaf8/c/LRO8TMLdnExkShMOmCzHeHV4mMEZDLbMOusHCI7xm10EX
26l3L1I1Kyqnhm1RH3e7TVWgkTmIDW3V5Fgrhm1jx5Iz6et4sb4Uh+bZq9tTLyqfZY
278s0yJUrfpjRggfk7eUs5s7aY
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientca-cert.pem b/plugins/tests/certs/clientca-cert.pem
new file mode 100644
index 0000000..9ce7cd7
--- /dev/null
+++ b/plugins/tests/certs/clientca-cert.pem
@@ -0,0 +1,25 @@
1-----BEGIN CERTIFICATE-----
2MIIEIzCCAwugAwIBAgIUL9Jfp5zv5B29NgDsNEFU2OM/UHswDQYJKoZIhvcNAQEL
3BQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEkMCIGA1UEAwwbTW9u
5aXRvcmluZyBQbHVnaW5zIENsaWVudENBMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBt
6b25pdG9yaW5nLXBsdWdpbnMub3JnMB4XDTIxMDIyODIxMDIxMVoXDTMwMTEyODIx
7MDIxMVowgaAxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQH
8DAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEkMCIGA1UEAwwb
9TW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENBMSswKQYJKoZIhvcNAQkBFhxkZXZl
10bEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
11MIIBCgKCAQEAyxiWsGrsJFHw3VR0pqHviXUfbfKMw8LaCxI5EQZfInsMVkBIGWEW
12tFW6qDuAOsMdzsrKOnQRNNt852ts/0Uz++z8zysoauAGpc4JnCZuM5A1DU5CFXBx
13w6Ax+1ft3UsTt8C6kfLfs8mPCbtNVqAHrMrIqDxsNSRRxQSqkzp1vD8rwSKcbB1h
14u2+lut1bEqMe7dp89jKOtc6G/1tHUFQuLAGFoX/qk9yPscmQNzL6YbLP4m9r/416
15PsxWsAfyY97hmoYo6mSCue5LmeanOsjf4Kzq90hIJRwrpiUGmxGjW+tPLEhQBZw6
16C2wHyN74YIJYX2xREz2ijT0mgsqdhO5ZxwIDAQABo1MwUTAdBgNVHQ4EFgQUtsP9
17Z3fKkhmFp97Kh/cW/UqHMIMwHwYDVR0jBBgwFoAUtsP9Z3fKkhmFp97Kh/cW/UqH
18MIMwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEApO5o+YECwTEv
19s+elDJZQ20UYwDSiU9Lpf4EcdnRv6FAb5UlhfRTH3ZdKCc/HX7kcKuy3PsF+b8Pw
20EusoKito9OlNEOF5HYAI9/J54/qceqn+SC0INsISeE19PvT0dma7lBSj4OvBv0IS
21GYbdztVaKLWqYgYs0mcEzteUc4MZcy1/C+Ru1i1Kp2s9/vIeAw2PV2+kpWtw88Pb
22FRJomGngP/hQdwniayCltG/Q1smS4iFEHNI5ayLZj1qJGMHwzqGiRr4KknJKfHzv
23fl4NQaFyMY31s1FRIS6QVIRFHVzUAlKZTdzwqEJygg3fUS9n9uDBnyDI/sW7DQuj
24yjSmYRS1hw==
25-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientca-key.pem b/plugins/tests/certs/clientca-key.pem
new file mode 100644
index 0000000..a939f03
--- /dev/null
+++ b/plugins/tests/certs/clientca-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLGJawauwkUfDd
3VHSmoe+JdR9t8ozDwtoLEjkRBl8iewxWQEgZYRa0VbqoO4A6wx3Oyso6dBE023zn
4a2z/RTP77PzPKyhq4AalzgmcJm4zkDUNTkIVcHHDoDH7V+3dSxO3wLqR8t+zyY8J
5u01WoAesysioPGw1JFHFBKqTOnW8PyvBIpxsHWG7b6W63VsSox7t2nz2Mo61zob/
6W0dQVC4sAYWhf+qT3I+xyZA3Mvphss/ib2v/jXo+zFawB/Jj3uGahijqZIK57kuZ
75qc6yN/grOr3SEglHCumJQabEaNb608sSFAFnDoLbAfI3vhgglhfbFETPaKNPSaC
8yp2E7lnHAgMBAAECggEAJqAWiJbNMlsjI/Tb+pTxqYLM52wpuVFlhpWApOxBS517
9SywOikUcvE9RoI0wZfyVvq5yp4tLenID3z9fC21t5Yu8yOm8VhclLINy8G+epc/X
10RyCLEOjBuiLNXq/qXRvaNChDU16NjPPYcFFe9AqbaxFl+BkFu1Wc94tbpYSIv7Qt
11L6iBxUTXdgvLM5doa9AazIQzJx+jUsVCgRVQQf3zsLqtp9hH0Pfq+KWFIy5TA+bG
120NFmYyQndRjtT0ihWGuNU7D8AXa+z7abzk+HydIlx4D//vGgdNq92QYPdnu2BBya
135Fs6LkmkUonX/I8FbkLbRKkQWNPMt+Ks21t3xcVBgQKBgQDn4HuHVCPwxgU6Mv+5
140sHJXYBq1fDzrUt0+iTtYkRqViX+9Mp4sUpYgXext/wXFLcKzQQp5B0g1dLYLSRS
15KwhsdiN0J7ZcoP1GMStw8zsayRTf8C3WRU6aACqyFiylYbyh56XomfYgwhja/7l9
16pzpVJD9ecG+mLVAyAkJtK2JolQKBgQDgOZfvrQj0L4QG+9E5VmFc3PE+6k3g+zDO
17MWqTSh0fOHqdTEyet4bMC4DogXGVsvw0/UKwbrGHOk0+ltA5VyKUtK/whSutr/+S
18nhCHljhV0XUN/I3OFcvezFjM3g0oC4uy1cL30hoM4IfeHM1d3EYse9N1Y/Op+mR6
19Sx+fEku16wKBgQC0KQ7RjuZ95N2a4pUe5En9EtD8MU4Nhs/iC5k1d+yAUn8jIT9P
20lzCUo8NEKheMN2Qg2Dor8jlPkdNIc4qM7TKWUxQo49IlFlCzgPCnydRac3HsrMhw
21e1ke/pIt3FzEArR1d27I0xcRTL3TKm4M2ynPjWJPFj0peHue33KNL/A+IQKBgEpL
22awd0Sxo1wEZcG9gmwf32C01wbzuTn3lCsHB7Ryj4GtCR3nVclCJ50U24zjzu4Fhi
23bj1tgA8xhzSs3fOR5phlQkKsrWtQfJtFGm8CnEn7LBDlVMsrN7Dr/qRrEuro4HHy
24GDbq+8y2fO5glr955BqLMOadprf0imRnDeQ0OLffAoGBAJio+X+xpglgMOC4BeH9
259LcYi9nUEw8MDJNGo9/3e0XKA7spd3HShLDvt8YZhFJ2m168qBpGfezuw0+jpWxy
26PV9q0dokAgDx4pvCzIKaptZ1D30CWXJZHq25VK1tA41PCUIOh8JD5+R0MpxA5rn2
27DbqL4Vq7K7K0imGENYhHdyM+
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientchain-cert.pem b/plugins/tests/certs/clientchain-cert.pem
new file mode 100644
index 0000000..acd1e3e
--- /dev/null
+++ b/plugins/tests/certs/clientchain-cert.pem
@@ -0,0 +1,45 @@
1-----BEGIN CERTIFICATE-----
2MIIDuTCCAqECAQQwDQYJKoZIhvcNAQELBQAwgaAxCzAJBgNVBAYTAkRFMRAwDgYD
3VQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0b3Jp
4bmcgUGx1Z2luczEkMCIGA1UEAwwbTW9uaXRvcmluZyBQbHVnaW5zIENsaWVudENB
5MSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMub3JnMB4X
6DTIxMDIyODIxMDIxMloXDTMwMTEyODIxMDIxMlowgaMxCzAJBgNVBAYTAkRFMRAw
7DgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gxGzAZBgNVBAoMEk1vbml0
8b3JpbmcgUGx1Z2luczEnMCUGA1UEAwweTW9uaXRvcmluZyBQbHVnaW5zIENsaWVu
9dENoYWluMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdpbnMu
10b3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAphvoJBbi/rDvm3+X
118xok0sLCJvCRuUpSbU5wEmREQlkoOGmWK4l6r1JyOphKRBo8+n2MxPiCMvAmTrqx
12VlBmkcmyrwWj392Nga+2SLWTziASk5nFrrhV6U79PkgXnETV2Wk1/FNVIFkB8N+B
13undsTce8LLiCs7hfA5CK7ctJg8fqsAsmgKBNGzBRWwkbvxZPd6xlY6foIJeD7PQ2
14elvTmrD6WXSZq7GshFpDEkL3AifqrPMdsTnbBpyGgJ/fBM1b2dx9k53e25mgEQmn
15iSuYQxn08BsUT0FOvav8ksZLBQz859fuqCtwhikpODO635fD9zK5YkBPlVl+/5xo
16SvKOywIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBh4zeSKjENfY+VDLtPssaNQz2a
17R1ioY40lZ0WoihDSrfG32dqTK/R2YsLKBABjJ7uRYS1NIBMrtS2OktK8BWD5IUTF
18FuGuWilu6IWiTKZrLiZh1rsilNDVqwhorRPxDnbF+qVt9EMIvzKnKdJLGF+CWHN9
19yYJDeTD8MK5uR7zUJR3PsgW4ve5pFTi7z2UJ/xRvgOds6bmeeQnvaWDEL7k2+hrr
200G899A086NL3htzaOnIllg0xo2D1o4ToncAJn+cUQVJmHZSg9HYiD4Lg3z8uXPAl
21rt/MX7dBm4dnImLXbSg7N3e8FdUtz+kZT9z+beKAeIe9JTbpxtsVUTzUZBBA
22-----END CERTIFICATE-----
23-----BEGIN CERTIFICATE-----
24MIID2jCCAsKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBoDELMAkGA1UEBhMCREUx
25EDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwSTW9u
26aXRvcmluZyBQbHVnaW5zMSQwIgYDVQQDDBtNb25pdG9yaW5nIFBsdWdpbnMgQ2xp
27ZW50Q0ExKzApBgkqhkiG9w0BCQEWHGRldmVsQG1vbml0b3JpbmctcGx1Z2lucy5v
28cmcwHhcNMjEwMjI4MjEwMjEyWhcNMzAxMTI4MjEwMjEyWjCBqjELMAkGA1UEBhMC
29REUxEDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwS
30TW9uaXRvcmluZyBQbHVnaW5zMS4wLAYDVQQDDCVNb25pdG9yaW5nIFBsdWdpbnMg
31Q2xpZW50SW50ZXJtZWRpYXRlMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9y
32aW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
336rUgOZ9pAOxrcgeeOT3Vmu1YmY2O/C9tXhpKzDzjTaWUzcdDg00KdsjXfgbDzSiV
34uvMzjX63aKpmqeFG+05D2VzQGit3knqerUgl10FnTotiJGF5CU5/gY1aPxTJ7rj2
35tD6LINBkJcPTyQ4MoJT19pssvCax9erY1RxoXxLblJ+31C+VvrftdmBP4nVKXK26
364anb1oUQhkgpXpJimJBmF+v7NbDs1Wh21Be80KXUh9SKgePhSQblr2QlRcA7jLgJ
374PMjZ+KYF+da+4RB7s+DvTXVDMn9AL84E1w5Ut1E8XZV+u4RjWPvNdhK/7GnuxOR
38C9SdxonqkPQ8hiI7thP9bQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
39SIb3DQEBCwUAA4IBAQDKQeiDbyr0/7sEhX33MmTDv84GeWgKl9qqHecx+d/0vImb
40c8XHK0PDa4lVqo/BW4P1hjKzpt2DW35kbOhuqGqM0lasIczef43aCDDEBLwstAe6
41qMoyWGVGoAQbpwT3li2pMrsIYoPwMvoSGNUphjrkdpviff2POkLly7a5RrR1X3qt
42Dai6eYbeMCr9NdgW7AZ5++/sKlFoe+zVk/Ed31s4D2lh3awrApZhVgcoquPmEwpt
43gm+OgRmHw50U4SF3ZaJPwDyLMbx+clH/bgUg0+Za9e53Br1NtGKmw7hh/7CG/hy0
44yxeLd930pH4vZu7s0XM56N/ckkfUzRkAH8dSmhH4
45-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientchain-key.pem b/plugins/tests/certs/clientchain-key.pem
new file mode 100644
index 0000000..0263604
--- /dev/null
+++ b/plugins/tests/certs/clientchain-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmG+gkFuL+sO+b
3f5fzGiTSwsIm8JG5SlJtTnASZERCWSg4aZYriXqvUnI6mEpEGjz6fYzE+IIy8CZO
4urFWUGaRybKvBaPf3Y2Br7ZItZPOIBKTmcWuuFXpTv0+SBecRNXZaTX8U1UgWQHw
534G6d2xNx7wsuIKzuF8DkIrty0mDx+qwCyaAoE0bMFFbCRu/Fk93rGVjp+ggl4Ps
69DZ6W9OasPpZdJmrsayEWkMSQvcCJ+qs8x2xOdsGnIaAn98EzVvZ3H2Tnd7bmaAR
7CaeJK5hDGfTwGxRPQU69q/ySxksFDPzn1+6oK3CGKSk4M7rfl8P3MrliQE+VWX7/
8nGhK8o7LAgMBAAECggEAAfTqMyKh4eYrrGVAYPi53lG0/8htrwUVG3yFDXJo628p
9biCwSCsCavZJqi8JEOxOM5UvB1L2FauGh/7i/+VKkAUUOcOTPpvZguGTACBDcXYn
10Qd3Z2kkJmgn4Kbenr4uQCVOX8zT4F710rGW1nYCyoefsa4pw37UYSW52dH6kiwzW
119k4X251nDMl/twBdOcjZbL768IEa5l4nySLpUNwfrVbSb1NzBoH0dVioh3DTLjt6
12gaShW4eIpaKczht1U97n6/7WNLl6vHX/mR99k/py8OhzhR1ccYpd2IfSHAWyQT0M
13K8BoNnkjICrr9oc0FCr2BVJa3IzKHlhukF4GTZiGYQKBgQDWCHTwAmwL4FFEBVhj
14pZne/sjaZc8TzPPxA8SkmxwDIZrM7tSu7qUuYgWTM432jZbLILWTyGfXf2PpqyF6
15wOpoBJj1ETkre8ZfRmYvsSvS5vtjF3Drszol+XvZnOclfB5VG3m5P2vYkQ8wI9OE
16Y5jUBgDj0RsCNd8QnrC1u54U/wKBgQDGrd5y8S9kUT0P0lkZit7bYjSPJExtClXt
17V7YNTjELrVCdc0jranxBWaub8NP3e6TGTi9HiQWvk2eOAS2qyccqlK4+YAK5XO3D
18EpFUNNcClq8CErw2POuCAKajrPuSp6vd6q8h4lTzDExVctQS4R9fRKKFBKkPUV5G
19UiKFllnKNQKBgQDBGIQXfLfpxwjKK2BhFihKDOc8UhmOrZtvV4zzTJTrJkg4l0f+
20QoN34ytQcHSleXwP6oSmvWkh/GYxjBj6XE2eZndwsYc4ecSwdB0A7gCxl345Gg7g
21NqRBWmGoJGxNXzsmYVFiFZvAmK5xKgFMMWbR8lCfOCn7xopmviSC8K9gFQKBgFRb
22KmH/SbH8VELNews/TVQ0pEBKlzCM/OLjJOcNVgGxOtM/Say677sHibeST0168AFK
233QQwh3t+yK8gjPVA6xGHQ1w0g7OUY1c6IP5x2QC+XdwxfDxDLXNrN1WzcrVX/78f
24j/CBGrR/ekGlmanSb/GRQLfdvLJGSBLveLzjk4gpAoGBANN9RUm/aRz3dDBWex46
25kJ15xKJfLZiUeyDvY5+5d7YF4/tw5LU4XmKQNhiojHecykrTzPUMaGyMrbMPNn32
26WFW9CKMjuBEwWpMDJJb1/5NLEvpwu++sr7bUPZkQl76ot6OqgNHodbP8ATqrNr80
275b8FrEN1LyfkTbabxNyAWcA0
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/clientintermediate-cert.pem b/plugins/tests/certs/clientintermediate-cert.pem
new file mode 100644
index 0000000..608a8fa
--- /dev/null
+++ b/plugins/tests/certs/clientintermediate-cert.pem
@@ -0,0 +1,23 @@
1-----BEGIN CERTIFICATE-----
2MIID2jCCAsKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBoDELMAkGA1UEBhMCREUx
3EDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwSTW9u
4aXRvcmluZyBQbHVnaW5zMSQwIgYDVQQDDBtNb25pdG9yaW5nIFBsdWdpbnMgQ2xp
5ZW50Q0ExKzApBgkqhkiG9w0BCQEWHGRldmVsQG1vbml0b3JpbmctcGx1Z2lucy5v
6cmcwHhcNMjEwMjI4MjEwMjEyWhcNMzAxMTI4MjEwMjEyWjCBqjELMAkGA1UEBhMC
7REUxEDAOBgNVBAgMB0JhdmFyaWExDzANBgNVBAcMBk11bmljaDEbMBkGA1UECgwS
8TW9uaXRvcmluZyBQbHVnaW5zMS4wLAYDVQQDDCVNb25pdG9yaW5nIFBsdWdpbnMg
9Q2xpZW50SW50ZXJtZWRpYXRlMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9y
10aW5nLXBsdWdpbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
116rUgOZ9pAOxrcgeeOT3Vmu1YmY2O/C9tXhpKzDzjTaWUzcdDg00KdsjXfgbDzSiV
12uvMzjX63aKpmqeFG+05D2VzQGit3knqerUgl10FnTotiJGF5CU5/gY1aPxTJ7rj2
13tD6LINBkJcPTyQ4MoJT19pssvCax9erY1RxoXxLblJ+31C+VvrftdmBP4nVKXK26
144anb1oUQhkgpXpJimJBmF+v7NbDs1Wh21Be80KXUh9SKgePhSQblr2QlRcA7jLgJ
154PMjZ+KYF+da+4RB7s+DvTXVDMn9AL84E1w5Ut1E8XZV+u4RjWPvNdhK/7GnuxOR
16C9SdxonqkPQ8hiI7thP9bQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
17SIb3DQEBCwUAA4IBAQDKQeiDbyr0/7sEhX33MmTDv84GeWgKl9qqHecx+d/0vImb
18c8XHK0PDa4lVqo/BW4P1hjKzpt2DW35kbOhuqGqM0lasIczef43aCDDEBLwstAe6
19qMoyWGVGoAQbpwT3li2pMrsIYoPwMvoSGNUphjrkdpviff2POkLly7a5RrR1X3qt
20Dai6eYbeMCr9NdgW7AZ5++/sKlFoe+zVk/Ed31s4D2lh3awrApZhVgcoquPmEwpt
21gm+OgRmHw50U4SF3ZaJPwDyLMbx+clH/bgUg0+Za9e53Br1NtGKmw7hh/7CG/hy0
22yxeLd930pH4vZu7s0XM56N/ckkfUzRkAH8dSmhH4
23-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/clientintermediate-key.pem b/plugins/tests/certs/clientintermediate-key.pem
new file mode 100644
index 0000000..13f6887
--- /dev/null
+++ b/plugins/tests/certs/clientintermediate-key.pem
@@ -0,0 +1,28 @@
1-----BEGIN PRIVATE KEY-----
2MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDqtSA5n2kA7Gty
3B545PdWa7ViZjY78L21eGkrMPONNpZTNx0ODTQp2yNd+BsPNKJW68zONfrdoqmap
44Ub7TkPZXNAaK3eSep6tSCXXQWdOi2IkYXkJTn+BjVo/FMnuuPa0Posg0GQlw9PJ
5DgyglPX2myy8JrH16tjVHGhfEtuUn7fUL5W+t+12YE/idUpcrbrhqdvWhRCGSCle
6kmKYkGYX6/s1sOzVaHbUF7zQpdSH1IqB4+FJBuWvZCVFwDuMuAng8yNn4pgX51r7
7hEHuz4O9NdUMyf0AvzgTXDlS3UTxdlX67hGNY+812Er/sae7E5EL1J3GieqQ9DyG
8Iju2E/1tAgMBAAECggEACyYJXtNUoIeaXvM/r8ZhJBfMEpcnyJDUKBklnmfyABky
9ZUfmzBDXw2as3b6ihFc+LYAp3bm8KouVjtI1lfBUxrli5StVZa7PZLm9mmjv6Eo0
10ojfDEQ8afWPieoaZRO6iQVOLNkbPyv9vSuiQ7vvEZy9dw54u69h47j6IMqPprDiG
11ropUNeGAvTnh1Vf9/8aCHEvHUNHcc4zjzGiQ+E60JgnbpGVeJKoeiMgrQE0yjweo
12KyKA47Y6vqP6+AxAaPplXtmrx2UCbMjktHNvLvg42+2UlLS5roiwmJYEN9c6iT6t
13y82MJrjEFGZyLG2u6ZQANSJiIWaCnOyT1o2deJ8NoQKBgQD7UxivDTuljQD0so+E
14JX9UaFZ9PgS+8LC9v56PciL4XQ7bcCVP5vVgZZPABiQ9i989Wq7qI042Jrfu5qtE
15SthlOAu80GvAQV+Oujwo7ZzM6ciQtjMsj63r2uayWXnmQ07QcIg7x7y161Pt9Bqr
16LIDrqHziIj/lzT7+6QKZaQwFaQKBgQDvEuSC14CBlMhy2jji71kB/3Ya3c+8dP+A
17kQZL9wEWK4a4dm8IaTS8jl1/luhQUzFRMyh2rWaTqqigSe3dvs5DRblhE5NPwTSI
189TO7t1EnzjW3R8LxZZsySyiSFnZ/8mR0empxq0Mov37OdXBj0tXuuzREf/hwijWh
19WuLxJUSjZQKBgAIDZ2Y3l+u6lnBfYdDwL/XwJAk6zvTsnq3WdCG4C1mr/St62YGr
20WvnbtnRKWE356d7m9BHCGKVMaBrM1EBmzRb6fPWVQde3blmJWmQFi0UE9mtaWkyY
21Fg+WoFR7bQOQNHhs/lpkPjnC2dhFJVWLtLiuj9mL5rEjlMab/T5XXhZJAoGBAMEP
22FZ8fXbPGrTQqSwPfWpZFcF9zvbynEmkFM/uGRMddcNZnNXSqWJ7nrFNLTuEGvW2g
23DU4A6zPV/YQrDz4hRjmHBZOCFlSyZbUvpY4yFAQ7/p66AY+kiHZNwT5vi1P5Luvs
24qyaNsZcnRMR+i7rg2EeHv0aNvNdMlNBvL5KikNINAoGAU2P/phdwJOUcqgHavQcQ
25ureTEyZ5i5AeNomNeHSj0slG24V9nxOqEL7D00JKln7oAPovYBUWocEnF39uBJe0
26p0Hy7fCCK6EI8/0QyiQuuZmJfDEEvjQqE6irONNH63r2UwDEpDNGFvGsZNuWHLZc
27SXADu5oSNu6o6IydiyOx528=
28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/expired-cert.pem b/plugins/tests/certs/expired-cert.pem
index 77a9166..87fc8e4 100644
--- a/plugins/tests/certs/expired-cert.pem
+++ b/plugins/tests/certs/expired-cert.pem
@@ -1,24 +1,24 @@
1-----BEGIN CERTIFICATE----- 1-----BEGIN CERTIFICATE-----
2MIIEETCCAvmgAwIBAgIUFDsP6WnV/uqeQMpD/DYSqouE13kwDQYJKoZIhvcNAQEL 2MIIEETCCAvmgAwIBAgIUVDKkhcUoYFnjYCw12tScPIqQzqIwDQYJKoZIhvcNAQEL
3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN 3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u 4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u
5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n 5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n
6LXBsdWdpbnMub3JnMB4XDTA4MDEwMTExMDAyNloXDTA4MDEwMjExMDAyNlowgZcx 6LXBsdWdpbnMub3JnMB4XDTA4MDEwMTEyMDAwMFoXDTA4MDEwMjEyMDAwMFowgZcx
7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx 7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx
8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu 8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu
9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp 9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp
10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyeHKwKFjJWUX 10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwg1dmGT3rVqM
11YHKsisypUf9dHlIPQAISyGP1BX6UL26ZLvE6kKbx3LFQ9W2POGoQWlzFiB1soGeV 11beVWWLy8EAiq9re07AF8sTERy9oIYF5EUq9f0xO53mwwqIWV77O9mF99/kDFGQuQ
12WDd0U0JtWdCKmOXWdcXpupQlTSUtRCMDQkfqLN8GR5TBTd73rezp5mz08nMfLwu0 12NOnICMSHXNtMXEXzfBaMighw0uyCh1o/VCejNQ5x/HU8aLh930g5DIcOJQ3fZ4v9
13p5VQ191Ui8JHFgrAOalAn8Uw5De8vj4VmTXmU5NJ2UFoC0ddU/Th/lwRCayHc1cn 138kBaie7+aPgRMVDM1vIrILfedq9Kt56zvPizkXhDeqxjKyIZdrdoBlX5zAfftWtY
14MVq2F7c/uhMUUQYNBmJy0pxoHawp+j9NKl/xIYsjgQNgahQyNuswuGHjaEwhPu+7 14HpQ+lkThSSXqQnchN6S2JFejmRtsNnceDVOBBdvlzmH0NlfwjynLK3/EJooTsINy
15G03XsW4ehu+H1898M/MkSln6LQAU1syoJ8ypPM8tV+zgx4uwj7udnZ2hceN95uW7 15i9dXD8/Oe8r+UA+nokWvnWC2IAUJjpxW+XAyTG/NofGwX+PwquT0YD5cSlODIwZA
160PWg5DQyUwIDAQABo1MwUTAdBgNVHQ4EFgQUt9ps3KJ1XiMuy/ijFBjMzf6jgwkw 16WAimygWLqQIDAQABo1MwUTAdBgNVHQ4EFgQUsKyJAwR9OXWEcSZMQz73GfpxCJIw
17HwYDVR0jBBgwFoAUt9ps3KJ1XiMuy/ijFBjMzf6jgwkwDwYDVR0TAQH/BAUwAwEB 17HwYDVR0jBBgwFoAUsKyJAwR9OXWEcSZMQz73GfpxCJIwDwYDVR0TAQH/BAUwAwEB
18/zANBgkqhkiG9w0BAQsFAAOCAQEAVPBZwMHbrnHFbmhbcPuvYd5cxk0uSVNAUzsl 18/zANBgkqhkiG9w0BAQsFAAOCAQEAYKFGX7J3Fc/T9s278w61E2dSsY4DS/mjSDik
192biCq5P+ZHo10VHGygXtdV4utqk/IrAt2u5qSxycWPStCtAgTd3Q8ncfjOkaHM4z 19fMWvod6eKw0fE3wJOnkWxjEH3VywTY6CmHd/oiJOaD8lr/Vk+BJfYNVBaVNmguyg
202bxTkhLyQeU8NWPuDBqDszo2GOaFTv+lm36LEKiAfqB1tjQVePSkycdrWIhkamBV 204LXoWz9Benx0bAIeuDbNAhOvA4H4aIz8UrD9lKFvKdRp42gPMLtMEbzbLcBdT95D
21EgMe6uHLdU7QQk1ajQfrBdakN1beqki/dKieA6gm+XF/QS4SSYINmsHB/2X5cT9U 216BX7EhYm7vTnpitLPgFxVCsJ1JFqv2AQfUm+IkqQkezPs5x0tWLyrvCDNRGJ0kfv
22b/KMB8xurCnuJQuk1P4VsSkJCOSeHjWZgK9pKNdsIJZr4wDVfhjQgU0XT6xakSf7 22UuowpUZXDOh3k1vB+xaSOFviieLaCW8TSdd5FZgI2HQj4e6vCKsMGuKKZXrMUTI/
23eCaHtO0VKsbLZoiTmpxidjsdYiXyeKYIQNtUpTjyJ5V/cZsq9w== 23qtrFlUfsOuwourfC5LMHtCyYo5B3uvAWT1eTXxhrGqyleSlxJQ==
24-----END CERTIFICATE----- 24-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/expired-key.pem b/plugins/tests/certs/expired-key.pem
index c1510b2..c5bba56 100644
--- a/plugins/tests/certs/expired-key.pem
+++ b/plugins/tests/certs/expired-key.pem
@@ -1,28 +1,28 @@
1-----BEGIN PRIVATE KEY----- 1-----BEGIN PRIVATE KEY-----
2MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDJ4crAoWMlZRdg 2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCDV2YZPetWoxt
3cqyKzKlR/10eUg9AAhLIY/UFfpQvbpku8TqQpvHcsVD1bY84ahBaXMWIHWygZ5VY 35VZYvLwQCKr2t7TsAXyxMRHL2ghgXkRSr1/TE7nebDCohZXvs72YX33+QMUZC5A0
4N3RTQm1Z0IqY5dZ1xem6lCVNJS1EIwNCR+os3wZHlMFN3vet7OnmbPTycx8vC7Sn 46cgIxIdc20xcRfN8FoyKCHDS7IKHWj9UJ6M1DnH8dTxouH3fSDkMhw4lDd9ni/3y
5lVDX3VSLwkcWCsA5qUCfxTDkN7y+PhWZNeZTk0nZQWgLR11T9OH+XBEJrIdzVycx 5QFqJ7v5o+BExUMzW8isgt952r0q3nrO8+LOReEN6rGMrIhl2t2gGVfnMB9+1a1ge
6WrYXtz+6ExRRBg0GYnLSnGgdrCn6P00qX/EhiyOBA2BqFDI26zC4YeNoTCE+77sb 6lD6WROFJJepCdyE3pLYkV6OZG2w2dx4NU4EF2+XOYfQ2V/CPKcsrf8QmihOwg3KL
7Tdexbh6G74fXz3wz8yRKWfotABTWzKgnzKk8zy1X7ODHi7CPu52dnaFx433m5bvQ 711cPz857yv5QD6eiRa+dYLYgBQmOnFb5cDJMb82h8bBf4/Cq5PRgPlxKU4MjBkBY
89aDkNDJTAgMBAAECggEACrLFfNnQmD24NGs/S4e2/VpsA9xTZI/3kNkDNgxULANP 8CKbKBYupAgMBAAECggEBAJ2mdCKJ7LoWdT4W8pZ3BqZUFGkKCF8wOhhOUDH3+ZQp
9aNZtxRajwI9A/BCXQ2UTgsZhzWnJxOJYXrlpl7PweY78mUesysb3MOUC6QisUm0M 9IYK3XbdDMF7mMIXIuW4a7W4sLlTwU/Ar98U1JMESwRIMS7YvUke+ngDKKLcDVGwY
10kimfdktHWOnAKLFFLNleN9DUVjjVkTeslijqhNX80f80py1grG2UuCLKCX4OqYIm 10Qpjg9vP0v2Al8qT1NbW/nDF0S2aJJbWfAvnblHK5ClFHL9iL107NQYJ8PqzXbnFL
11qACE8TMmSZLz42AO96TndNtKplQ8LuGLEmByW95wEfhx3Gm4ckkL7qII/U3DnQXr 11gCQRiZxVHlrbn/73ZUMHPGEoU0711U9hSjrsqrRuSAMC+V38s4HxOomZWutlVAHF
120T+3xLaj+eNJzYDpIFZiw4sNzOuAyCz+4Cc4sPDuMnzquXF+enpkemoycC1RmEpG 12HwClNZBqRO+a2njPyUuV9DM/rl5Tm9IQ89iFo3/QEORICK77HjJYhi+UzdfI5F35
13KIDTwmFsc8TrbGV0qifC6fsCrDivdYLqL7R/q3IBQQKBgQDmfvO3VYTEKY8NA+AT 13UntRJt+WLaiAP+K6Vt6oxHSm58qXnOkeLzaAunTTie0CgYEA6OLYfme8xe5zYXWX
145s6+7NTxRsXxJUCEhCNBWimSH3EzmBAvrodLY6A0oYg8i81bgNX1I9GPVXJZ/QA7 14rqmKNYdcVfMkvL+vUfVT475o/piRtE54JC1LYWEFAN8paxEWHD5HZMy0+ONNXfGm
15ukd84HUIQoGS5Usmo4rp+kz4P6KkLXDemZtWPU5GXxicfajHRQlkbW6St6SpV7IS 15zyNNTN/Lagz4WcpdFzKQmhfdro7DzRiDfdvwSLmaZDyE41PPPVVvfrI9IeDiUNY4
16ibJcDADeoiaPL1xvue1ToP/LoQKBgQDgOFHjYpep00gabvjXfYW7vhrg1vVwaKUM 16nWLSb3sWo96Iuns+RoMqeA9wkqsCgYEA1U/UqeVQVTPlrWyiB2VXoI1xvFCCJTf8
17rf0+UW8Exk4nbBw0eEC2YjxIwzdktlkdbzGaXYULnhg8GnfxYesMOpCLPw1JdB8o 174NC0gcisxLRrtINk0BwrUJrRy0x1OLpJWiKwUl/W1GgvPPfhbYcUOb669JNtTIjY
18ixETAFpW5bKrUsjEFRUGhzWnsCSFIQ4smpmtGLTxOQ8AkoDdORY5Z+Wv7JtFF6Do 18FeIZblCTjz9GzKKmXeDciXvccyEdCJVUlPO3/e2JiJ4mCDjULprifq0a2gcQevFS
19PSoblckZcwKBgB3TD3YJesRnHDty5OuuUdIikuslXTd2uoJrFqS+JeLibqNeabnB 19PfqVULhBOvsCgYB5KfS7J1vGmv36ucSWAe0/VlKLATqe3RfpCzt/JQTZWSWNaroF
20u3/lxDULMbWj4U6VvRmbKOKDC+jY887Gq7lc0cff0yROxwqY3sCnwo3crg7QUmp7 20EG/ElUaWIoUZCEW5oglg/0Q0rYYGF4DTCingkhrx7ReVF70BIbSsBzi15d8nKNbY
21Nb5S8G3qoCSfndcq96wm/Me/O28uCbycVJfUdchY8uRUHIHYbP0FOBQBAoGBAMgh 21t4I3RCF4fyggYe1TmsysXS2DH85/gkToVY7oo2CvF0uJwi8vXnTNDDNkiwKBgHKs
22fPX4imaKr1DovDObVkK87EDDnU84GBm5MtDs3qrkVd3aIVK0Aw7HoAdSN58tI12i 22mAc94BHt9GtnGzQepx0I7TvvjAe2MZwqlt+uojKdS8mfWXMHscGDeYVxdRMqEoUC
23YiPmVVqJQhhjh6tsOuAvZdTj8ngdrbICbrsHFZt6an+A5LIgHyQ0iy+hiPdLCdvG 23YQfnvfYyjDKaj/XxyE3C237gQsICTyh0hHdpmepIeidIyWdumyDOFZVPF+ylWvM4
24ImTeKKMmyr04Bs1upueWVO0xw2VoMbcY4Py+NUEBAoGASQqedfCSKGLT+5lLZrhP 24kpFQQb/QRWHmKyti2KCBLw5G/fUaBryLGfprE6ZBAoGBANy5rr41A679UQZ0abev
25CbFVMmswEPjBcRb1trcuA09vfExn9FfUNFnnw3i9miprED5kufvAjb+6nduXizKg 25bOZb7YWOHYp/wReJaQbvLAyR30os3aEY/0ht9S+OWdrgGMezPKvsx2Sqr/CwoFXI
267HQYHCwVvakgtXgbiDMaNgYZcjWm+MdnfiwLJjJTO3DfI1JF2PJ8y9R95DPlAkDm 26esiklpknr11maEPxnQJYi4FYiXS1a3NCg7yBvKzFEgx2XnMAC3s6zhuZXaFq4zNu
27xH3OV8KV4UiTEVxS7ksmGzY= 27pm5Btrq/NZqtVXovS+UhGLvJ
28-----END PRIVATE KEY----- 28-----END PRIVATE KEY-----
diff --git a/plugins/tests/certs/ext.cnf b/plugins/tests/certs/ext.cnf
new file mode 100644
index 0000000..d09cee1
--- /dev/null
+++ b/plugins/tests/certs/ext.cnf
@@ -0,0 +1,2 @@
1[ client_ca ]
2basicConstraints = critical, CA:true
diff --git a/plugins/tests/certs/generate-certs.sh b/plugins/tests/certs/generate-certs.sh
new file mode 100755
index 0000000..78660a2
--- /dev/null
+++ b/plugins/tests/certs/generate-certs.sh
@@ -0,0 +1,63 @@
1#!/bin/sh -e
2#
3# Recreates the https server certificates
4#
5# Set the GEN_EXPIRED environment variable to also regenerate
6# the expired certificate.
7
8cd "$(dirname "$0")"
9trap 'rm -f *.csr; rm -f clientca-cert.srl' EXIT
10
11subj() {
12 c="DE"
13 st="Bavaria"
14 l="Munich"
15 o="Monitoring Plugins"
16 cn="Monitoring Plugins"
17 emailAddress="devel@monitoring-plugins.org"
18
19 if [ -n "$1" ]; then
20 # Add to CN
21 cn="$cn $1"
22 fi
23
24 printf "/C=%s/ST=%s/L=%s/O=%s/CN=%s/emailAddress=%s" \
25 "$c" "$st" "$l" "$o" "$cn" "$emailAddress"
26}
27
28# server
29openssl req -new -x509 -days 3560 -nodes \
30 -keyout server-key.pem -out server-cert.pem \
31 -subj "$(subj)"
32# server, expired
33# there is generally no need to regenerate this, as it will stay epxired
34[ -n "$GEN_EXPIRED" ] && TZ=UTC faketime -f '2008-01-01 12:00:00' \
35 openssl req -new -x509 -days 1 -nodes \
36 -keyout expired-key.pem -out expired-cert.pem \
37 -subj "$(subj)"
38
39# client, ca
40openssl req -new -x509 -days 3560 -nodes \
41 -keyout clientca-key.pem -out clientca-cert.pem \
42 -subj "$(subj ClientCA)"
43echo "01" >clientca-cert.srl
44# client
45openssl req -new -nodes \
46 -keyout client-key.pem -out client-cert.csr \
47 -subj "$(subj Client)"
48openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
49 -in client-cert.csr -out client-cert.pem
50# client, intermediate
51openssl req -new -nodes \
52 -keyout clientintermediate-key.pem -out clientintermediate-cert.csr \
53 -subj "$(subj ClientIntermediate)"
54openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
55 -extfile ext.cnf -extensions client_ca \
56 -in clientintermediate-cert.csr -out clientintermediate-cert.pem
57# client, chain
58openssl req -new -nodes \
59 -keyout clientchain-key.pem -out clientchain-cert.csr \
60 -subj "$(subj ClientChain)"
61openssl x509 -days 3560 -req -CA clientca-cert.pem -CAkey clientca-key.pem \
62 -in clientchain-cert.csr -out clientchain-cert.pem
63cat clientintermediate-cert.pem >>clientchain-cert.pem
diff --git a/plugins/tests/certs/server-cert.pem b/plugins/tests/certs/server-cert.pem
index b84b91d..d1249ef 100644
--- a/plugins/tests/certs/server-cert.pem
+++ b/plugins/tests/certs/server-cert.pem
@@ -1,24 +1,24 @@
1-----BEGIN CERTIFICATE----- 1-----BEGIN CERTIFICATE-----
2MIIEBjCCAu6gAwIBAgIJANbQ5QQrKhUGMA0GCSqGSIb3DQEBCwUAMIGXMQswCQYD 2MIIEETCCAvmgAwIBAgIUZwOhY4myaCUaPek3NM+MxbLG9vwwDQYJKoZIhvcNAQEL
3VQQGEwJERTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYD 3BQAwgZcxCzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZN
4VQQKDBJNb25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1 4dW5pY2gxGzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9u
5Z2luczErMCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9y 5aXRvcmluZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5n
6ZzAeFw0xOTAyMTkxNTMxNDRaFw0yOTAyMTYxNTMxNDRaMIGXMQswCQYDVQQGEwJE 6LXBsdWdpbnMub3JnMB4XDTIxMDIyODIxMDIxMVoXDTMwMTEyODIxMDIxMVowgZcx
7RTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYDVQQKDBJN 7CzAJBgNVBAYTAkRFMRAwDgYDVQQIDAdCYXZhcmlhMQ8wDQYDVQQHDAZNdW5pY2gx
8b25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1Z2luczEr 8GzAZBgNVBAoMEk1vbml0b3JpbmcgUGx1Z2luczEbMBkGA1UEAwwSTW9uaXRvcmlu
9MCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9yZzCCASIw 9ZyBQbHVnaW5zMSswKQYJKoZIhvcNAQkBFhxkZXZlbEBtb25pdG9yaW5nLXBsdWdp
10DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgV2yp8pQvJuN+aJGdAe6Hd0tja 10bnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/3eBA4WG6xz
11uteCPcNIcM92WLOF69TLTSYon1XDon4tHTh4Z5d4lD8bfsGzFVBmDSgWidhAUf+v 11LfM6xcWywxThb1Rp7XAW3ewQd9/PdoWXEe8BJWlLfyYi1drLMcsDywhLkKmW4Vp9
12EqEXwbp293ej/Frc0pXCvmrz6kI1tWrLtQhL/VdbxFYxhV7JjKb+PY3SxGFpSLPe 121R4PAkiljjrB/ZaUMDLJ1ri3dwX4RvXG7crsU3QWFWCBOrf5V2FTRQ2m/H/KyB/6
13PQ/5SwVndv7rZIwcjseL22K5Uy2TIrkgzzm2pRs/IvoxRybYr/+LGoHyrtJC6AO8 13rVZANsU47HqTFSPiUm2j7P3wx/wtHeYC+qmNG7zZTjAYPYxfKiod0lytTSmb+h54
14ylp8A/etL0gwtUvRnrnZeTQ2pA1uZ5QN3anTL8JP/ZRZYNegIkaawqMtTKbhM6pi 146lxn3+VPEXZAQZlLvPnm/58JnXGrUv7B2yocf5MhKkLJOrGxH2hfwKISfaj2gpOV
15u3/4a3Uppvt0y7vmGfQlYejxCpICnMrvHMpw8L58zv/98AbCGjDU3UwCt6MCAwEA 15m4PUVYiDzCSpq1fPvwbUxIvdO27xprx+mrGOFM6f2UCEOc35w8FSmYiR2yQTnEJK
16AaNTMFEwHQYDVR0OBBYEFG/UH6nGYPlVcM75UXzXBF5GZyrcMB8GA1UdIwQYMBaA 16pbSQD6t1jQIDAQABo1MwUTAdBgNVHQ4EFgQUMeYgglT2aWDlF8KEeF2376AlTGYw
17FG/UH6nGYPlVcM75UXzXBF5GZyrcMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN 17HwYDVR0jBBgwFoAUMeYgglT2aWDlF8KEeF2376AlTGYwDwYDVR0TAQH/BAUwAwEB
18AQELBQADggEBAGwitJPOnlIKLndNf+iCLMIs0dxsl8kAaejFcjoT0n4ja7Y6Zrqz 18/zANBgkqhkiG9w0BAQsFAAOCAQEAFcEg83rTJdgkp7JLYqK0j8JogSHNlDYchr/r
19VSIidzz9vQWvy24xKJpAOdj/iLRHCUOG+Pf5fA6+/FiuqXr6gE2/lm0eC58BNONr 19VxKBgQwfnjSp5A8d5+uTQ9s3QDabw8v7YeSrzYXbbjuWZ61mnl84tzOQ8LMeESnC
20E5OzjQ/VoQ8RX4hDntgu6FYbaVa/vhwn16igt9qmdNGGZXf2/+DM3JADwyaA4EK8 20CBXRCxB8Ow22WsVTVJq279SGYT+cZrdsmqGVWDi1A0C5kH+XTLAioG5CZmmxemD/
21vm7KdofX9zkxXecHPNvf3jiVLPiDDt6tkGpHPEsyP/yc+RUdltUeZvHfliV0cCuC 21S92ZoRxGyYfg33r+3X6EMcEYtHKGxCUa3EPcPOL4dq2F3nOnyjiWPZm3786H3NY2
22jJX+Fm9ysjSpHIFFr+jUMuMHibWoOD8iy3eYxfCDoWsH488pCbj8MNuAq6vd6DBk 22nsYwrEhAdUFtbYSsV5O0c/Zlc33fmTfh654ab35io1DtwmFo7q8J532dUE007EN0
23bOZxDz43vjWuYMkwXJTxJQh7Pne6kK0vE1g= 23mIQmhdrjNJJHIftgSt0fuN5m48oLOnX7vvkz+X0WLWfVTtMr0w==
24-----END CERTIFICATE----- 24-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/server-key.pem b/plugins/tests/certs/server-key.pem
index 1194755..0de63f8 100644
--- a/plugins/tests/certs/server-key.pem
+++ b/plugins/tests/certs/server-key.pem
@@ -1,28 +1,28 @@
1-----BEGIN PRIVATE KEY----- 1-----BEGIN PRIVATE KEY-----
2MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCoFdsqfKULybjf 2MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDb/d4EDhYbrHMt
3miRnQHuh3dLY2rrXgj3DSHDPdlizhevUy00mKJ9Vw6J+LR04eGeXeJQ/G37BsxVQ 38zrFxbLDFOFvVGntcBbd7BB33892hZcR7wElaUt/JiLV2ssxywPLCEuQqZbhWn3V
4Zg0oFonYQFH/rxKhF8G6dvd3o/xa3NKVwr5q8+pCNbVqy7UIS/1XW8RWMYVeyYym 4Hg8CSKWOOsH9lpQwMsnWuLd3BfhG9cbtyuxTdBYVYIE6t/lXYVNFDab8f8rIH/qt
5/j2N0sRhaUiz3j0P+UsFZ3b+62SMHI7Hi9tiuVMtkyK5IM85tqUbPyL6MUcm2K// 5VkA2xTjsepMVI+JSbaPs/fDH/C0d5gL6qY0bvNlOMBg9jF8qKh3SXK1NKZv6Hnjq
6ixqB8q7SQugDvMpafAP3rS9IMLVL0Z652Xk0NqQNbmeUDd2p0y/CT/2UWWDXoCJG 6XGff5U8RdkBBmUu8+eb/nwmdcatS/sHbKhx/kyEqQsk6sbEfaF/AohJ9qPaCk5Wb
7msKjLUym4TOqYrt/+Gt1Kab7dMu75hn0JWHo8QqSApzK7xzKcPC+fM7//fAGwhow 7g9RViIPMJKmrV8+/BtTEi907bvGmvH6asY4Uzp/ZQIQ5zfnDwVKZiJHbJBOcQkql
81N1MArejAgMBAAECggEANuvdTwanTzC8jaNqHaq+OuemS2E9B8nwsGxtH/zFgvNR 8tJAPq3WNAgMBAAECggEBAIvJDUjQVpXxByL8eazviT5SR0jBf6mC3tTWykQRb7ck
9WZiMPtmrJnTkFWJcV+VPw/iMSAqN4nDHmBugVOb4Z4asxGTKK4T9shXJSnh0rqPU 9/bBEiRrnhDRf3CS9KP4TvO5G8BUU3a2GHYzM08akuKXeiiODidfyfbQ1nUZBAdi9
1000ZsvbmxY6z0+E5TesCJqQ+9GYTY1V357V7JchvaOxIRxWPqg9urHbru8OCtW/I5 10FVFF7tK8YcflkVfpTMOMMSggm6m33fc58sQvmQ/0U85XuJvnOEkeJ9pQJa49e8GR
11Fh5HPUZlgCvlMpjlhyjydIf/oXyVA3RNsXlwe8+2cKuGIrjEzm2j9o3VF0sctTX0 11lpCQImF7ygltHPEz4o8qOtNMuPxiHOxpc517+ozQULZk153NTfGok1XctDFFZ3YX
12ItP8A9qDmDQN7GIWX0MW6gncojpS1omC2wcFsdjj/xfPyiDal1X4aq/2YqG8351c 128okLSfcqZ28mdHYSvI9xf60Cm7cT9tunXHwZ0f1esTFiVYpAp+oTJqtdYxr/fYlL
13YlM/+6Va0u9WWE/i64gASTAVqpMV4Yg8y0gGycuA0QKBgQDbgI2QeLd3FvMcURiU 13oO8G8iIQ7LjdJfgo84PscpKdSRCq3BfnmER1Eyg6hrUCgYEA/0hL5Y/haz/2jYGy
14l3w9qJgw/Jp3jaNC/9LkVGGz4f4lKKB67lPZvI4noMK8GqO/LcXgqP/RY1oJojoA 14aa8yZSuD1ZcWtj7pLKrBQnHPHIHsjSBggWhopvonCFvCjgSS1pOFOUAwMGc0T+Dw
15/6JKVvzYGASZ7VgMoG9bk1AneP1PGdibuTUEwimGlcObxnDFIC/yjwPFu3jIdqdS 15rWo3w8cEUyECl3Bw8gbCWtRXaigzU9TPgCWyx1j5dTopQhLObzS/m7fJFElnYNru
16zZi1RZzyqAogN5y3SBEypSmn9wKBgQDECKsqqlcizmCl8v5aVk875AzGN+DOHZqx 16jqhsUfWS+NKk8a5+A7i9lv4iBLMCgYEA3Jws3Lfj/Xs7LljrvryTMpPthvUGBcyt
17bkmztlnLO/2e2Fmk3G5Vvnui0FYisf8Eq19tUTQCF6lSfJlGQeFAT119wkFZhLu+ 17U9Qmf1Hmur90RP5V1rx4FqPQzIeaGQyZDNIUnkhBSqQZNCts3Rzay7N4uQzk8OEg
18FfLGqoEMH0ijJg/8PpdpFRK3I94YcISoTNN6yxMvE6xdDGfKCt5a+IX5bwQi9Zdc 18S8Llnw76wLwi0SJ4okDtT5tpTR6fcS0M9lGN+zvvfUB4+ul8oub0pMcyme/pywEz
19B242gEc6tQKBgA6tM8n7KFlAIZU9HuWgk2AUC8kKutFPmSD7tgAqXDYI4FNfugs+ 19ap+x3xAQPL8CgYEAiYOBVtTNof9fqdRurh1w8SyipKDx3BRBeQ02c7tozLt0GIWT
20MEEYyHCB4UNujJBV4Ss6YZCAkh6eyD4U2aca1eElCfm40vBVMdzvpqZdAqLtWXxg 20VsJOdXwVIJyFTglKrAnlXvSjwL8nX8wU+eVYyr5fJwSGJ9urC8T2VwVBXW7wTz04
21D9l3mgszrFaYGCY2Fr6jLV9lP5g3xsxUjudf9jSLY9HvpfzjRrMaNATVAoGBALTl 211Zf5GQdlwW8mIHCPATqR6Kj0yVfNN1BX50L0rqWxmRWnQoUzXn/aqQaWfp8CgYAW
22/vYfPMucwKlC5B7++J0e4/7iv6vUu9SyHocdZh1anb9AjPDKjXLIlZT4RhQ8R0XK 229693/zEeR8EejyVkAy/z+RCml0XcPrXg31pusPErihkpwazgIVkDSmTHlmqFpxkc
230wOw5JpttU2uN08TKkbLNk3/vYhbKVjPLjrQSseh8sjDLgsqw1QwIxYnniLVakVY 23C5cX73/UrIbvNoIr9wAUawfrhBsltNpu6MiNKbsTa8LYMRWMFuReAFkTLVf+KWmL
24p+rvjSNrNyqicQCMKQavwgocvSd5lJRTMwxOMezlAoGBAKWj71BX+0CK00/2S6lC 24D2yPtmq1iIvP25UdRJw9t3teKWsWtnZK6HtVNM/r8wKBgQDKlqUpy8r4KK+S2w80
25TcNcuUPG0d8y1czZ4q6tUlG4htwq1FMOpaghATXjkdsOGTLS+H1aA0Kt7Ai9zDhc 25H7rAQJo1DgXsYrgSa2gfppSKro4lm3ltyAfVIrKQKP7uCo9xTGKVQAUPttMs2+17
26/bzOJEJ+jvBXV4Gcs7jl1r/HTKv0tT9ZSI5Vzkida0rfqxDGzcMVlLuCdH0cb8Iu 26nwbwvt7/nG7G1Dk/C/t6b7SJ80VY5b9ZZKIJ0wOjajLufSjPNCe0ZTRn32XusZUn
27N0wdmCAqlQwHR13+F1zrAD7V 27nYGB5/QXYr5WGV9YhAkRsFJYgA==
28-----END PRIVATE KEY----- 28-----END PRIVATE KEY-----
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t
index 29cb03f..aa72ef6 100755
--- a/plugins/tests/check_curl.t
+++ b/plugins/tests/check_curl.t
@@ -228,23 +228,25 @@ SKIP: {
228 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; 228 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https};
229 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 229 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
230 230
231 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
232
231 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 233 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
232 is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); 234 is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
233 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" ); 235 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" );
234 236
235 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 237 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
236 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); 238 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
237 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 239 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
238 240
239 # Expired cert tests 241 # Expired cert tests
240 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 242 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
241 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); 243 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
242 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 244 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
243 245
244 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 246 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
245 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); 247 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
246 is( $result->output, 248 is( $result->output,
247 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 11:00:26 2008 +0000.', 249 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.',
248 "output ok" ); 250 "output ok" );
249 251
250} 252}
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index 188f5e7..ea11b2a 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -3,16 +3,7 @@
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;
@@ -23,7 +14,7 @@ $ENV{'LC_TIME'} = "C";
23 14
24my $common_tests = 70; 15my $common_tests = 70;
25my $virtual_port_tests = 8; 16my $virtual_port_tests = 8;
26my $ssl_only_tests = 8; 17my $ssl_only_tests = 12;
27# Check that all dependent modules are available 18# Check that all dependent modules are available
28eval "use HTTP::Daemon 6.01;"; 19eval "use HTTP::Daemon 6.01;";
29plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; 20plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@;
@@ -59,61 +50,87 @@ $HTTP::Daemon::VERSION = "1.00";
59my $port_http = 50000 + int(rand(1000)); 50my $port_http = 50000 + int(rand(1000));
60my $port_https = $port_http + 1; 51my $port_https = $port_http + 1;
61my $port_https_expired = $port_http + 2; 52my $port_https_expired = $port_http + 2;
53my $port_https_clientcert = $port_http + 3;
62 54
63# This array keeps sockets around for implementing timeouts 55# This array keeps sockets around for implementing timeouts
64my @persist; 56my @persist;
65 57
66# Start up all servers 58# Start up all servers
67my @pids; 59my @pids;
68my $pid = fork(); 60# Fork a HTTP server
69if ($pid) { 61my $pid = fork;
70 # Parent 62defined $pid or die "Failed to fork";
71 push @pids, $pid; 63if (!$pid) {
72 if (exists $servers->{https}) { 64 undef @pids;
73 # Fork a normal HTTPS server
74 $pid = fork();
75 if ($pid) {
76 # Parent
77 push @pids, $pid;
78 # Fork an expired cert server
79 $pid = fork();
80 if ($pid) {
81 push @pids, $pid;
82 } else {
83 my $d = HTTP::Daemon::SSL->new(
84 LocalPort => $port_https_expired,
85 LocalAddr => "127.0.0.1",
86 SSL_cert_file => "$Bin/certs/expired-cert.pem",
87 SSL_key_file => "$Bin/certs/expired-key.pem",
88 ) || die;
89 print "Please contact https expired at: <URL:", $d->url, ">\n";
90 run_server( $d );
91 exit;
92 }
93 } else {
94 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
95 local $SIG{'PIPE'} = 'IGNORE';
96 my $d = HTTP::Daemon::SSL->new(
97 LocalPort => $port_https,
98 LocalAddr => "127.0.0.1",
99 SSL_cert_file => "$Bin/certs/server-cert.pem",
100 SSL_key_file => "$Bin/certs/server-key.pem",
101 ) || die;
102 print "Please contact https at: <URL:", $d->url, ">\n";
103 run_server( $d );
104 exit;
105 }
106 }
107} else {
108 # Child
109 #print "child\n";
110 my $d = HTTP::Daemon->new( 65 my $d = HTTP::Daemon->new(
111 LocalPort => $port_http, 66 LocalPort => $port_http,
112 LocalAddr => "127.0.0.1", 67 LocalAddr => "127.0.0.1",
113 ) || die; 68 ) || die;
114 print "Please contact http at: <URL:", $d->url, ">\n"; 69 print "Please contact http at: <URL:", $d->url, ">\n";
115 run_server( $d ); 70 run_server( $d );
116 exit; 71 die "webserver stopped";
72}
73push @pids, $pid;
74
75if (exists $servers->{https}) {
76 # Fork a normal HTTPS server
77 $pid = fork;
78 defined $pid or die "Failed to fork";
79 if (!$pid) {
80 undef @pids;
81 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
82 local $SIG{'PIPE'} = 'IGNORE';
83 my $d = HTTP::Daemon::SSL->new(
84 LocalPort => $port_https,
85 LocalAddr => "127.0.0.1",
86 SSL_cert_file => "$Bin/certs/server-cert.pem",
87 SSL_key_file => "$Bin/certs/server-key.pem",
88 ) || die;
89 print "Please contact https at: <URL:", $d->url, ">\n";
90 run_server( $d );
91 die "webserver stopped";
92 }
93 push @pids, $pid;
94
95 # Fork an expired cert server
96 $pid = fork;
97 defined $pid or die "Failed to fork";
98 if (!$pid) {
99 undef @pids;
100 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
101 local $SIG{'PIPE'} = 'IGNORE';
102 my $d = HTTP::Daemon::SSL->new(
103 LocalPort => $port_https_expired,
104 LocalAddr => "127.0.0.1",
105 SSL_cert_file => "$Bin/certs/expired-cert.pem",
106 SSL_key_file => "$Bin/certs/expired-key.pem",
107 ) || die;
108 print "Please contact https expired at: <URL:", $d->url, ">\n";
109 run_server( $d );
110 die "webserver stopped";
111 }
112 push @pids, $pid;
113
114 # Fork an client cert expecting server
115 $pid = fork;
116 defined $pid or die "Failed to fork";
117 if (!$pid) {
118 undef @pids;
119 # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise
120 local $SIG{'PIPE'} = 'IGNORE';
121 my $d = HTTP::Daemon::SSL->new(
122 LocalPort => $port_https_clientcert,
123 LocalAddr => "127.0.0.1",
124 SSL_cert_file => "$Bin/certs/server-cert.pem",
125 SSL_key_file => "$Bin/certs/server-key.pem",
126 SSL_verify_mode => IO::Socket::SSL->SSL_VERIFY_PEER | IO::Socket::SSL->SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
127 SSL_ca_file => "$Bin/certs/clientca-cert.pem",
128 ) || die;
129 print "Please contact https client cert at: <URL:", $d->url, ">\n";
130 run_server( $d );
131 die "webserver stopped";
132 }
133 push @pids, $pid;
117} 134}
118 135
119# give our webservers some time to startup 136# give our webservers some time to startup
@@ -122,60 +139,62 @@ sleep(3);
122# Run the same server on http and https 139# Run the same server on http and https
123sub run_server { 140sub run_server {
124 my $d = shift; 141 my $d = shift;
125 MAINLOOP: while (my $c = $d->accept ) { 142 while (1) {
126 while (my $r = $c->get_request) { 143 MAINLOOP: while (my $c = $d->accept) {
127 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) { 144 while (my $r = $c->get_request) {
128 $c->send_basic_header($1); 145 if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) {
129 $c->send_crlf; 146 $c->send_basic_header($1);
130 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) { 147 $c->send_crlf;
131 $c->send_basic_header; 148 } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) {
132 $c->send_crlf; 149 $c->send_basic_header;
133 $c->send_file_response("$Bin/var/$1"); 150 $c->send_crlf;
134 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") { 151 $c->send_file_response("$Bin/var/$1");
135 $c->send_basic_header; 152 } elsif ($r->method eq "GET" and $r->url->path eq "/slow") {
136 $c->send_crlf; 153 $c->send_basic_header;
137 sleep 1; 154 $c->send_crlf;
138 $c->send_response("slow"); 155 sleep 1;
139 } elsif ($r->url->path eq "/method") { 156 $c->send_response("slow");
140 if ($r->method eq "DELETE") { 157 } elsif ($r->url->path eq "/method") {
141 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED); 158 if ($r->method eq "DELETE") {
142 } elsif ($r->method eq "foo") { 159 $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED);
143 $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED); 160 } elsif ($r->method eq "foo") {
161 $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED);
162 } else {
163 $c->send_status_line(200, $r->method);
164 }
165 } elsif ($r->url->path eq "/postdata") {
166 $c->send_basic_header;
167 $c->send_crlf;
168 $c->send_response($r->method.":".$r->content);
169 } elsif ($r->url->path eq "/redirect") {
170 $c->send_redirect( "/redirect2" );
171 } elsif ($r->url->path eq "/redir_external") {
172 $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" );
173 } elsif ($r->url->path eq "/redirect2") {
174 $c->send_basic_header;
175 $c->send_crlf;
176 $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' ));
177 } elsif ($r->url->path eq "/redir_timeout") {
178 $c->send_redirect( "/timeout" );
179 } elsif ($r->url->path eq "/timeout") {
180 # Keep $c from being destroyed, but prevent severe leaks
181 unshift @persist, $c;
182 delete($persist[1000]);
183 next MAINLOOP;
184 } elsif ($r->url->path eq "/header_check") {
185 $c->send_basic_header;
186 $c->send_header('foo');
187 $c->send_crlf;
188 } elsif ($r->url->path eq "/virtual_port") {
189 # return sent Host header
190 $c->send_basic_header;
191 $c->send_crlf;
192 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
144 } else { 193 } else {
145 $c->send_status_line(200, $r->method); 194 $c->send_error(HTTP::Status->RC_FORBIDDEN);
146 } 195 }
147 } elsif ($r->url->path eq "/postdata") { 196 $c->close;
148 $c->send_basic_header;
149 $c->send_crlf;
150 $c->send_response($r->method.":".$r->content);
151 } elsif ($r->url->path eq "/redirect") {
152 $c->send_redirect( "/redirect2" );
153 } elsif ($r->url->path eq "/redir_external") {
154 $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" );
155 } elsif ($r->url->path eq "/redirect2") {
156 $c->send_basic_header;
157 $c->send_crlf;
158 $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' ));
159 } elsif ($r->url->path eq "/redir_timeout") {
160 $c->send_redirect( "/timeout" );
161 } elsif ($r->url->path eq "/timeout") {
162 # Keep $c from being destroyed, but prevent severe leaks
163 unshift @persist, $c;
164 delete($persist[1000]);
165 next MAINLOOP;
166 } elsif ($r->url->path eq "/header_check") {
167 $c->send_basic_header;
168 $c->send_header('foo');
169 $c->send_crlf;
170 } elsif ($r->url->path eq "/virtual_port") {
171 # return sent Host header
172 $c->send_basic_header;
173 $c->send_crlf;
174 $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host')));
175 } else {
176 $c->send_error(HTTP::Status->RC_FORBIDDEN);
177 } 197 }
178 $c->close;
179 } 198 }
180 } 199 }
181} 200}
@@ -200,25 +219,44 @@ SKIP: {
200 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; 219 skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https};
201 run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); 220 run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
202 221
222 my $expiry = "Thu Nov 28 21:02:11 2030 +0000";
223
203 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); 224 $result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
204 is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); 225 is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
205 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" ); 226 is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" );
206 227
207 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); 228 $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
208 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); 229 is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
209 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 230 like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
210 231
211 # Expired cert tests 232 # Expired cert tests
212 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); 233 $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
213 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); 234 is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
214 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); 235 like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" );
215 236
216 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); 237 $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
217 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); 238 is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
218 is( $result->output, 239 is( $result->output,
219 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 11:00:26 2008 +0000.', 240 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.',
220 "output ok" ); 241 "output ok" );
221 242
243 # client cert tests
244 my $cmd;
245 $cmd = "$command -p $port_https_clientcert"
246 . " -J \"$Bin/certs/client-cert.pem\""
247 . " -K \"$Bin/certs/client-key.pem\""
248 . " -u /statuscode/200";
249 $result = NPTest->testCmd($cmd);
250 is( $result->return_code, 0, $cmd);
251 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
252
253 $cmd = "$command -p $port_https_clientcert"
254 . " -J \"$Bin/certs/clientchain-cert.pem\""
255 . " -K \"$Bin/certs/clientchain-key.pem\""
256 . " -u /statuscode/200";
257 $result = NPTest->testCmd($cmd);
258 is( $result->return_code, 0, $cmd);
259 like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output );
222} 260}
223 261
224my $cmd; 262my $cmd;