diff options
author | Lorenz <12514511+RincewindsHat@users.noreply.github.com> | 2023-03-12 10:59:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-12 10:59:39 +0100 |
commit | 73c24a393b79940b109b3c3608a4008a7fca44f4 (patch) | |
tree | c0eeb5952582a300ec6eef639473b6861339a333 /plugins | |
parent | 357787868b5201ec3e874e7a225b1c944cbbdb4d (diff) | |
parent | ea53555f2d6254da5fec0c1061899a01dd5321ec (diff) | |
download | monitoring-plugins-73c24a393b79940b109b3c3608a4008a7fca44f4.tar.gz |
Merge pull request #1847 from monitoring-plugins/curlfix1845
Fix for SSL host list messup when picking from multiple IPs (#1844)
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/check_curl.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index c37d45d9..e5be1ad5 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -384,8 +384,11 @@ int | |||
384 | lookup_host (const char *host, char *buf, size_t buflen) | 384 | lookup_host (const char *host, char *buf, size_t buflen) |
385 | { | 385 | { |
386 | struct addrinfo hints, *res, *result; | 386 | struct addrinfo hints, *res, *result; |
387 | char addrstr[100]; | ||
388 | size_t addrstr_len; | ||
387 | int errcode; | 389 | int errcode; |
388 | void *ptr; | 390 | void *ptr; |
391 | size_t buflen_remaining = buflen - 1; | ||
389 | 392 | ||
390 | memset (&hints, 0, sizeof (hints)); | 393 | memset (&hints, 0, sizeof (hints)); |
391 | hints.ai_family = address_family; | 394 | hints.ai_family = address_family; |
@@ -395,26 +398,40 @@ lookup_host (const char *host, char *buf, size_t buflen) | |||
395 | errcode = getaddrinfo (host, NULL, &hints, &result); | 398 | errcode = getaddrinfo (host, NULL, &hints, &result); |
396 | if (errcode != 0) | 399 | if (errcode != 0) |
397 | return errcode; | 400 | return errcode; |
398 | 401 | ||
402 | strcpy(buf, ""); | ||
399 | res = result; | 403 | res = result; |
400 | 404 | ||
401 | while (res) { | 405 | while (res) { |
402 | inet_ntop (res->ai_family, res->ai_addr->sa_data, buf, buflen); | 406 | switch (res->ai_family) { |
403 | switch (res->ai_family) { | 407 | case AF_INET: |
404 | case AF_INET: | 408 | ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; |
405 | ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; | 409 | break; |
406 | break; | 410 | case AF_INET6: |
407 | case AF_INET6: | 411 | ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; |
408 | ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; | 412 | break; |
409 | break; | ||
410 | } | 413 | } |
411 | inet_ntop (res->ai_family, ptr, buf, buflen); | 414 | |
412 | if (verbose >= 1) | 415 | inet_ntop (res->ai_family, ptr, addrstr, 100); |
416 | if (verbose >= 1) { | ||
413 | printf ("* getaddrinfo IPv%d address: %s\n", | 417 | printf ("* getaddrinfo IPv%d address: %s\n", |
414 | res->ai_family == PF_INET6 ? 6 : 4, buf); | 418 | res->ai_family == PF_INET6 ? 6 : 4, addrstr); |
419 | } | ||
420 | |||
421 | // Append all IPs to buf as a comma-separated string | ||
422 | addrstr_len = strlen(addrstr); | ||
423 | if (buflen_remaining > addrstr_len + 1) { | ||
424 | if (buf[0] != '\0') { | ||
425 | strncat(buf, ",", buflen_remaining); | ||
426 | buflen_remaining -= 1; | ||
427 | } | ||
428 | strncat(buf, addrstr, buflen_remaining); | ||
429 | buflen_remaining -= addrstr_len; | ||
430 | } | ||
431 | |||
415 | res = res->ai_next; | 432 | res = res->ai_next; |
416 | } | 433 | } |
417 | 434 | ||
418 | freeaddrinfo(result); | 435 | freeaddrinfo(result); |
419 | 436 | ||
420 | return 0; | 437 | return 0; |
@@ -445,7 +462,7 @@ check_http (void) | |||
445 | int i; | 462 | int i; |
446 | char *force_host_header = NULL; | 463 | char *force_host_header = NULL; |
447 | struct curl_slist *host = NULL; | 464 | struct curl_slist *host = NULL; |
448 | char addrstr[100]; | 465 | char addrstr[DEFAULT_BUFFER_SIZE/2]; |
449 | char dnscache[DEFAULT_BUFFER_SIZE]; | 466 | char dnscache[DEFAULT_BUFFER_SIZE]; |
450 | 467 | ||
451 | /* initialize curl */ | 468 | /* initialize curl */ |
@@ -497,7 +514,7 @@ check_http (void) | |||
497 | 514 | ||
498 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy | 515 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy |
499 | if(use_ssl && host_name != NULL) { | 516 | if(use_ssl && host_name != NULL) { |
500 | if ( (res=lookup_host (server_address, addrstr, 100)) != 0) { | 517 | if ( (res=lookup_host (server_address, addrstr, DEFAULT_BUFFER_SIZE/2)) != 0) { |
501 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), | 518 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), |
502 | server_address, res, gai_strerror (res)); | 519 | server_address, res, gai_strerror (res)); |
503 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 520 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); |
@@ -792,6 +809,9 @@ check_http (void) | |||
792 | /* free header and server IP resolve lists, we don't need it anymore */ | 809 | /* free header and server IP resolve lists, we don't need it anymore */ |
793 | curl_slist_free_all (header_list); header_list = NULL; | 810 | curl_slist_free_all (header_list); header_list = NULL; |
794 | curl_slist_free_all (server_ips); server_ips = NULL; | 811 | curl_slist_free_all (server_ips); server_ips = NULL; |
812 | if (host) { | ||
813 | curl_slist_free_all (host); host = NULL; | ||
814 | } | ||
795 | 815 | ||
796 | /* Curl errors, result in critical Nagios state */ | 816 | /* Curl errors, result in critical Nagios state */ |
797 | if (res != CURLE_OK) { | 817 | if (res != CURLE_OK) { |