diff options
Diffstat (limited to 'plugins/check_tcp.c')
| -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 | } |
