diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2026-04-08 17:21:44 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-08 17:21:44 +0200 |
| commit | 613cb60c96e21eaafb82b80a6b6d84b1b1f9729f (patch) | |
| tree | b8b0b26ea8b14b74cd92da272c213dccf5356fbd /plugins/check_curl.d | |
| parent | ddd1bd9fbd84b29fb169e592943d1fdfc8ad0d7e (diff) | |
| download | monitoring-plugins-613cb60c96e21eaafb82b80a6b6d84b1b1f9729f.tar.gz | |
check_curl: Clean up (#2252)
* check_curl: remove unused variables
* check_curl: run formatter on related files
* check_curl_helpers: make code a bit more understandable
* check_curl helpers: general api cleanup and code style
Diffstat (limited to 'plugins/check_curl.d')
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.c | 374 | ||||
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.h | 30 |
2 files changed, 244 insertions, 160 deletions
diff --git a/plugins/check_curl.d/check_curl_helpers.c b/plugins/check_curl.d/check_curl_helpers.c index 4372dc0b..f23dbdb7 100644 --- a/plugins/check_curl.d/check_curl_helpers.c +++ b/plugins/check_curl.d/check_curl_helpers.c | |||
| @@ -60,8 +60,8 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 60 | result.curl_state.curl_easy_initialized = true; | 60 | result.curl_state.curl_easy_initialized = true; |
| 61 | 61 | ||
| 62 | if (verbose >= 1) { | 62 | if (verbose >= 1) { |
| 63 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_VERBOSE, 1L), | 63 | handle_curl_option_return_code( |
| 64 | "CURLOPT_VERBOSE"); | 64 | curl_easy_setopt(result.curl_state.curl, CURLOPT_VERBOSE, 1L), "CURLOPT_VERBOSE"); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | /* print everything on stdout like check_http would do */ | 67 | /* print everything on stdout like check_http would do */ |
| @@ -120,21 +120,23 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 120 | "CURLOPT_TIMEOUT"); | 120 | "CURLOPT_TIMEOUT"); |
| 121 | 121 | ||
| 122 | /* set proxy */ | 122 | /* set proxy */ |
| 123 | /* http(s) proxy can either be given from the command line, or taken from environment variables */ | 123 | /* http(s) proxy can either be given from the command line, or taken from environment variables |
| 124 | */ | ||
| 124 | /* socks4(a) / socks5(h) proxy should be given using the command line */ | 125 | /* socks4(a) / socks5(h) proxy should be given using the command line */ |
| 125 | 126 | ||
| 126 | /* first source to check is the environment variables */ | 127 | /* first source to check is the environment variables */ |
| 127 | /* lower case proxy environment variables are almost always accepted, while some programs also checking | 128 | /* lower case proxy environment variables are almost always accepted, while some programs also |
| 128 | uppercase ones. discover both, but take the lowercase one if both are present */ | 129 | checking uppercase ones. discover both, but take the lowercase one if both are present */ |
| 129 | 130 | ||
| 130 | /* extra information: libcurl does not discover the uppercase version HTTP_PROXY due to security reasons */ | 131 | /* extra information: libcurl does not discover the uppercase version HTTP_PROXY due to security |
| 132 | * reasons */ | ||
| 131 | /* https://github.com/curl/curl/blob/d445f2d930ae701039518d695481ee53b8490521/lib/url.c#L1987 */ | 133 | /* https://github.com/curl/curl/blob/d445f2d930ae701039518d695481ee53b8490521/lib/url.c#L1987 */ |
| 132 | 134 | ||
| 133 | /* first environment variable to read is all_proxy. it can be overridden by protocol specific environment variables */ | 135 | /* first environment variable to read is all_proxy. it can be overridden by protocol specific |
| 134 | char *all_proxy_env, *all_proxy_uppercase_env; | 136 | * environment variables */ |
| 135 | all_proxy_env = getenv("all_proxy"); | 137 | char *all_proxy_env = getenv("all_proxy"); |
| 136 | all_proxy_uppercase_env = getenv("ALL_PROXY"); | 138 | char *all_proxy_uppercase_env = getenv("ALL_PROXY"); |
| 137 | if (all_proxy_env != NULL && strlen(all_proxy_env)){ | 139 | if (all_proxy_env != NULL && strlen(all_proxy_env)) { |
| 138 | working_state.curlopt_proxy = strdup(all_proxy_env); | 140 | working_state.curlopt_proxy = strdup(all_proxy_env); |
| 139 | if (all_proxy_uppercase_env != NULL && verbose >= 1) { | 141 | if (all_proxy_uppercase_env != NULL && verbose >= 1) { |
| 140 | printf("* cURL ignoring environment variable 'ALL_PROXY' as 'all_proxy' is set\n"); | 142 | printf("* cURL ignoring environment variable 'ALL_PROXY' as 'all_proxy' is set\n"); |
| @@ -143,15 +145,16 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 143 | working_state.curlopt_proxy = strdup(all_proxy_uppercase_env); | 145 | working_state.curlopt_proxy = strdup(all_proxy_uppercase_env); |
| 144 | } | 146 | } |
| 145 | 147 | ||
| 146 | /* second environment variable to read is http_proxy. only set curlopt_proxy if ssl is not toggled */ | 148 | /* second environment variable to read is http_proxy. only set curlopt_proxy if ssl is not |
| 147 | char *http_proxy_env, *http_proxy_uppercase_env; | 149 | * toggled */ |
| 148 | http_proxy_env = getenv("http_proxy"); | 150 | char *http_proxy_env = getenv("http_proxy"); |
| 149 | http_proxy_uppercase_env = getenv("HTTP_PROXY"); | 151 | char *http_proxy_uppercase_env = getenv("HTTP_PROXY"); |
| 150 | if (!working_state.use_ssl){ | 152 | if (!working_state.use_ssl) { |
| 151 | if (http_proxy_env != NULL && strlen(http_proxy_env) > 0) { | 153 | if (http_proxy_env != NULL && strlen(http_proxy_env) > 0) { |
| 152 | working_state.curlopt_proxy = strdup(http_proxy_env); | 154 | working_state.curlopt_proxy = strdup(http_proxy_env); |
| 153 | if (http_proxy_uppercase_env != NULL && verbose >= 1) { | 155 | if (http_proxy_uppercase_env != NULL && verbose >= 1) { |
| 154 | printf("* cURL ignoring environment variable 'HTTP_PROXY' as 'http_proxy' is set\n"); | 156 | printf( |
| 157 | "* cURL ignoring environment variable 'HTTP_PROXY' as 'http_proxy' is set\n"); | ||
| 155 | } | 158 | } |
| 156 | } else if (http_proxy_uppercase_env != NULL && strlen(http_proxy_uppercase_env) > 0) { | 159 | } else if (http_proxy_uppercase_env != NULL && strlen(http_proxy_uppercase_env) > 0) { |
| 157 | working_state.curlopt_proxy = strdup(http_proxy_uppercase_env); | 160 | working_state.curlopt_proxy = strdup(http_proxy_uppercase_env); |
| @@ -159,30 +162,31 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 159 | } | 162 | } |
| 160 | #ifdef LIBCURL_FEATURE_SSL | 163 | #ifdef LIBCURL_FEATURE_SSL |
| 161 | /* optionally read https_proxy environment variable and set curlopt_proxy if ssl is toggled */ | 164 | /* optionally read https_proxy environment variable and set curlopt_proxy if ssl is toggled */ |
| 162 | char *https_proxy_env, *https_proxy_uppercase_env; | 165 | char *https_proxy_env = getenv("https_proxy"); |
| 163 | https_proxy_env = getenv("https_proxy"); | 166 | char *https_proxy_uppercase_env = getenv("HTTPS_PROXY"); |
| 164 | https_proxy_uppercase_env = getenv("HTTPS_PROXY"); | ||
| 165 | if (working_state.use_ssl) { | 167 | if (working_state.use_ssl) { |
| 166 | if (https_proxy_env != NULL && strlen(https_proxy_env) > 0) { | 168 | if (https_proxy_env != NULL && strlen(https_proxy_env) > 0) { |
| 167 | working_state.curlopt_proxy = strdup(https_proxy_env); | 169 | working_state.curlopt_proxy = strdup(https_proxy_env); |
| 168 | if (https_proxy_uppercase_env != NULL && verbose >= 1) { | 170 | if (https_proxy_uppercase_env != NULL && verbose >= 1) { |
| 169 | printf("* cURL ignoring environment variable 'HTTPS_PROXY' as 'https_proxy' is set\n"); | 171 | printf( |
| 172 | "* cURL ignoring environment variable 'HTTPS_PROXY' as 'https_proxy' is set\n"); | ||
| 170 | } | 173 | } |
| 171 | } | 174 | } else if (https_proxy_uppercase_env != NULL) { |
| 172 | else if (https_proxy_uppercase_env != NULL && strlen(https_proxy_uppercase_env) >= 0) { | ||
| 173 | working_state.curlopt_proxy = strdup(https_proxy_uppercase_env); | 175 | working_state.curlopt_proxy = strdup(https_proxy_uppercase_env); |
| 174 | } | 176 | } |
| 175 | } | 177 | } |
| 176 | #endif /* LIBCURL_FEATURE_SSL */ | 178 | #endif /* LIBCURL_FEATURE_SSL */ |
| 177 | 179 | ||
| 178 | /* second source to check for proxies is command line argument, overwriting the environment variables */ | 180 | /* second source to check for proxies is command line argument, overwriting the environment |
| 181 | * variables */ | ||
| 179 | if (strlen(config.proxy) > 0) { | 182 | if (strlen(config.proxy) > 0) { |
| 180 | working_state.curlopt_proxy = strdup(config.proxy); | 183 | working_state.curlopt_proxy = strdup(config.proxy); |
| 181 | } | 184 | } |
| 182 | 185 | ||
| 183 | if (working_state.curlopt_proxy != NULL && strlen(working_state.curlopt_proxy)){ | 186 | if (working_state.curlopt_proxy != NULL && strlen(working_state.curlopt_proxy)) { |
| 184 | handle_curl_option_return_code( | 187 | handle_curl_option_return_code( |
| 185 | curl_easy_setopt(result.curl_state.curl, CURLOPT_PROXY, working_state.curlopt_proxy), "CURLOPT_PROXY"); | 188 | curl_easy_setopt(result.curl_state.curl, CURLOPT_PROXY, working_state.curlopt_proxy), |
| 189 | "CURLOPT_PROXY"); | ||
| 186 | if (verbose >= 1) { | 190 | if (verbose >= 1) { |
| 187 | printf("* curl CURLOPT_PROXY: %s\n", working_state.curlopt_proxy); | 191 | printf("* curl CURLOPT_PROXY: %s\n", working_state.curlopt_proxy); |
| 188 | } | 192 | } |
| @@ -190,34 +194,35 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 190 | 194 | ||
| 191 | /* set no_proxy */ | 195 | /* set no_proxy */ |
| 192 | /* first source to check is environment variables */ | 196 | /* first source to check is environment variables */ |
| 193 | char *no_proxy_env, *no_proxy_uppercase_env; | 197 | char *no_proxy_env = getenv("no_proxy"); |
| 194 | no_proxy_env = getenv("no_proxy"); | 198 | char *no_proxy_uppercase_env = getenv("NO_PROXY"); |
| 195 | no_proxy_uppercase_env = getenv("NO_PROXY"); | 199 | if (no_proxy_env != NULL && strlen(no_proxy_env)) { |
| 196 | if (no_proxy_env != NULL && strlen(no_proxy_env)){ | ||
| 197 | working_state.curlopt_noproxy = strdup(no_proxy_env); | 200 | working_state.curlopt_noproxy = strdup(no_proxy_env); |
| 198 | if (no_proxy_uppercase_env != NULL && verbose >= 1){ | 201 | if (no_proxy_uppercase_env != NULL && verbose >= 1) { |
| 199 | printf("* cURL ignoring environment variable 'NO_PROXY' as 'no_proxy' is set\n"); | 202 | printf("* cURL ignoring environment variable 'NO_PROXY' as 'no_proxy' is set\n"); |
| 200 | } | 203 | } |
| 201 | }else if (no_proxy_uppercase_env != NULL && strlen(no_proxy_uppercase_env) > 0){ | 204 | } else if (no_proxy_uppercase_env != NULL && strlen(no_proxy_uppercase_env) > 0) { |
| 202 | working_state.curlopt_noproxy = strdup(no_proxy_uppercase_env); | 205 | working_state.curlopt_noproxy = strdup(no_proxy_uppercase_env); |
| 203 | } | 206 | } |
| 204 | 207 | ||
| 205 | /* second source to check for no_proxy is command line argument, overwriting the environment variables */ | 208 | /* second source to check for no_proxy is command line argument, overwriting the environment |
| 209 | * variables */ | ||
| 206 | if (strlen(config.no_proxy) > 0) { | 210 | if (strlen(config.no_proxy) > 0) { |
| 207 | working_state.curlopt_noproxy = strdup(config.no_proxy); | 211 | working_state.curlopt_noproxy = strdup(config.no_proxy); |
| 208 | } | 212 | } |
| 209 | 213 | ||
| 210 | if ( working_state.curlopt_noproxy != NULL && strlen(working_state.curlopt_noproxy)){ | 214 | if (working_state.curlopt_noproxy != NULL && strlen(working_state.curlopt_noproxy)) { |
| 211 | handle_curl_option_return_code( | 215 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_NOPROXY, |
| 212 | curl_easy_setopt(result.curl_state.curl, CURLOPT_NOPROXY, working_state.curlopt_noproxy), "CURLOPT_NOPROXY"); | 216 | working_state.curlopt_noproxy), |
| 217 | "CURLOPT_NOPROXY"); | ||
| 213 | if (verbose >= 1) { | 218 | if (verbose >= 1) { |
| 214 | printf("* curl CURLOPT_NOPROXY: %s\n", working_state.curlopt_noproxy); | 219 | printf("* curl CURLOPT_NOPROXY: %s\n", working_state.curlopt_noproxy); |
| 215 | } | 220 | } |
| 216 | } | 221 | } |
| 217 | 222 | ||
| 218 | int proxy_resolves_hostname = determine_hostname_resolver(working_state, config); | 223 | bool have_local_resolution = hostname_gets_resolved_locally(working_state); |
| 219 | if (verbose >= 1) { | 224 | if (verbose >= 1) { |
| 220 | printf("* proxy_resolves_hostname: %d\n", proxy_resolves_hostname); | 225 | printf("* have local name resolution: %s\n", (have_local_resolution ? "true": "false")); |
| 221 | } | 226 | } |
| 222 | 227 | ||
| 223 | /* enable haproxy protocol */ | 228 | /* enable haproxy protocol */ |
| @@ -231,7 +236,7 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 231 | /* host_name, only required for ssl, because we use the host_name later on to make SNI happy */ | 236 | /* host_name, only required for ssl, because we use the host_name later on to make SNI happy */ |
| 232 | char dnscache[DEFAULT_BUFFER_SIZE]; | 237 | char dnscache[DEFAULT_BUFFER_SIZE]; |
| 233 | char addrstr[DEFAULT_BUFFER_SIZE / 2]; | 238 | char addrstr[DEFAULT_BUFFER_SIZE / 2]; |
| 234 | if (working_state.use_ssl && working_state.host_name != NULL && !proxy_resolves_hostname ) { | 239 | if (working_state.use_ssl && working_state.host_name != NULL && !have_local_resolution) { |
| 235 | char *tmp_mod_address; | 240 | char *tmp_mod_address; |
| 236 | 241 | ||
| 237 | /* lookup_host() requires an IPv6 address without the brackets. */ | 242 | /* lookup_host() requires an IPv6 address without the brackets. */ |
| @@ -682,7 +687,7 @@ char *get_header_value(const struct phr_header *headers, const size_t nof_header | |||
| 682 | return NULL; | 687 | return NULL; |
| 683 | } | 688 | } |
| 684 | 689 | ||
| 685 | check_curl_working_state check_curl_working_state_init() { | 690 | check_curl_working_state check_curl_working_state_init(void) { |
| 686 | check_curl_working_state result = { | 691 | check_curl_working_state result = { |
| 687 | .server_address = NULL, | 692 | .server_address = NULL, |
| 688 | .server_url = DEFAULT_SERVER_URL, | 693 | .server_url = DEFAULT_SERVER_URL, |
| @@ -699,7 +704,7 @@ check_curl_working_state check_curl_working_state_init() { | |||
| 699 | return result; | 704 | return result; |
| 700 | } | 705 | } |
| 701 | 706 | ||
| 702 | check_curl_config check_curl_config_init() { | 707 | check_curl_config check_curl_config_init(void) { |
| 703 | check_curl_config tmp = { | 708 | check_curl_config tmp = { |
| 704 | .initial_config = check_curl_working_state_init(), | 709 | .initial_config = check_curl_working_state_init(), |
| 705 | 710 | ||
| @@ -1404,10 +1409,10 @@ char *fmt_url(check_curl_working_state workingState) { | |||
| 1404 | return url; | 1409 | return url; |
| 1405 | } | 1410 | } |
| 1406 | 1411 | ||
| 1407 | int determine_hostname_resolver(const check_curl_working_state working_state, const check_curl_static_curl_config config){ | 1412 | bool hostname_gets_resolved_locally(const check_curl_working_state working_state) { |
| 1408 | char *host_name_display = "NULL"; | 1413 | char *host_name_display = "NULL"; |
| 1409 | unsigned long host_name_len = 0; | 1414 | unsigned long host_name_len = 0; |
| 1410 | if( working_state.host_name){ | 1415 | if (working_state.host_name) { |
| 1411 | host_name_len = strlen(working_state.host_name); | 1416 | host_name_len = strlen(working_state.host_name); |
| 1412 | host_name_display = working_state.host_name; | 1417 | host_name_display = working_state.host_name; |
| 1413 | } | 1418 | } |
| @@ -1415,8 +1420,11 @@ int determine_hostname_resolver(const check_curl_working_state working_state, co | |||
| 1415 | /* IPv4 or IPv6 version of the address */ | 1420 | /* IPv4 or IPv6 version of the address */ |
| 1416 | char *server_address_clean = strdup(working_state.server_address); | 1421 | char *server_address_clean = strdup(working_state.server_address); |
| 1417 | /* server address might be a full length ipv6 address encapsulated in square brackets */ | 1422 | /* server address might be a full length ipv6 address encapsulated in square brackets */ |
| 1418 | if ((strnlen(working_state.server_address, MAX_IPV4_HOSTLENGTH) > 2) && (working_state.server_address[0] == '[') && (working_state.server_address[strlen(working_state.server_address)-1] == ']') ) { | 1423 | if ((strnlen(working_state.server_address, MAX_IPV4_HOSTLENGTH) > 2) && |
| 1419 | server_address_clean = strndup( working_state.server_address + 1, strlen(working_state.server_address) - 2); | 1424 | (working_state.server_address[0] == '[') && |
| 1425 | (working_state.server_address[strlen(working_state.server_address) - 1] == ']')) { | ||
| 1426 | server_address_clean = | ||
| 1427 | strndup(working_state.server_address + 1, strlen(working_state.server_address) - 2); | ||
| 1420 | } | 1428 | } |
| 1421 | 1429 | ||
| 1422 | /* check curlopt_noproxy option first */ | 1430 | /* check curlopt_noproxy option first */ |
| @@ -1427,79 +1435,90 @@ int determine_hostname_resolver(const check_curl_working_state working_state, co | |||
| 1427 | IPv4 or IPv6 CIDR regions e.g 10.241.0.0/16 , abcd:ef01:2345::/48 , | 1435 | IPv4 or IPv6 CIDR regions e.g 10.241.0.0/16 , abcd:ef01:2345::/48 , |
| 1428 | direct hostnames e.g example.com, google.de */ | 1436 | direct hostnames e.g example.com, google.de */ |
| 1429 | 1437 | ||
| 1430 | if (working_state.curlopt_noproxy != NULL){ | 1438 | if (working_state.curlopt_noproxy != NULL) { |
| 1431 | char* curlopt_noproxy_copy = strdup( working_state.curlopt_noproxy); | 1439 | char *curlopt_noproxy_copy = strdup(working_state.curlopt_noproxy); |
| 1432 | char* noproxy_item = strtok(curlopt_noproxy_copy, ","); | 1440 | char *noproxy_item = strtok(curlopt_noproxy_copy, ","); |
| 1433 | while(noproxy_item != NULL){ | 1441 | while (noproxy_item != NULL) { |
| 1434 | unsigned long noproxy_item_len = strlen(noproxy_item); | 1442 | unsigned long noproxy_item_len = strlen(noproxy_item); |
| 1435 | 1443 | ||
| 1436 | /* According to the CURLOPT_NOPROXY documentation: */ | 1444 | /* According to the CURLOPT_NOPROXY documentation: */ |
| 1437 | /* https://curl.se/libcurl/c/CURLOPT_NOPROXY.html */ | 1445 | /* https://curl.se/libcurl/c/CURLOPT_NOPROXY.html */ |
| 1438 | /* The only wildcard available is a single * character, which matches all hosts, and effectively disables the proxy. */ | 1446 | /* The only wildcard available is a single * character, which matches all hosts, and |
| 1439 | if ( strlen(noproxy_item) == 1 && noproxy_item[0] == '*'){ | 1447 | * effectively disables the proxy. */ |
| 1440 | if (verbose >= 1){ | 1448 | if (strlen(noproxy_item) == 1 && noproxy_item[0] == '*') { |
| 1441 | printf("* noproxy includes '*' which disables proxy for all host name incl. : %s / server address incl. : %s\n", host_name_display , server_address_clean); | 1449 | if (verbose >= 1) { |
| 1450 | printf("* noproxy includes '*' which disables proxy for all host name incl. : " | ||
| 1451 | "%s / server address incl. : %s\n", | ||
| 1452 | host_name_display, server_address_clean); | ||
| 1442 | } | 1453 | } |
| 1443 | free(curlopt_noproxy_copy); | 1454 | free(curlopt_noproxy_copy); |
| 1444 | free(server_address_clean); | 1455 | free(server_address_clean); |
| 1445 | return 0; | 1456 | return true; |
| 1446 | } | 1457 | } |
| 1447 | 1458 | ||
| 1448 | /* direct comparison with the server_address */ | 1459 | /* direct comparison with the server_address */ |
| 1449 | if( server_address_clean != NULL && strlen(server_address_clean) == strlen(noproxy_item) && strcmp(server_address_clean, noproxy_item) == 0){ | 1460 | if (server_address_clean != NULL && |
| 1450 | if (verbose >= 1){ | 1461 | strlen(server_address_clean) == strlen(noproxy_item) && |
| 1462 | strcmp(server_address_clean, noproxy_item) == 0) { | ||
| 1463 | if (verbose >= 1) { | ||
| 1451 | printf("* server_address is in the no_proxy list: %s\n", noproxy_item); | 1464 | printf("* server_address is in the no_proxy list: %s\n", noproxy_item); |
| 1452 | } | 1465 | } |
| 1453 | free(curlopt_noproxy_copy); | 1466 | free(curlopt_noproxy_copy); |
| 1454 | free(server_address_clean); | 1467 | free(server_address_clean); |
| 1455 | return 0; | 1468 | return true; |
| 1456 | } | 1469 | } |
| 1457 | 1470 | ||
| 1458 | /* direct comparison with the host_name */ | 1471 | /* direct comparison with the host_name */ |
| 1459 | if( working_state.host_name != NULL && host_name_len == noproxy_item_len && strcmp(working_state.host_name, noproxy_item) == 0){ | 1472 | if (working_state.host_name != NULL && host_name_len == noproxy_item_len && |
| 1460 | if (verbose >= 1){ | 1473 | strcmp(working_state.host_name, noproxy_item) == 0) { |
| 1474 | if (verbose >= 1) { | ||
| 1461 | printf("* host_name is in the no_proxy list: %s\n", noproxy_item); | 1475 | printf("* host_name is in the no_proxy list: %s\n", noproxy_item); |
| 1462 | } | 1476 | } |
| 1463 | free(curlopt_noproxy_copy); | 1477 | free(curlopt_noproxy_copy); |
| 1464 | free(server_address_clean); | 1478 | free(server_address_clean); |
| 1465 | return 0; | 1479 | return true; |
| 1466 | } | 1480 | } |
| 1467 | 1481 | ||
| 1468 | /* check if hostname is a subdomain of the item, e.g www.example.com when token is example.com */ | 1482 | /* check if hostname is a subdomain of the item, e.g www.example.com when token is |
| 1469 | /* subdomain1.acme.com will not will use a proxy if you only specify 'acme' in the noproxy */ | 1483 | * example.com */ |
| 1484 | /* subdomain1.acme.com will not will use a proxy if you only specify 'acme' in the | ||
| 1485 | * noproxy */ | ||
| 1470 | /* check if noproxy_item is a suffix */ | 1486 | /* check if noproxy_item is a suffix */ |
| 1471 | /* check if the character just before the suffix is '.' */ | 1487 | /* check if the character just before the suffix is '.' */ |
| 1472 | if( working_state.host_name != NULL && host_name_len > noproxy_item_len){ | 1488 | if (working_state.host_name != NULL && host_name_len > noproxy_item_len) { |
| 1473 | unsigned long suffix_start_idx = host_name_len - noproxy_item_len; | 1489 | unsigned long suffix_start_idx = host_name_len - noproxy_item_len; |
| 1474 | if (strcmp(working_state.host_name + suffix_start_idx, noproxy_item ) == 0 && working_state.host_name[suffix_start_idx-1] == '.' ){ | 1490 | if (strcmp(working_state.host_name + suffix_start_idx, noproxy_item) == 0 && |
| 1475 | if (verbose >= 1){ | 1491 | working_state.host_name[suffix_start_idx - 1] == '.') { |
| 1476 | printf("* host_name: %s is a subdomain of the no_proxy list item: %s\n", working_state.host_name , noproxy_item); | 1492 | if (verbose >= 1) { |
| 1493 | printf("* host_name: %s is a subdomain of the no_proxy list item: %s\n", | ||
| 1494 | working_state.host_name, noproxy_item); | ||
| 1477 | } | 1495 | } |
| 1478 | free(curlopt_noproxy_copy); | 1496 | free(curlopt_noproxy_copy); |
| 1479 | free(server_address_clean); | 1497 | free(server_address_clean); |
| 1480 | return 0; | 1498 | return true; |
| 1481 | } | 1499 | } |
| 1482 | } | 1500 | } |
| 1483 | 1501 | ||
| 1484 | // noproxy_item could be a CIDR IP range | 1502 | // noproxy_item could be a CIDR IP range |
| 1485 | if( server_address_clean != NULL && strlen(server_address_clean)){ | 1503 | if (server_address_clean != NULL && strlen(server_address_clean)) { |
| 1486 | 1504 | ip_addr_inside ip_addr_inside_cidr_ret = | |
| 1487 | int ip_addr_inside_cidr_ret = ip_addr_inside_cidr(noproxy_item, server_address_clean); | 1505 | ip_addr_inside_cidr(noproxy_item, server_address_clean); |
| 1488 | 1506 | ||
| 1489 | switch(ip_addr_inside_cidr_ret){ | 1507 | if (ip_addr_inside_cidr_ret.error == NO_ERROR) { |
| 1490 | case 1: | 1508 | if (ip_addr_inside_cidr_ret.inside) { |
| 1491 | return 0; | 1509 | return true; |
| 1492 | break; | 1510 | } else { |
| 1493 | case 0: | 1511 | if (verbose >= 1) { |
| 1494 | if(verbose >= 1){ | 1512 | printf("server address: %s is not inside IP cidr: %s\n", |
| 1495 | printf("server address: %s is not inside IP cidr: %s\n", server_address_clean, noproxy_item); | 1513 | server_address_clean, noproxy_item); |
| 1514 | } | ||
| 1496 | } | 1515 | } |
| 1497 | break; | 1516 | } else { |
| 1498 | case -1: | 1517 | if (verbose >= 1) { |
| 1499 | if(verbose >= 1){ | 1518 | printf("could not fully determine if server address: %s is inside the IP " |
| 1500 | printf("could not fully determine if server address: %s is inside the IP cidr: %s\n", server_address_clean, noproxy_item); | 1519 | "cidr: %s\n", |
| 1520 | server_address_clean, noproxy_item); | ||
| 1501 | } | 1521 | } |
| 1502 | break; | ||
| 1503 | } | 1522 | } |
| 1504 | } | 1523 | } |
| 1505 | 1524 | ||
| @@ -1509,82 +1528,97 @@ int determine_hostname_resolver(const check_curl_working_state working_state, co | |||
| 1509 | free(curlopt_noproxy_copy); | 1528 | free(curlopt_noproxy_copy); |
| 1510 | } | 1529 | } |
| 1511 | 1530 | ||
| 1512 | if (working_state.curlopt_proxy != NULL){ | 1531 | if (working_state.curlopt_proxy != NULL) { |
| 1513 | // Libcurl documentation | 1532 | // Libcurl documentation |
| 1514 | // Setting the proxy string to "" (an empty string) explicitly disables the use of a proxy, even if there is an environment variable set for it. | 1533 | // Setting the proxy string to "" (an empty string) explicitly disables the use of a proxy, |
| 1515 | if ( strlen(working_state.curlopt_proxy) == 0){ | 1534 | // even if there is an environment variable set for it. |
| 1516 | return 0; | 1535 | if (strlen(working_state.curlopt_proxy) == 0) { |
| 1536 | return true; | ||
| 1517 | } | 1537 | } |
| 1518 | 1538 | ||
| 1519 | if ( strncmp( working_state.curlopt_proxy, "http://", 7) == 0){ | 1539 | if (strncmp(working_state.curlopt_proxy, "http://", 7) == 0) { |
| 1520 | if (verbose >= 1){ | 1540 | if (verbose >= 1) { |
| 1521 | printf("* proxy scheme is http, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | 1541 | printf( |
| 1542 | "* proxy scheme is http, proxy: %s resolves host: %s or server_address: %s\n", | ||
| 1543 | working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1522 | } | 1544 | } |
| 1523 | free(server_address_clean); | 1545 | free(server_address_clean); |
| 1524 | return 1; | 1546 | return false; |
| 1525 | } | 1547 | } |
| 1526 | 1548 | ||
| 1527 | if ( strncmp( working_state.curlopt_proxy, "https://", 8) == 0){ | 1549 | if (strncmp(working_state.curlopt_proxy, "https://", 8) == 0) { |
| 1528 | if (verbose >= 1){ | 1550 | if (verbose >= 1) { |
| 1529 | printf("* proxy scheme is https, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | 1551 | printf( |
| 1552 | "* proxy scheme is https, proxy: %s resolves host: %s or server_address: %s\n", | ||
| 1553 | working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1530 | } | 1554 | } |
| 1531 | free(server_address_clean); | 1555 | free(server_address_clean); |
| 1532 | return 1; | 1556 | return false; |
| 1533 | } | 1557 | } |
| 1534 | 1558 | ||
| 1535 | if ( strncmp( working_state.curlopt_proxy, "socks4://", 9) == 0){ | 1559 | if (strncmp(working_state.curlopt_proxy, "socks4://", 9) == 0) { |
| 1536 | if (verbose >= 1){ | 1560 | if (verbose >= 1) { |
| 1537 | printf("* proxy scheme is socks, proxy: %s does not resolve host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | 1561 | printf("* proxy scheme is socks, proxy: %s does not resolve host: %s or " |
| 1562 | "server_address: %s\n", | ||
| 1563 | working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1538 | } | 1564 | } |
| 1539 | free(server_address_clean); | 1565 | free(server_address_clean); |
| 1540 | return 0; | 1566 | return true; |
| 1541 | } | 1567 | } |
| 1542 | 1568 | ||
| 1543 | if ( strncmp( working_state.curlopt_proxy, "socks4a://", 10) == 0){ | 1569 | if (strncmp(working_state.curlopt_proxy, "socks4a://", 10) == 0) { |
| 1544 | if (verbose >= 1){ | 1570 | if (verbose >= 1) { |
| 1545 | printf("* proxy scheme is socks4a, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | 1571 | printf("* proxy scheme is socks4a, proxy: %s resolves host: %s or server_address: " |
| 1572 | "%s\n", | ||
| 1573 | working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1546 | } | 1574 | } |
| 1547 | free(server_address_clean); | 1575 | free(server_address_clean); |
| 1548 | return 1; | 1576 | return false; |
| 1549 | } | 1577 | } |
| 1550 | 1578 | ||
| 1551 | if ( strncmp( working_state.curlopt_proxy, "socks5://", 9) == 0){ | 1579 | if (strncmp(working_state.curlopt_proxy, "socks5://", 9) == 0) { |
| 1552 | if (verbose >= 1){ | 1580 | if (verbose >= 1) { |
| 1553 | printf("* proxy scheme is socks5, proxy: %s does not resolve host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | 1581 | printf("* proxy scheme is socks5, proxy: %s does not resolve host: %s or " |
| 1582 | "server_address: %s\n", | ||
| 1583 | working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1554 | } | 1584 | } |
| 1555 | free(server_address_clean); | 1585 | free(server_address_clean); |
| 1556 | return 0; | 1586 | return true; |
| 1557 | } | 1587 | } |
| 1558 | 1588 | ||
| 1559 | if ( strncmp( working_state.curlopt_proxy, "socks5h://", 10) == 0){ | 1589 | if (strncmp(working_state.curlopt_proxy, "socks5h://", 10) == 0) { |
| 1560 | if (verbose >= 1){ | 1590 | if (verbose >= 1) { |
| 1561 | printf("* proxy scheme is socks5h, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | 1591 | printf("* proxy scheme is socks5h, proxy: %s resolves host: %s or server_address: " |
| 1592 | "%s\n", | ||
| 1593 | working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1562 | } | 1594 | } |
| 1563 | free(server_address_clean); | 1595 | free(server_address_clean); |
| 1564 | return 1; | 1596 | return false; |
| 1565 | } | 1597 | } |
| 1566 | 1598 | ||
| 1567 | // Libcurl documentation: | 1599 | // Libcurl documentation: |
| 1568 | // Without a scheme prefix, CURLOPT_PROXYTYPE can be used to specify which kind of proxy the string identifies. | 1600 | // Without a scheme prefix, CURLOPT_PROXYTYPE can be used to specify which kind of proxy the |
| 1569 | // We do not set this value | 1601 | // string identifies. We do not set this value Without a scheme, it is treated as an http |
| 1570 | // Without a scheme, it is treated as an http proxy | 1602 | // proxy |
| 1571 | 1603 | ||
| 1572 | return 1; | 1604 | return false; |
| 1573 | } | 1605 | } |
| 1574 | 1606 | ||
| 1575 | if (verbose >= 1){ | 1607 | if (verbose >= 1) { |
| 1576 | printf("* proxy scheme is unknown/unavailable, no proxy is assumed for host: %s or server_address: %s\n", host_name_display, server_address_clean); | 1608 | printf("* proxy scheme is unknown/unavailable, no proxy is assumed for host: %s or " |
| 1609 | "server_address: %s\n", | ||
| 1610 | host_name_display, server_address_clean); | ||
| 1577 | } | 1611 | } |
| 1578 | 1612 | ||
| 1579 | free(server_address_clean); | 1613 | free(server_address_clean); |
| 1580 | return 0; | 1614 | return 0; |
| 1581 | } | 1615 | } |
| 1582 | 1616 | ||
| 1583 | int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_ip){ | 1617 | ip_addr_inside ip_addr_inside_cidr(const char *cidr_region_or_ip_addr, const char *target_ip) { |
| 1584 | unsigned int slash_count = 0; | 1618 | unsigned int slash_count = 0; |
| 1585 | unsigned int last_slash_idx = 0; | 1619 | unsigned int last_slash_idx = 0; |
| 1586 | for(size_t i = 0; i < strlen(cidr_region_or_ip_addr); i++){ | 1620 | for (size_t i = 0; i < strlen(cidr_region_or_ip_addr); i++) { |
| 1587 | if(cidr_region_or_ip_addr[i] == '/'){ | 1621 | if (cidr_region_or_ip_addr[i] == '/') { |
| 1588 | slash_count++; | 1622 | slash_count++; |
| 1589 | last_slash_idx = (unsigned int)i; | 1623 | last_slash_idx = (unsigned int)i; |
| 1590 | } | 1624 | } |
| @@ -1592,48 +1626,67 @@ int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_i | |||
| 1592 | 1626 | ||
| 1593 | char *cidr_ip_part = NULL; | 1627 | char *cidr_ip_part = NULL; |
| 1594 | int prefix_length = 0; | 1628 | int prefix_length = 0; |
| 1629 | ip_addr_inside result = { | ||
| 1630 | .inside = false, | ||
| 1631 | .error = NO_ERROR, | ||
| 1632 | }; | ||
| 1595 | 1633 | ||
| 1596 | if (slash_count == 0) { | 1634 | if (slash_count == 0) { |
| 1597 | cidr_ip_part = strdup(cidr_region_or_ip_addr); | 1635 | cidr_ip_part = strdup(cidr_region_or_ip_addr); |
| 1598 | if (!cidr_ip_part) return -1; | 1636 | if (!cidr_ip_part) { |
| 1637 | result.error = FAILED_STRDUP; | ||
| 1638 | return result; | ||
| 1639 | } | ||
| 1599 | } else if (slash_count == 1) { | 1640 | } else if (slash_count == 1) { |
| 1600 | cidr_ip_part = strndup(cidr_region_or_ip_addr, last_slash_idx); | 1641 | cidr_ip_part = strndup(cidr_region_or_ip_addr, last_slash_idx); |
| 1601 | if (!cidr_ip_part) return -1; | 1642 | if (!cidr_ip_part) { |
| 1643 | result.error = FAILED_STRDUP; | ||
| 1644 | return result; | ||
| 1645 | } | ||
| 1602 | 1646 | ||
| 1603 | errno = 0; | 1647 | errno = 0; |
| 1604 | long long tmp = strtoll(cidr_region_or_ip_addr + last_slash_idx + 1, NULL, 10); | 1648 | long long tmp = strtoll(cidr_region_or_ip_addr + last_slash_idx + 1, NULL, 10); |
| 1605 | if (errno == ERANGE) { | 1649 | if (errno == ERANGE) { |
| 1606 | if (verbose >= 1) { | 1650 | if (verbose >= 1) { |
| 1607 | printf("cidr_region_or_ip: %s , could not parse subnet length\n", cidr_region_or_ip_addr); | 1651 | printf("cidr_region_or_ip: %s , could not parse subnet length\n", |
| 1652 | cidr_region_or_ip_addr); | ||
| 1608 | } | 1653 | } |
| 1609 | free(cidr_ip_part); | 1654 | free(cidr_ip_part); |
| 1610 | return -1; | 1655 | result.error = COULD_NOT_PARSE_SUBNET_LENGTH; |
| 1656 | return result; | ||
| 1611 | } | 1657 | } |
| 1612 | prefix_length = (int)tmp; | 1658 | prefix_length = (int)tmp; |
| 1613 | } else { | 1659 | } else { |
| 1614 | printf("cidr_region_or_ip: %s , has %d number of '/' characters, is not a valid cidr_region or IP\n", cidr_region_or_ip_addr, slash_count); | 1660 | if (verbose >= 1) { |
| 1615 | return -1; | 1661 | printf("cidr_region_or_ip: %s , has %d number of '/' characters, is not a valid " |
| 1662 | "cidr_region or IP\n", | ||
| 1663 | cidr_region_or_ip_addr, slash_count); | ||
| 1664 | } | ||
| 1665 | result.error = CIDR_REGION_INVALID; | ||
| 1666 | return result; | ||
| 1616 | } | 1667 | } |
| 1617 | 1668 | ||
| 1618 | int cidr_addr_family, target_addr_family; | 1669 | int cidr_addr_family, target_addr_family; |
| 1619 | if (strchr(cidr_ip_part, ':')){ | 1670 | if (strchr(cidr_ip_part, ':')) { |
| 1620 | cidr_addr_family = AF_INET6; | 1671 | cidr_addr_family = AF_INET6; |
| 1621 | } else { | 1672 | } else { |
| 1622 | cidr_addr_family = AF_INET; | 1673 | cidr_addr_family = AF_INET; |
| 1623 | } | 1674 | } |
| 1624 | 1675 | ||
| 1625 | if (strchr(target_ip, ':')){ | 1676 | if (strchr(target_ip, ':')) { |
| 1626 | target_addr_family = AF_INET6; | 1677 | target_addr_family = AF_INET6; |
| 1627 | } else { | 1678 | } else { |
| 1628 | target_addr_family = AF_INET; | 1679 | target_addr_family = AF_INET; |
| 1629 | } | 1680 | } |
| 1630 | 1681 | ||
| 1631 | if (cidr_addr_family != target_addr_family){ | 1682 | if (cidr_addr_family != target_addr_family) { |
| 1632 | if (verbose >= 1){ | 1683 | if (verbose >= 1) { |
| 1633 | printf("cidr address: %s and target ip address: %s have different address families\n", cidr_ip_part, target_ip); | 1684 | printf("cidr address: %s and target ip address: %s have different address families\n", |
| 1685 | cidr_ip_part, target_ip); | ||
| 1634 | } | 1686 | } |
| 1635 | free(cidr_ip_part); | 1687 | free(cidr_ip_part); |
| 1636 | return 0; | 1688 | result.inside = false; |
| 1689 | return result; | ||
| 1637 | } | 1690 | } |
| 1638 | 1691 | ||
| 1639 | // If no prefix is given, treat the cidr as a single address (full-length prefix) | 1692 | // If no prefix is given, treat the cidr as a single address (full-length prefix) |
| @@ -1644,14 +1697,17 @@ int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_i | |||
| 1644 | int max_bits = (cidr_addr_family == AF_INET) ? 32u : 128u; | 1697 | int max_bits = (cidr_addr_family == AF_INET) ? 32u : 128u; |
| 1645 | if (prefix_length < 0 || prefix_length > max_bits) { | 1698 | if (prefix_length < 0 || prefix_length > max_bits) { |
| 1646 | if (verbose >= 1) { | 1699 | if (verbose >= 1) { |
| 1647 | printf("cidr_region_or_ip: %s has invalid prefix length: %u\n", cidr_region_or_ip_addr, prefix_length); | 1700 | printf("cidr_region_or_ip: %s has invalid prefix length: %u\n", cidr_region_or_ip_addr, |
| 1701 | prefix_length); | ||
| 1648 | } | 1702 | } |
| 1649 | free(cidr_ip_part); | 1703 | free(cidr_ip_part); |
| 1650 | return -1; | 1704 | result.error = CIDR_REGION_INVALID_PREFIX; |
| 1705 | return result; | ||
| 1651 | } | 1706 | } |
| 1652 | 1707 | ||
| 1653 | if (verbose >= 1){ | 1708 | if (verbose >= 1) { |
| 1654 | printf("cidr_region_or_ip: %s , has prefix length: %u\n", cidr_region_or_ip_addr, prefix_length); | 1709 | printf("cidr_region_or_ip: %s , has prefix length: %u\n", cidr_region_or_ip_addr, |
| 1710 | prefix_length); | ||
| 1655 | } | 1711 | } |
| 1656 | 1712 | ||
| 1657 | int inet_pton_rc; | 1713 | int inet_pton_rc; |
| @@ -1659,7 +1715,6 @@ int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_i | |||
| 1659 | uint8_t *target_bytes = NULL; | 1715 | uint8_t *target_bytes = NULL; |
| 1660 | uint8_t cidr_buf[16]; | 1716 | uint8_t cidr_buf[16]; |
| 1661 | uint8_t target_buf[16]; | 1717 | uint8_t target_buf[16]; |
| 1662 | size_t total_bytes = 0; | ||
| 1663 | 1718 | ||
| 1664 | if (cidr_addr_family == AF_INET) { | 1719 | if (cidr_addr_family == AF_INET) { |
| 1665 | struct in_addr cidr_ipv4; | 1720 | struct in_addr cidr_ipv4; |
| @@ -1667,49 +1722,55 @@ int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_i | |||
| 1667 | inet_pton_rc = inet_pton(AF_INET, cidr_ip_part, &cidr_ipv4); | 1722 | inet_pton_rc = inet_pton(AF_INET, cidr_ip_part, &cidr_ipv4); |
| 1668 | if (inet_pton_rc != 1) { | 1723 | if (inet_pton_rc != 1) { |
| 1669 | if (verbose >= 1) { | 1724 | if (verbose >= 1) { |
| 1670 | printf("ip string: %s contains characters not valid for its address family: IPv4\n", cidr_ip_part); | 1725 | printf("ip string: %s contains characters not valid for its address family: IPv4\n", |
| 1726 | cidr_ip_part); | ||
| 1671 | } | 1727 | } |
| 1672 | free(cidr_ip_part); | 1728 | free(cidr_ip_part); |
| 1673 | return -1; | 1729 | result.error = IP_CONTAINS_INVALID_CHARACTERS; |
| 1730 | return result; | ||
| 1674 | } | 1731 | } |
| 1675 | inet_pton_rc = inet_pton(AF_INET, target_ip, &target_ipv4); | 1732 | inet_pton_rc = inet_pton(AF_INET, target_ip, &target_ipv4); |
| 1676 | if (inet_pton_rc != 1) { | 1733 | if (inet_pton_rc != 1) { |
| 1677 | if (verbose >= 1) { | 1734 | if (verbose >= 1) { |
| 1678 | printf("ip string: %s contains characters not valid for its address family: IPv4\n", target_ip); | 1735 | printf("ip string: %s contains characters not valid for its address family: IPv4\n", |
| 1736 | target_ip); | ||
| 1679 | } | 1737 | } |
| 1680 | free(cidr_ip_part); | 1738 | free(cidr_ip_part); |
| 1681 | return -1; | 1739 | result.error = IP_CONTAINS_INVALID_CHARACTERS; |
| 1740 | return result; | ||
| 1682 | } | 1741 | } |
| 1683 | // copy the addresses in network byte order to a buffer for comparison | 1742 | // copy the addresses in network byte order to a buffer for comparison |
| 1684 | memcpy(cidr_buf, &cidr_ipv4.s_addr, 4); | 1743 | memcpy(cidr_buf, &cidr_ipv4.s_addr, 4); |
| 1685 | memcpy(target_buf, &target_ipv4.s_addr, 4); | 1744 | memcpy(target_buf, &target_ipv4.s_addr, 4); |
| 1686 | cidr_bytes = cidr_buf; | 1745 | cidr_bytes = cidr_buf; |
| 1687 | target_bytes = target_buf; | 1746 | target_bytes = target_buf; |
| 1688 | total_bytes = 4; | ||
| 1689 | } else { | 1747 | } else { |
| 1690 | struct in6_addr cidr_ipv6; | 1748 | struct in6_addr cidr_ipv6; |
| 1691 | struct in6_addr target_ipv6; | 1749 | struct in6_addr target_ipv6; |
| 1692 | inet_pton_rc = inet_pton(AF_INET6, cidr_ip_part, &cidr_ipv6); | 1750 | inet_pton_rc = inet_pton(AF_INET6, cidr_ip_part, &cidr_ipv6); |
| 1693 | if (inet_pton_rc != 1) { | 1751 | if (inet_pton_rc != 1) { |
| 1694 | if (verbose >= 1) { | 1752 | if (verbose >= 1) { |
| 1695 | printf("ip string: %s contains characters not valid for its address family: IPv6\n", cidr_ip_part); | 1753 | printf("ip string: %s contains characters not valid for its address family: IPv6\n", |
| 1754 | cidr_ip_part); | ||
| 1696 | } | 1755 | } |
| 1697 | free(cidr_ip_part); | 1756 | free(cidr_ip_part); |
| 1698 | return -1; | 1757 | result.error = IP_CONTAINS_INVALID_CHARACTERS; |
| 1758 | return result; | ||
| 1699 | } | 1759 | } |
| 1700 | inet_pton_rc = inet_pton(AF_INET6, target_ip, &target_ipv6); | 1760 | inet_pton_rc = inet_pton(AF_INET6, target_ip, &target_ipv6); |
| 1701 | if (inet_pton_rc != 1) { | 1761 | if (inet_pton_rc != 1) { |
| 1702 | if (verbose >= 1) { | 1762 | if (verbose >= 1) { |
| 1703 | printf("ip string: %s contains characters not valid for its address family: IPv6\n", target_ip); | 1763 | printf("ip string: %s contains characters not valid for its address family: IPv6\n", |
| 1764 | target_ip); | ||
| 1704 | } | 1765 | } |
| 1705 | free(cidr_ip_part); | 1766 | free(cidr_ip_part); |
| 1706 | return -1; | 1767 | result.error = IP_CONTAINS_INVALID_CHARACTERS; |
| 1768 | return result; | ||
| 1707 | } | 1769 | } |
| 1708 | memcpy(cidr_buf, &cidr_ipv6, 16); | 1770 | memcpy(cidr_buf, &cidr_ipv6, 16); |
| 1709 | memcpy(target_buf, &target_ipv6, 16); | 1771 | memcpy(target_buf, &target_ipv6, 16); |
| 1710 | cidr_bytes = cidr_buf; | 1772 | cidr_bytes = cidr_buf; |
| 1711 | target_bytes = target_buf; | 1773 | target_bytes = target_buf; |
| 1712 | total_bytes = 16; | ||
| 1713 | } | 1774 | } |
| 1714 | 1775 | ||
| 1715 | int prefix_bytes = prefix_length / 8; | 1776 | int prefix_bytes = prefix_length / 8; |
| @@ -1718,10 +1779,13 @@ int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_i | |||
| 1718 | if (prefix_bytes > 0) { | 1779 | if (prefix_bytes > 0) { |
| 1719 | if (memcmp(cidr_bytes, target_bytes, (size_t)prefix_bytes) != 0) { | 1780 | if (memcmp(cidr_bytes, target_bytes, (size_t)prefix_bytes) != 0) { |
| 1720 | if (verbose >= 1) { | 1781 | if (verbose >= 1) { |
| 1721 | printf("the first %d bytes of the cidr_region_or_ip: %s and target_ip: %s are different\n", prefix_bytes, cidr_ip_part, target_ip); | 1782 | printf("the first %d bytes of the cidr_region_or_ip: %s and target_ip: %s are " |
| 1783 | "different\n", | ||
| 1784 | prefix_bytes, cidr_ip_part, target_ip); | ||
| 1722 | } | 1785 | } |
| 1723 | free(cidr_ip_part); | 1786 | free(cidr_ip_part); |
| 1724 | return 0; | 1787 | result.inside = false; |
| 1788 | return result; | ||
| 1725 | } | 1789 | } |
| 1726 | } | 1790 | } |
| 1727 | 1791 | ||
| @@ -1732,13 +1796,19 @@ int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_i | |||
| 1732 | uint8_t mask = (uint8_t)(0xFFu << (8 - prefix_bits)); | 1796 | uint8_t mask = (uint8_t)(0xFFu << (8 - prefix_bits)); |
| 1733 | if ((cidr_oct & mask) != (target_oct & mask)) { | 1797 | if ((cidr_oct & mask) != (target_oct & mask)) { |
| 1734 | if (verbose >= 1) { | 1798 | if (verbose >= 1) { |
| 1735 | printf("looking at the last %d bits of the prefix, cidr_region_or_ip(%s) byte is: %u and target_ip byte(%s) is: %u, applying bitmask: %02X returns different results\n", prefix_bits, cidr_ip_part, (unsigned)cidr_oct, target_ip, (unsigned)target_oct, mask); | 1799 | printf("looking at the last %d bits of the prefix, cidr_region_or_ip(%s) byte is: " |
| 1800 | "%u and target_ip byte(%s) is: %u, applying bitmask: %02X returns different " | ||
| 1801 | "results\n", | ||
| 1802 | prefix_bits, cidr_ip_part, (unsigned)cidr_oct, target_ip, | ||
| 1803 | (unsigned)target_oct, mask); | ||
| 1736 | } | 1804 | } |
| 1737 | free(cidr_ip_part); | 1805 | free(cidr_ip_part); |
| 1738 | return 0; | 1806 | result.inside = false; |
| 1807 | return result; | ||
| 1739 | } | 1808 | } |
| 1740 | } | 1809 | } |
| 1741 | 1810 | ||
| 1742 | free(cidr_ip_part); | 1811 | free(cidr_ip_part); |
| 1743 | return 1; | 1812 | result.inside = true; |
| 1813 | return result; | ||
| 1744 | } | 1814 | } |
diff --git a/plugins/check_curl.d/check_curl_helpers.h b/plugins/check_curl.d/check_curl_helpers.h index cc47bf9d..55df9bc1 100644 --- a/plugins/check_curl.d/check_curl_helpers.h +++ b/plugins/check_curl.d/check_curl_helpers.h | |||
| @@ -127,11 +127,25 @@ mp_subcheck check_curl_certificate_checks(CURL *curl, X509 *cert, int warn_days_ | |||
| 127 | int crit_days_till_exp); | 127 | int crit_days_till_exp); |
| 128 | char *fmt_url(check_curl_working_state workingState); | 128 | char *fmt_url(check_curl_working_state workingState); |
| 129 | 129 | ||
| 130 | 130 | /* determine_hostname_resolver determines if the host or the proxy resolves the target hostname | |
| 131 | /* function that will determine if the host or the proxy resolves the target hostname | 131 | returns RESOLVE_LOCALLY if requester resolves the hostname locally, RESOLVE_REMOTELY if proxy |
| 132 | returns 0 if requester resolves the hostname locally, 1 if proxy resolves the hostname */ | 132 | resolves the hostname */ |
| 133 | int determine_hostname_resolver(const check_curl_working_state working_state, const check_curl_static_curl_config config); | 133 | bool hostname_gets_resolved_locally(const check_curl_working_state working_state); |
| 134 | 134 | ||
| 135 | /* Checks if an IP is inside given CIDR region. Using /protocol_size or not specifying the prefix length performs an equality check. Supports both IPv4 and IPv6 | 135 | /* Checks if an IP is inside given CIDR region. Using /protocol_size or not specifying the prefix |
| 136 | returns 1 if the target_ip address is inside the given cidr_region_or_ip_addr, 0 if its out. return codes < 0 mean an error has occurred. */ | 136 | length performs an equality check. Supports both IPv4 and IPv6 returns 1 if the target_ip address is |
| 137 | int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_ip); | 137 | inside the given cidr_region_or_ip_addr, 0 if its out. return codes < 0 mean an error has occurred. |
| 138 | */ | ||
| 139 | typedef enum { | ||
| 140 | NO_ERROR, | ||
| 141 | FAILED_STRDUP, | ||
| 142 | COULD_NOT_PARSE_SUBNET_LENGTH, | ||
| 143 | CIDR_REGION_INVALID, | ||
| 144 | CIDR_REGION_INVALID_PREFIX, | ||
| 145 | IP_CONTAINS_INVALID_CHARACTERS, | ||
| 146 | } ip_addr_inside_error_code; | ||
| 147 | typedef struct { | ||
| 148 | bool inside; | ||
| 149 | ip_addr_inside_error_code error; | ||
| 150 | } ip_addr_inside; | ||
| 151 | ip_addr_inside ip_addr_inside_cidr(const char *cidr_region_or_ip_addr, const char *target_ip); | ||
