*** check_tcp.c Tue Jun 10 00:56:47 2003 --- /usr/local/projects/nagios-plugins-1.3.1/plugins//check_tcp.c Wed Sep 29 15:14:33 2004 *************** *** 50,62 **** --- 50,67 ---- #include #include #endif #ifdef HAVE_SSL + int check_cert = FALSE; + int days_till_exp; + char *randbuff = ""; SSL_CTX *ctx; SSL *ssl; + X509 *server_cert; int connect_SSL (void); + int check_certificate (X509 **); #endif enum { TCP_PROTOCOL = 1, UDP_PROTOCOL = 2, *************** *** 74,83 **** --- 79,89 ---- char *EXPECT = NULL; char *QUIT = NULL; int PROTOCOL = 0; int PORT = 0; + char timestamp[17] = ""; int server_port = 0; char *server_address = NULL; char *server_send = NULL; char *server_quit = NULL; char **server_expect = NULL; *************** *** 193,202 **** --- 199,224 ---- asprintf (&server_expect[server_expect_count - 1], "201"); asprintf (&QUIT, "QUIT\r\n"); PROTOCOL = TCP_PROTOCOL; PORT = 119; } + #ifdef HAVE_SSL + else if (strstr (argv[0], "check_nntps")) { + asprintf (&progname, "check_nntps"); + asprintf (&SERVICE, "NNTPS"); + SEND = NULL; + EXPECT = NULL; + server_expect = realloc (server_expect, ++server_expect_count); + asprintf (&server_expect[server_expect_count - 1], "200"); + server_expect = realloc (server_expect, ++server_expect_count); + asprintf (&server_expect[server_expect_count - 1], "201"); + asprintf (&QUIT, "QUIT\r\n"); + PROTOCOL = TCP_PROTOCOL; + use_ssl=TRUE; + PORT = 563; + } + #endif else { usage ("ERROR: Generic check_tcp called with unknown service\n"); } asprintf (&server_address, "127.0.0.1"); *************** *** 220,230 **** alarm (socket_timeout); /* try to connect to the host at the given port number */ gettimeofday (&tv, NULL); #ifdef HAVE_SSL ! if (use_ssl) result = connect_SSL (); else #endif { if (PROTOCOL == UDP_PROTOCOL) --- 242,270 ---- alarm (socket_timeout); /* try to connect to the host at the given port number */ gettimeofday (&tv, NULL); #ifdef HAVE_SSL ! if (use_ssl && check_cert == TRUE) { ! if (connect_SSL () != OK) ! terminate (STATE_CRITICAL, ! "TCP CRITICAL - Could not make SSL connection\n"); ! if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { ! result = check_certificate (&server_cert); ! X509_free(server_cert); ! } ! else { ! printf("ERROR: Cannot retrieve server certificate.\n"); ! result = STATE_CRITICAL; ! } ! SSL_shutdown (ssl); ! SSL_free (ssl); ! SSL_CTX_free (ctx); ! close (sd); ! return result; ! } ! else if (use_ssl) result = connect_SSL (); else #endif { if (PROTOCOL == UDP_PROTOCOL) *************** *** 354,363 **** --- 394,404 ---- {"quit", required_argument, 0, 'q'}, {"delay", required_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, + {"certificate", required_argument, 0, 'C'}, {0, 0, 0, 0} }; #endif if (argc < 2) *************** *** 421,434 **** --- 462,477 ---- if (!is_intnonneg (optarg)) usage ("Warning threshold must be a nonnegative integer\n"); warning_time = strtod (optarg, NULL); check_warning_time = TRUE; break; + /* case 'C': crit_codes = realloc (crit_codes, ++crit_codes_count); crit_codes[crit_codes_count - 1] = optarg; break; + */ case 'W': warn_codes = realloc (warn_codes, ++warn_codes_count); warn_codes[warn_codes_count - 1] = optarg; break; case 't': /* timeout */ *************** *** 470,479 **** --- 513,533 ---- terminate (STATE_UNKNOWN, "SSL support not available. Install OpenSSL and recompile."); #endif use_ssl = TRUE; break; + case 'C': /* Check SSL cert validity */ + #ifdef HAVE_SSL + if (!is_intnonneg (optarg)) + usage2 ("invalid certificate expiration period", optarg); + days_till_exp = atoi (optarg); + check_cert = TRUE; + #else + terminate (STATE_UNKNOWN, + "SSL support not available. Install OpenSSL and recompile."); + #endif + break; } } if (server_address == NULL) usage ("You must provide a server address\n"); *************** *** 532,541 **** --- 586,600 ---- " Seconds before connection times out (default: %d)\n" " -v, --verbose" " Show details for command-line debugging (do not use with nagios server)\n" " -h, --help\n" " Print detailed help screen\n" + #ifdef HAVE_SSL + " -C, --certificate=INTEGER\n" + "Minimum number of days a certificate has to be valid.\n" + "(when this option is used the banner is not checked.)\n" + #endif " -V, --version\n" " Print version information\n", DEFAULT_SOCKET_TIMEOUT); } /* *************** *** 593,603 **** --- 652,736 ---- return STATE_CRITICAL; } #endif + #ifdef HAVE_SSL + int + check_certificate (X509 ** certificate) + { + ASN1_STRING *tm; + int offset; + struct tm stamp; + int days_left; + + /* Retrieve timestamp of certificate */ + tm = X509_get_notAfter (*certificate); + + /* Generate tm structure to process timestamp */ + if (tm->type == V_ASN1_UTCTIME) { + if (tm->length < 10) { + printf ("ERROR: Wrong time format in certificate.\n"); + return STATE_CRITICAL; + } + else { + stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); + if (stamp.tm_year < 50) + stamp.tm_year += 100; + offset = 0; + } + } + else { + if (tm->length < 12) { + printf ("ERROR: Wrong time format in certificate.\n"); + return STATE_CRITICAL; + } + else { + stamp.tm_year = + (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + + (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); + stamp.tm_year -= 1900; + offset = 2; + } + } + stamp.tm_mon = + (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; + stamp.tm_mday = + (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); + stamp.tm_hour = + (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0'); + stamp.tm_min = + (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0'); + stamp.tm_sec = 0; + stamp.tm_isdst = -1; + + days_left = (mktime (&stamp) - time (NULL)) / 86400; + snprintf + (timestamp, 16, "%02d/%02d/%04d %02d:%02d", + stamp.tm_mon + 1, + stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min); + + if (days_left > 0 && days_left <= days_till_exp) { + printf ("Certificate expires in %d day(s) (%s).\n", days_left, timestamp); + return STATE_WARNING; + } + if (days_left < 0) { + printf ("Certificate expired on %s.\n", timestamp); + return STATE_CRITICAL; + } + + if (days_left == 0) { + printf ("Certificate expires today (%s).\n", timestamp); + return STATE_WARNING; + } + + printf ("Certificate will expire on %s.\n", timestamp); + + return STATE_OK; + } + #endif int my_recv (void) { int i;