summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_curl.c3
-rw-r--r--plugins/netutils.h3
-rw-r--r--plugins/sslutils.c135
3 files changed, 139 insertions, 2 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 680ecef7..b1021045 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -569,8 +569,9 @@ mp_subcheck check_http(const check_curl_config config, check_curl_working_state
569 sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK); 569 sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK);
570 } 570 }
571 } else if (errcode == REG_NOMATCH) { 571 } else if (errcode == REG_NOMATCH) {
572 xasprintf(&sc_body_regex.output, "%s not", sc_body_regex.output);
573 // got no match 572 // got no match
573 xasprintf(&sc_body_regex.output, "%s not", sc_body_regex.output);
574
574 if (config.invert_regex) { 575 if (config.invert_regex) {
575 sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK); 576 sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK);
576 } else { 577 } else {
diff --git a/plugins/netutils.h b/plugins/netutils.h
index c53b3cef..6adb8e01 100644
--- a/plugins/netutils.h
+++ b/plugins/netutils.h
@@ -32,6 +32,7 @@
32#define _NETUTILS_H_ 32#define _NETUTILS_H_
33 33
34#include "common.h" 34#include "common.h"
35#include "output.h"
35#include "states.h" 36#include "states.h"
36#include "utils.h" 37#include "utils.h"
37#include <netinet/in.h> 38#include <netinet/in.h>
@@ -114,6 +115,6 @@ void np_net_ssl_cleanup();
114int np_net_ssl_write(const void *buf, int num); 115int np_net_ssl_write(const void *buf, int num);
115int np_net_ssl_read(void *buf, int num); 116int np_net_ssl_read(void *buf, int num);
116mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); 117mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit);
118mp_subcheck mp_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit);
117#endif /* HAVE_SSL */ 119#endif /* HAVE_SSL */
118
119#endif /* _NETUTILS_H_ */ 120#endif /* _NETUTILS_H_ */
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index bea1307f..3ce6afed 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -26,6 +26,7 @@
26 * 26 *
27 *****************************************************************************/ 27 *****************************************************************************/
28 28
29#include "output.h"
29#define MAX_CN_LENGTH 256 30#define MAX_CN_LENGTH 256
30#include "common.h" 31#include "common.h"
31#include "netutils.h" 32#include "netutils.h"
@@ -322,4 +323,138 @@ mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_cr
322# endif /* USE_OPENSSL */ 323# endif /* USE_OPENSSL */
323} 324}
324 325
326mp_subcheck mp_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn,
327 int days_till_exp_crit) {
328 mp_subcheck sc_cert = mp_subcheck_init();
329# ifdef USE_OPENSSL
330 if (!certificate) {
331 xasprintf(&sc_cert.output, _("No server certificate present to inspect"));
332 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
333 return sc_cert;
334 }
335
336 /* Extract CN from certificate subject */
337 X509_NAME *subj = X509_get_subject_name(certificate);
338
339 if (!subj) {
340 xasprintf(&sc_cert.output, _("Cannot retrieve certificate subject"));
341 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
342 return sc_cert;
343 }
344
345 char commonName[MAX_CN_LENGTH] = "";
346 int cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, commonName, sizeof(commonName));
347 if (cnlen == -1) {
348 strcpy(commonName, _("Unknown CN"));
349 }
350
351 /* Retrieve timestamp of certificate */
352 ASN1_STRING *expiry_timestamp = X509_get_notAfter(certificate);
353
354 int offset = 0;
355 struct tm stamp = {};
356 /* Generate tm structure to process timestamp */
357 if (expiry_timestamp->type == V_ASN1_UTCTIME) {
358 if (expiry_timestamp->length < 10) {
359 xasprintf(&sc_cert.output, _("Wrong time format in certificate"));
360 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
361 return sc_cert;
362 }
363
364 stamp.tm_year = (expiry_timestamp->data[0] - '0') * 10 + (expiry_timestamp->data[1] - '0');
365 if (stamp.tm_year < 50) {
366 stamp.tm_year += 100;
367 }
368
369 offset = 0;
370 } else {
371 if (expiry_timestamp->length < 12) {
372 xasprintf(&sc_cert.output, _("Wrong time format in certificate"));
373 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
374 return sc_cert;
375 }
376 stamp.tm_year = (expiry_timestamp->data[0] - '0') * 1000 +
377 (expiry_timestamp->data[1] - '0') * 100 +
378 (expiry_timestamp->data[2] - '0') * 10 + (expiry_timestamp->data[3] - '0');
379 stamp.tm_year -= 1900;
380 offset = 2;
381 }
382
383 stamp.tm_mon = (expiry_timestamp->data[2 + offset] - '0') * 10 +
384 (expiry_timestamp->data[3 + offset] - '0') - 1;
385 stamp.tm_mday = (expiry_timestamp->data[4 + offset] - '0') * 10 +
386 (expiry_timestamp->data[5 + offset] - '0');
387 stamp.tm_hour = (expiry_timestamp->data[6 + offset] - '0') * 10 +
388 (expiry_timestamp->data[7 + offset] - '0');
389 stamp.tm_min = (expiry_timestamp->data[8 + offset] - '0') * 10 +
390 (expiry_timestamp->data[9 + offset] - '0');
391 stamp.tm_sec = (expiry_timestamp->data[10 + offset] - '0') * 10 +
392 (expiry_timestamp->data[11 + offset] - '0');
393 stamp.tm_isdst = -1;
394
395 time_t tm_t = timegm(&stamp);
396 double time_left = difftime(tm_t, time(NULL));
397 int days_left = (int)(time_left / 86400);
398 char *timeZone = getenv("TZ");
399 setenv("TZ", "GMT", 1);
400 tzset();
401
402 char timestamp[50] = "";
403 strftime(timestamp, 50, "%c %z", localtime(&tm_t));
404 if (timeZone) {
405 setenv("TZ", timeZone, 1);
406 } else {
407 unsetenv("TZ");
408 }
409
410 tzset();
411
412 int time_remaining;
413 if (days_left > 0 && days_left <= days_till_exp_warn) {
414 xasprintf(&sc_cert.output, _("Certificate '%s' expires in %d day(s) (%s)"), commonName,
415 days_left, timestamp);
416 if (days_left > days_till_exp_crit) {
417 sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING);
418 } else {
419 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
420 }
421 } else if (days_left == 0 && time_left > 0) {
422 if (time_left >= 3600) {
423 time_remaining = (int)time_left / 3600;
424 } else {
425 time_remaining = (int)time_left / 60;
426 }
427
428 xasprintf(&sc_cert.output, _("Certificate '%s' expires in %u %s (%s)"), commonName,
429 time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp);
430
431 if (days_left > days_till_exp_crit) {
432 sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING);
433 } else {
434 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
435 }
436 } else if (time_left < 0) {
437 xasprintf(&sc_cert.output, _("Certificate '%s' expired on %s"), commonName, timestamp);
438 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
439 } else if (days_left == 0) {
440 xasprintf(&sc_cert.output, _("Certificate '%s' just expired (%s)"), commonName,
441 timestamp);
442 if (days_left > days_till_exp_crit) {
443 sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING);
444 } else {
445 sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL);
446 }
447 } else {
448 xasprintf(&sc_cert.output, _("Certificate '%s' will expire on %s"), commonName,
449 timestamp);
450 sc_cert = mp_set_subcheck_state(sc_cert, STATE_OK);
451 }
452 X509_free(certificate);
453 return sc_cert;
454# else /* ifndef USE_OPENSSL */
455 xasprintf(&sc_cert.output, _("Plugin does not support checking certificates"));
456 sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING);
457 return sc_cert;
458# endif /* USE_OPENSSL */
459}
325#endif /* HAVE_SSL */ 460#endif /* HAVE_SSL */