diff options
Diffstat (limited to 'plugins/sslutils.c')
| -rw-r--r-- | plugins/sslutils.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/plugins/sslutils.c b/plugins/sslutils.c index 0e6d7525..c58a35ab 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c | |||
| @@ -312,6 +312,138 @@ mp_state_enum np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_ | |||
| 312 | # endif /* USE_OPENSSL */ | 312 | # endif /* USE_OPENSSL */ |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | retrieve_expiration_time_result np_net_ssl_get_cert_expiration(X509 *certificate) { | ||
| 316 | # ifdef USE_OPENSSL | ||
| 317 | retrieve_expiration_time_result result = { | ||
| 318 | .errors = ALL_OK, | ||
| 319 | .remaining_seconds = 0, | ||
| 320 | }; | ||
| 321 | |||
| 322 | if (!certificate) { | ||
| 323 | // printf("%s\n", _("CRITICAL - No server certificate present to inspect.")); | ||
| 324 | result.errors = NO_SERVER_CERTIFICATE_PRESENT; | ||
| 325 | return result; | ||
| 326 | } | ||
| 327 | |||
| 328 | /* Extract CN from certificate subject */ | ||
| 329 | X509_NAME *subj = X509_get_subject_name(certificate); | ||
| 330 | |||
| 331 | if (!subj) { | ||
| 332 | // printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject.")); | ||
| 333 | result.errors = UNABLE_TO_RETRIEVE_CERTIFICATE_SUBJECT; | ||
| 334 | return result; | ||
| 335 | } | ||
| 336 | |||
| 337 | char cn[MAX_CN_LENGTH] = ""; | ||
| 338 | int cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn)); | ||
| 339 | if (cnlen == -1) { | ||
| 340 | strcpy(cn, _("Unknown CN")); | ||
| 341 | } | ||
| 342 | |||
| 343 | /* Retrieve timestamp of certificate */ | ||
| 344 | ASN1_STRING *expiration_timestamp = X509_get_notAfter(certificate); | ||
| 345 | |||
| 346 | int offset = 0; | ||
| 347 | struct tm stamp = {}; | ||
| 348 | /* Generate tm structure to process timestamp */ | ||
| 349 | if (expiration_timestamp->type == V_ASN1_UTCTIME) { | ||
| 350 | if (expiration_timestamp->length < 10) { | ||
| 351 | result.errors = WRONG_TIME_FORMAT_IN_CERTIFICATE; | ||
| 352 | return result; | ||
| 353 | } | ||
| 354 | |||
| 355 | stamp.tm_year = | ||
| 356 | (expiration_timestamp->data[0] - '0') * 10 + (expiration_timestamp->data[1] - '0'); | ||
| 357 | if (stamp.tm_year < 50) { | ||
| 358 | stamp.tm_year += 100; | ||
| 359 | } | ||
| 360 | offset = 0; | ||
| 361 | } else { | ||
| 362 | if (expiration_timestamp->length < 12) { | ||
| 363 | result.errors = WRONG_TIME_FORMAT_IN_CERTIFICATE; | ||
| 364 | return result; | ||
| 365 | } | ||
| 366 | |||
| 367 | stamp.tm_year = (expiration_timestamp->data[0] - '0') * 1000 + | ||
| 368 | (expiration_timestamp->data[1] - '0') * 100 + | ||
| 369 | (expiration_timestamp->data[2] - '0') * 10 + | ||
| 370 | (expiration_timestamp->data[3] - '0'); | ||
| 371 | stamp.tm_year -= 1900; | ||
| 372 | offset = 2; | ||
| 373 | } | ||
| 374 | stamp.tm_mon = (expiration_timestamp->data[2 + offset] - '0') * 10 + | ||
| 375 | (expiration_timestamp->data[3 + offset] - '0') - 1; | ||
| 376 | stamp.tm_mday = (expiration_timestamp->data[4 + offset] - '0') * 10 + | ||
| 377 | (expiration_timestamp->data[5 + offset] - '0'); | ||
| 378 | stamp.tm_hour = (expiration_timestamp->data[6 + offset] - '0') * 10 + | ||
| 379 | (expiration_timestamp->data[7 + offset] - '0'); | ||
| 380 | stamp.tm_min = (expiration_timestamp->data[8 + offset] - '0') * 10 + | ||
| 381 | (expiration_timestamp->data[9 + offset] - '0'); | ||
| 382 | stamp.tm_sec = (expiration_timestamp->data[10 + offset] - '0') * 10 + | ||
| 383 | (expiration_timestamp->data[11 + offset] - '0'); | ||
| 384 | stamp.tm_isdst = -1; | ||
| 385 | |||
| 386 | time_t tm_t = timegm(&stamp); | ||
| 387 | double time_left = difftime(tm_t, time(NULL)); | ||
| 388 | result.remaining_seconds = time_left; | ||
| 389 | |||
| 390 | char *timezone = getenv("TZ"); | ||
| 391 | setenv("TZ", "GMT", 1); | ||
| 392 | tzset(); | ||
| 393 | |||
| 394 | char timestamp[50] = ""; | ||
| 395 | strftime(timestamp, 50, "%c %z", localtime(&tm_t)); | ||
| 396 | if (timezone) { | ||
| 397 | setenv("TZ", timezone, 1); | ||
| 398 | } else { | ||
| 399 | unsetenv("TZ"); | ||
| 400 | } | ||
| 401 | |||
| 402 | tzset(); | ||
| 403 | |||
| 404 | X509_free(certificate); | ||
| 405 | |||
| 406 | return result; | ||
| 407 | # else /* ifndef USE_OPENSSL */ | ||
| 408 | printf("%s\n", _("WARNING - Plugin does not support checking certificates.")); | ||
| 409 | return STATE_WARNING; | ||
| 410 | # endif /* USE_OPENSSL */ | ||
| 411 | } | ||
| 412 | |||
| 413 | net_ssl_check_cert_result np_net_ssl_check_cert2(int days_till_exp_warn, int days_till_exp_crit) { | ||
| 414 | # ifdef USE_OPENSSL | ||
| 415 | X509 *certificate = NULL; | ||
| 416 | certificate = SSL_get_peer_certificate(s); | ||
| 417 | |||
| 418 | retrieve_expiration_time_result expiration_date = np_net_ssl_get_cert_expiration(certificate); | ||
| 419 | |||
| 420 | net_ssl_check_cert_result result = { | ||
| 421 | .result_state = STATE_UNKNOWN, | ||
| 422 | .remaining_seconds = expiration_date.remaining_seconds, | ||
| 423 | .errors = expiration_date.errors, | ||
| 424 | }; | ||
| 425 | |||
| 426 | if (expiration_date.errors == ALL_OK) { | ||
| 427 | // got a valid expiration date | ||
| 428 | unsigned int remaining_days = result.remaining_seconds / 86400; | ||
| 429 | |||
| 430 | if (remaining_days < days_till_exp_crit) { | ||
| 431 | result.result_state = STATE_CRITICAL; | ||
| 432 | } else if (remaining_days < days_till_exp_warn) { | ||
| 433 | result.result_state = STATE_WARNING; | ||
| 434 | } else { | ||
| 435 | result.result_state = STATE_OK; | ||
| 436 | } | ||
| 437 | } | ||
| 438 | |||
| 439 | return result; | ||
| 440 | |||
| 441 | # else /* ifndef USE_OPENSSL */ | ||
| 442 | printf("%s\n", _("WARNING - Plugin does not support checking certificates.")); | ||
| 443 | return STATE_WARNING; | ||
| 444 | # endif /* USE_OPENSSL */ | ||
| 445 | } | ||
| 446 | |||
| 315 | mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) { | 447 | mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) { |
| 316 | # ifdef USE_OPENSSL | 448 | # ifdef USE_OPENSSL |
| 317 | X509 *certificate = NULL; | 449 | X509 *certificate = NULL; |
