diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/check_tcp.c | 167 |
1 files changed, 156 insertions, 11 deletions
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index b78bf34d..7cef8bb9 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c | |||
@@ -45,9 +45,14 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #ifdef HAVE_SSL | 47 | #ifdef HAVE_SSL |
48 | int check_cert = FALSE; | ||
49 | int days_till_exp; | ||
50 | char *randbuff = ""; | ||
48 | SSL_CTX *ctx; | 51 | SSL_CTX *ctx; |
49 | SSL *ssl; | 52 | SSL *ssl; |
53 | X509 *server_cert; | ||
50 | int connect_SSL (void); | 54 | int connect_SSL (void); |
55 | int check_certificate (X509 **); | ||
51 | #endif | 56 | #endif |
52 | 57 | ||
53 | enum { | 58 | enum { |
@@ -68,6 +73,7 @@ char *QUIT = NULL; | |||
68 | int PROTOCOL = 0; | 73 | int PROTOCOL = 0; |
69 | int PORT = 0; | 74 | int PORT = 0; |
70 | 75 | ||
76 | char timestamp[17] = ""; | ||
71 | int server_port = 0; | 77 | int server_port = 0; |
72 | char *server_address = NULL; | 78 | char *server_address = NULL; |
73 | char *server_send = NULL; | 79 | char *server_send = NULL; |
@@ -184,6 +190,31 @@ main (int argc, char **argv) | |||
184 | use_ssl=TRUE; | 190 | use_ssl=TRUE; |
185 | PORT=995; | 191 | PORT=995; |
186 | } | 192 | } |
193 | else if (strstr(argv[0],"check_jabber")) { | ||
194 | progname = strdup("check_jabber"); | ||
195 | SERVICE = strdup("JABBER"); | ||
196 | SEND = strdup("<stream:stream to=\'host\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>\n"); | ||
197 | EXPECT = strdup("<?xml version=\'1.0\'?><stream:stream xmlns:stream=\'http://etherx.jabber.org/streams\'"); | ||
198 | QUIT = strdup("</stream:stream>\n"); | ||
199 | PROTOCOL=TCP_PROTOCOL; | ||
200 | use_ssl=TRUE; | ||
201 | PORT = 5222; | ||
202 | } | ||
203 | else if (strstr (argv[0], "check_nntps")) { | ||
204 | progname = strdup("check_nntps"); | ||
205 | SERVICE = strdup("NNTPS"); | ||
206 | SEND = NULL; | ||
207 | EXPECT = NULL; | ||
208 | server_expect = realloc (server_expect, ++server_expect_count); | ||
209 | asprintf (&server_expect[server_expect_count - 1], "200"); | ||
210 | server_expect = realloc (server_expect, ++server_expect_count); | ||
211 | asprintf (&server_expect[server_expect_count - 1], "201"); | ||
212 | QUIT = strdup("QUIT\r\n"); | ||
213 | PROTOCOL = TCP_PROTOCOL; | ||
214 | use_ssl=TRUE; | ||
215 | PORT = 563; | ||
216 | } | ||
217 | |||
187 | #endif | 218 | #endif |
188 | else if (strstr (argv[0], "check_nntp")) { | 219 | else if (strstr (argv[0], "check_nntp")) { |
189 | progname = strdup ("check_nntp"); | 220 | progname = strdup ("check_nntp"); |
@@ -227,7 +258,24 @@ main (int argc, char **argv) | |||
227 | /* try to connect to the host at the given port number */ | 258 | /* try to connect to the host at the given port number */ |
228 | gettimeofday (&tv, NULL); | 259 | gettimeofday (&tv, NULL); |
229 | #ifdef HAVE_SSL | 260 | #ifdef HAVE_SSL |
230 | if (use_ssl) | 261 | if (use_ssl && check_cert == TRUE) { |
262 | if (connect_SSL () != OK) | ||
263 | die (STATE_CRITICAL,"TCP CRITICAL - Could not make SSL connection\n"); | ||
264 | if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { | ||
265 | result = check_certificate (&server_cert); | ||
266 | X509_free(server_cert); | ||
267 | } | ||
268 | else { | ||
269 | printf("ERROR: Cannot retrieve server certificate.\n"); | ||
270 | result = STATE_CRITICAL; | ||
271 | } | ||
272 | SSL_shutdown (ssl); | ||
273 | SSL_free (ssl); | ||
274 | SSL_CTX_free (ctx); | ||
275 | close (sd); | ||
276 | return result; | ||
277 | } | ||
278 | else if (use_ssl) | ||
231 | result = connect_SSL (); | 279 | result = connect_SSL (); |
232 | else | 280 | else |
233 | #endif | 281 | #endif |
@@ -373,6 +421,10 @@ process_arguments (int argc, char **argv) | |||
373 | {"verbose", no_argument, 0, 'v'}, | 421 | {"verbose", no_argument, 0, 'v'}, |
374 | {"version", no_argument, 0, 'V'}, | 422 | {"version", no_argument, 0, 'V'}, |
375 | {"help", no_argument, 0, 'h'}, | 423 | {"help", no_argument, 0, 'h'}, |
424 | #ifdef HAVE_SSL | ||
425 | {"ssl", no_argument, 0, 'S'}, | ||
426 | {"certificate", required_argument, 0, 'D'}, | ||
427 | #endif | ||
376 | {0, 0, 0, 0} | 428 | {0, 0, 0, 0} |
377 | }; | 429 | }; |
378 | 430 | ||
@@ -429,7 +481,7 @@ process_arguments (int argc, char **argv) | |||
429 | break; | 481 | break; |
430 | case 'H': /* hostname */ | 482 | case 'H': /* hostname */ |
431 | if (is_host (optarg) == FALSE) | 483 | if (is_host (optarg) == FALSE) |
432 | usage2 (_("Invalid host name/address"), optarg); | 484 | usage2 (_("invalid host name or address"), optarg); |
433 | server_address = optarg; | 485 | server_address = optarg; |
434 | break; | 486 | break; |
435 | case 'c': /* critical */ | 487 | case 'c': /* critical */ |
@@ -459,7 +511,7 @@ process_arguments (int argc, char **argv) | |||
459 | break; | 511 | break; |
460 | case 't': /* timeout */ | 512 | case 't': /* timeout */ |
461 | if (!is_intpos (optarg)) | 513 | if (!is_intpos (optarg)) |
462 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 514 | usage (_("Timeout interval must be a positive integer\n")); |
463 | else | 515 | else |
464 | socket_timeout = atoi (optarg); | 516 | socket_timeout = atoi (optarg); |
465 | break; | 517 | break; |
@@ -504,12 +556,19 @@ process_arguments (int argc, char **argv) | |||
504 | else | 556 | else |
505 | usage (_("Delay must be a positive integer\n")); | 557 | usage (_("Delay must be a positive integer\n")); |
506 | break; | 558 | break; |
559 | case 'D': /* Check SSL cert validity - days 'til certificate expiration */ | ||
560 | #ifdef HAVE_SSL | ||
561 | if (!is_intnonneg (optarg)) | ||
562 | usage2 ("invalid certificate expiration period", optarg); | ||
563 | days_till_exp = atoi (optarg); | ||
564 | check_cert = TRUE; | ||
565 | use_ssl = TRUE; | ||
566 | break; | ||
507 | case 'S': | 567 | case 'S': |
508 | #ifndef HAVE_SSL | ||
509 | die (STATE_UNKNOWN, | ||
510 | _("SSL support not available. Install OpenSSL and recompile.")); | ||
511 | #endif | ||
512 | use_ssl = TRUE; | 568 | use_ssl = TRUE; |
569 | #else | ||
570 | die (STATE_UNKNOWN, "SSL support not available. Install OpenSSL and recompile."); | ||
571 | #endif | ||
513 | break; | 572 | break; |
514 | } | 573 | } |
515 | } | 574 | } |
@@ -556,7 +615,10 @@ connect_SSL (void) | |||
556 | SSL_set_fd (ssl, sd); | 615 | SSL_set_fd (ssl, sd); |
557 | if (SSL_connect(ssl) == 1) | 616 | if (SSL_connect(ssl) == 1) |
558 | return OK; | 617 | return OK; |
559 | ERR_print_errors_fp (stderr); | 618 | /* ERR_print_errors_fp (stderr); */ |
619 | printf (_("ERROR: Cannot make SSL connection ")); | ||
620 | ERR_print_errors_fp (stdout); | ||
621 | /* printf("\n"); */ | ||
560 | } | 622 | } |
561 | else | 623 | else |
562 | { | 624 | { |
@@ -572,7 +634,81 @@ connect_SSL (void) | |||
572 | } | 634 | } |
573 | #endif | 635 | #endif |
574 | 636 | ||
637 | #ifdef HAVE_SSL | ||
638 | int | ||
639 | check_certificate (X509 ** certificate) | ||
640 | { | ||
641 | ASN1_STRING *tm; | ||
642 | int offset; | ||
643 | struct tm stamp; | ||
644 | int days_left; | ||
645 | |||
575 | 646 | ||
647 | /* Retrieve timestamp of certificate */ | ||
648 | tm = X509_get_notAfter (*certificate); | ||
649 | |||
650 | /* Generate tm structure to process timestamp */ | ||
651 | if (tm->type == V_ASN1_UTCTIME) { | ||
652 | if (tm->length < 10) { | ||
653 | printf ("ERROR: Wrong time format in certificate.\n"); | ||
654 | return STATE_CRITICAL; | ||
655 | } | ||
656 | else { | ||
657 | stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); | ||
658 | if (stamp.tm_year < 50) | ||
659 | stamp.tm_year += 100; | ||
660 | offset = 0; | ||
661 | } | ||
662 | } | ||
663 | else { | ||
664 | if (tm->length < 12) { | ||
665 | printf ("ERROR: Wrong time format in certificate.\n"); | ||
666 | return STATE_CRITICAL; | ||
667 | } | ||
668 | else { | ||
669 | stamp.tm_year = | ||
670 | (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + | ||
671 | (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); | ||
672 | stamp.tm_year -= 1900; | ||
673 | offset = 2; | ||
674 | } | ||
675 | } | ||
676 | stamp.tm_mon = | ||
677 | (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; | ||
678 | stamp.tm_mday = | ||
679 | (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); | ||
680 | stamp.tm_hour = | ||
681 | (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0'); | ||
682 | stamp.tm_min = | ||
683 | (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0'); | ||
684 | stamp.tm_sec = 0; | ||
685 | stamp.tm_isdst = -1; | ||
686 | |||
687 | days_left = (mktime (&stamp) - time (NULL)) / 86400; | ||
688 | snprintf | ||
689 | (timestamp, 16, "%02d/%02d/%04d %02d:%02d", | ||
690 | stamp.tm_mon + 1, | ||
691 | stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min); | ||
692 | |||
693 | if (days_left > 0 && days_left <= days_till_exp) { | ||
694 | printf ("Certificate expires in %d day(s) (%s).\n", days_left, timestamp); | ||
695 | return STATE_WARNING; | ||
696 | } | ||
697 | if (days_left < 0) { | ||
698 | printf ("Certificate expired on %s.\n", timestamp); | ||
699 | return STATE_CRITICAL; | ||
700 | } | ||
701 | |||
702 | if (days_left == 0) { | ||
703 | printf ("Certificate expires today (%s).\n", timestamp); | ||
704 | return STATE_WARNING; | ||
705 | } | ||
706 | |||
707 | printf ("Certificate will expire on %s.\n", timestamp); | ||
708 | |||
709 | return STATE_OK; | ||
710 | } | ||
711 | #endif | ||
576 | 712 | ||
577 | int | 713 | int |
578 | my_recv (void) | 714 | my_recv (void) |
@@ -603,8 +739,8 @@ print_help (void) | |||
603 | { | 739 | { |
604 | print_revision (progname, revision); | 740 | print_revision (progname, revision); |
605 | 741 | ||
606 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 742 | printf (_("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n")); |
607 | printf (COPYRIGHT, copyright, email); | 743 | printf (_(COPYRIGHT), copyright, email); |
608 | 744 | ||
609 | printf (_("This plugin tests %s connections with the specified host.\n\n"), | 745 | printf (_("This plugin tests %s connections with the specified host.\n\n"), |
610 | SERVICE); | 746 | SERVICE); |
@@ -635,6 +771,14 @@ print_help (void) | |||
635 | -d, --delay=INTEGER\n\ | 771 | -d, --delay=INTEGER\n\ |
636 | Seconds to wait between sending string and polling for response\n")); | 772 | Seconds to wait between sending string and polling for response\n")); |
637 | 773 | ||
774 | #ifdef HAVE_SSL | ||
775 | printf (_("\ | ||
776 | -D, --certificate=INTEGER\n\ | ||
777 | Minimum number of days a certificate has to be valid.\n\ | ||
778 | -S, --ssl\n\ | ||
779 | Use SSL for the connection.\n")); | ||
780 | #endif | ||
781 | |||
638 | printf (_(UT_WARN_CRIT)); | 782 | printf (_(UT_WARN_CRIT)); |
639 | 783 | ||
640 | printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); | 784 | printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); |
@@ -654,7 +798,8 @@ print_usage (void) | |||
654 | Usage: %s -H host -p port [-w <warning time>] [-c <critical time>]\n\ | 798 | Usage: %s -H host -p port [-w <warning time>] [-c <critical time>]\n\ |
655 | [-s <send string>] [-e <expect string>] [-q <quit string>]\n\ | 799 | [-s <send string>] [-e <expect string>] [-q <quit string>]\n\ |
656 | [-m <maximum bytes>] [-d <delay>] [-t <timeout seconds>]\n\ | 800 | [-m <maximum bytes>] [-d <delay>] [-t <timeout seconds>]\n\ |
657 | [-r <refuse state>] [-v] [-4|-6] [-j]\n"), progname); | 801 | [-r <refuse state>] [-v] [-4|-6] [-j] [-D <days to cert expiry>]\n\ |
802 | [-S <use SSL>]\n"), progname); | ||
658 | printf (" %s (-h|--help)\n", progname); | 803 | printf (" %s (-h|--help)\n", progname); |
659 | printf (" %s (-V|--version)\n", progname); | 804 | printf (" %s (-V|--version)\n", progname); |
660 | } | 805 | } |