diff options
| -rw-r--r-- | plugins/check_curl.c | 88 | ||||
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.c | 374 | ||||
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.h | 30 | ||||
| -rw-r--r-- | plugins/t/check_curl.t | 44 | ||||
| -rwxr-xr-x | plugins/tests/check_curl.t | 4 |
5 files changed, 324 insertions, 216 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index f63cdea2..b168cbcd 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
| @@ -247,8 +247,9 @@ mp_subcheck check_http(const check_curl_config config, check_curl_working_state | |||
| 247 | printf("**** REQUEST CONTENT ****\n%s\n", workingState.http_post_data); | 247 | printf("**** REQUEST CONTENT ****\n%s\n", workingState.http_post_data); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | // curl_state is updated after curl_easy_perform, and with updated curl_state certificate checks can be done | 250 | // curl_state is updated after curl_easy_perform, and with updated curl_state certificate checks |
| 251 | // Check_http tries to check certs as early as possible, and exits with certificate check result by default. Behave similarly. | 251 | // can be done Check_http tries to check certs as early as possible, and exits with certificate |
| 252 | // check result by default. Behave similarly. | ||
| 252 | #ifdef LIBCURL_FEATURE_SSL | 253 | #ifdef LIBCURL_FEATURE_SSL |
| 253 | if (workingState.use_ssl && config.check_cert) { | 254 | if (workingState.use_ssl && config.check_cert) { |
| 254 | if (verbose > 1) { | 255 | if (verbose > 1) { |
| @@ -1546,8 +1547,8 @@ void print_help(void) { | |||
| 1546 | printf(" %s\n", "-I, --IP-address=ADDRESS"); | 1547 | printf(" %s\n", "-I, --IP-address=ADDRESS"); |
| 1547 | printf(" %s\n", | 1548 | printf(" %s\n", |
| 1548 | "IP address or name (use numeric address if possible to bypass DNS lookup)."); | 1549 | "IP address or name (use numeric address if possible to bypass DNS lookup)."); |
| 1549 | printf(" %s\n", | 1550 | printf(" %s\n", "This overwrites the network address of the target while leaving everything " |
| 1550 | "This overwrites the network address of the target while leaving everything else (HTTP headers) as they are"); | 1551 | "else (HTTP headers) as they are"); |
| 1551 | printf(" %s\n", "-p, --port=INTEGER"); | 1552 | printf(" %s\n", "-p, --port=INTEGER"); |
| 1552 | printf(" %s", _("Port number (default: ")); | 1553 | printf(" %s", _("Port number (default: ")); |
| 1553 | printf("%d)\n", HTTP_PORT); | 1554 | printf("%d)\n", HTTP_PORT); |
| @@ -1611,7 +1612,8 @@ void print_help(void) { | |||
| 1611 | printf(" %s\n", _("String to expect in the content")); | 1612 | printf(" %s\n", _("String to expect in the content")); |
| 1612 | printf(" %s\n", "-u, --url=PATH"); | 1613 | printf(" %s\n", "-u, --url=PATH"); |
| 1613 | printf(" %s\n", _("URL to GET or POST (default: /)")); | 1614 | printf(" %s\n", _("URL to GET or POST (default: /)")); |
| 1614 | printf(" %s\n", _("This is the part after the address in a URL, so for \"https://example.com/index.html\" it would be '-u /index.html'")); | 1615 | printf(" %s\n", _("This is the part after the address in a URL, so for " |
| 1616 | "\"https://example.com/index.html\" it would be '-u /index.html'")); | ||
| 1615 | printf(" %s\n", "-P, --post=STRING"); | 1617 | printf(" %s\n", "-P, --post=STRING"); |
| 1616 | printf(" %s\n", _("URL decoded http POST data")); | 1618 | printf(" %s\n", _("URL decoded http POST data")); |
| 1617 | printf(" %s\n", | 1619 | printf(" %s\n", |
| @@ -1643,11 +1645,12 @@ void print_help(void) { | |||
| 1643 | printf(" %s\n", _("If port is not specified, libcurl defaults to 1080")); | 1645 | printf(" %s\n", _("If port is not specified, libcurl defaults to 1080")); |
| 1644 | printf(" %s\n", _("This value will be set as CURLOPT_PROXY")); | 1646 | printf(" %s\n", _("This value will be set as CURLOPT_PROXY")); |
| 1645 | printf(" %s\n", "--noproxy=COMMA_SEPARATED_LIST"); | 1647 | printf(" %s\n", "--noproxy=COMMA_SEPARATED_LIST"); |
| 1646 | printf(" %s\n", _("Specify hostnames, addresses and subnets where proxy should not be used")); | 1648 | printf(" %s\n", |
| 1649 | _("Specify hostnames, addresses and subnets where proxy should not be used")); | ||
| 1647 | printf(" %s\n", _("Example usage: \"example.com,::1,1.1.1.1,localhost,192.168.0.0/16\"")); | 1650 | printf(" %s\n", _("Example usage: \"example.com,::1,1.1.1.1,localhost,192.168.0.0/16\"")); |
| 1648 | printf(" %s\n", _("Do not use brackets when specifying IPv6 addresses")); | 1651 | printf(" %s\n", _("Do not use brackets when specifying IPv6 addresses")); |
| 1649 | printf(" %s\n", _("Special case when an item is '*' : matches all hosts/addresses " | 1652 | printf(" %s\n", _("Special case when an item is '*' : matches all hosts/addresses " |
| 1650 | "and effectively disables proxy.")); | 1653 | "and effectively disables proxy.")); |
| 1651 | printf(" %s\n", _("This value will be set as CURLOPT_NOPROXY")); | 1654 | printf(" %s\n", _("This value will be set as CURLOPT_NOPROXY")); |
| 1652 | printf(" %s\n", "-a, --authorization=AUTH_PAIR"); | 1655 | printf(" %s\n", "-a, --authorization=AUTH_PAIR"); |
| 1653 | printf(" %s\n", _("Username:password on sites with basic authentication")); | 1656 | printf(" %s\n", _("Username:password on sites with basic authentication")); |
| @@ -1757,38 +1760,59 @@ void print_help(void) { | |||
| 1757 | #endif | 1760 | #endif |
| 1758 | 1761 | ||
| 1759 | printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:"); | 1762 | printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:"); |
| 1760 | printf(" %s\n", _("Proxies are specified or disabled for certain hosts/addresses using environment variables" | 1763 | printf(" %s\n", _("Proxies are specified or disabled for certain hosts/addresses using " |
| 1761 | " or -x/--proxy and --noproxy arguments:")); | 1764 | "environment variables" |
| 1762 | printf(" %s\n", _("Checked environment variables: all_proxy, http_proxy, https_proxy, no_proxy")); | 1765 | " or -x/--proxy and --noproxy arguments:")); |
| 1763 | printf(" %s\n", _("Environment variables can also be given in uppercase, but the lowercase ones will " | 1766 | printf(" %s\n", |
| 1764 | "take predence if both are defined.")); | 1767 | _("Checked environment variables: all_proxy, http_proxy, https_proxy, no_proxy")); |
| 1765 | printf(" %s\n", _("The environment variables are overwritten by -x/--proxy and --noproxy arguments:")); | 1768 | printf(" %s\n", |
| 1769 | _("Environment variables can also be given in uppercase, but the lowercase ones will " | ||
| 1770 | "take predence if both are defined.")); | ||
| 1771 | printf(" %s\n", | ||
| 1772 | _("The environment variables are overwritten by -x/--proxy and --noproxy arguments:")); | ||
| 1766 | printf(" %s\n", _("all_proxy/ALL_PROXY environment variables are read first, but protocol " | 1773 | printf(" %s\n", _("all_proxy/ALL_PROXY environment variables are read first, but protocol " |
| 1767 | "specific environment variables override them.")); | 1774 | "specific environment variables override them.")); |
| 1768 | printf(" %s\n", _("If SSL is enabled and used, https_proxy/HTTPS_PROXY will be checked and overwrite " | 1775 | printf(" %s\n", |
| 1769 | "http_proxy/HTTPS_PROXY.")); | 1776 | _("If SSL is enabled and used, https_proxy/HTTPS_PROXY will be checked and overwrite " |
| 1770 | printf(" %s\n", _("Curl accepts proxies using http, https, socks4, socks4a, socks5 and socks5h schemes.")); | 1777 | "http_proxy/HTTPS_PROXY.")); |
| 1771 | printf(" %s\n", _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org")); | 1778 | printf( |
| 1772 | printf(" %s\n", _("http_proxy=http://used.proxy.com HTTP_PROXY=http://ignored.proxy.com ./check_curl -H www.monitoring-plugins.org")); | 1779 | " %s\n", |
| 1780 | _("Curl accepts proxies using http, https, socks4, socks4a, socks5 and socks5h schemes.")); | ||
| 1781 | printf(" %s\n", | ||
| 1782 | _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org")); | ||
| 1783 | printf(" %s\n", _("http_proxy=http://used.proxy.com HTTP_PROXY=http://ignored.proxy.com " | ||
| 1784 | "./check_curl -H www.monitoring-plugins.org")); | ||
| 1773 | printf(" %s\n", _(" Lowercase http_proxy takes predence over uppercase HTTP_PROXY")); | 1785 | printf(" %s\n", _(" Lowercase http_proxy takes predence over uppercase HTTP_PROXY")); |
| 1774 | printf(" %s\n", _("./check_curl -H www.monitoring-plugins.org -x http://192.168.100.35:3128")); | 1786 | printf(" %s\n", _("./check_curl -H www.monitoring-plugins.org -x http://192.168.100.35:3128")); |
| 1775 | printf(" %s\n", _("http_proxy=http://unused.proxy1.com HTTP_PROXY=http://unused.proxy2.com ./check_curl " | 1787 | printf(" %s\n", |
| 1776 | "-H www.monitoring-plugins.org --proxy http://used.proxy")); | 1788 | _("http_proxy=http://unused.proxy1.com HTTP_PROXY=http://unused.proxy2.com ./check_curl " |
| 1777 | printf(" %s\n", _(" Proxy specified by --proxy overrides any proxy specified by environment variable.")); | 1789 | "-H www.monitoring-plugins.org --proxy http://used.proxy")); |
| 1790 | printf( | ||
| 1791 | " %s\n", | ||
| 1792 | _(" Proxy specified by --proxy overrides any proxy specified by environment variable.")); | ||
| 1778 | printf(" %s\n", _(" Curl uses port 1080 by default as port is not specified")); | 1793 | printf(" %s\n", _(" Curl uses port 1080 by default as port is not specified")); |
| 1779 | printf(" %s\n", _("HTTPS_PROXY=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org --ssl")); | 1794 | printf(" %s\n", _("HTTPS_PROXY=http://192.168.100.35:3128 ./check_curl -H " |
| 1795 | "www.monitoring-plugins.org --ssl")); | ||
| 1780 | printf(" %s\n", _(" HTTPS_PROXY is read as --ssl is toggled")); | 1796 | printf(" %s\n", _(" HTTPS_PROXY is read as --ssl is toggled")); |
| 1781 | printf(" %s\n", _("./check_curl -H www.monitoring-plugins.org --proxy socks5h://192.168.122.21")); | 1797 | printf(" %s\n", |
| 1782 | printf(" %s\n", _("./check_curl -H www.monitoring-plugins.org -x http://unused.proxy.com --noproxy '*'")); | 1798 | _("./check_curl -H www.monitoring-plugins.org --proxy socks5h://192.168.122.21")); |
| 1799 | printf( | ||
| 1800 | " %s\n", | ||
| 1801 | _("./check_curl -H www.monitoring-plugins.org -x http://unused.proxy.com --noproxy '*'")); | ||
| 1783 | printf(" %s\n", _(" Disabled proxy for all hosts by using '*' in no_proxy .")); | 1802 | printf(" %s\n", _(" Disabled proxy for all hosts by using '*' in no_proxy .")); |
| 1784 | printf(" %s\n", _("NO_PROXY=www.monitoring-plugins.org ./check_curl -H www.monitoring-plugins.org -x http://unused.proxy.com")); | 1803 | printf(" %s\n", _("NO_PROXY=www.monitoring-plugins.org ./check_curl -H " |
| 1804 | "www.monitoring-plugins.org -x http://unused.proxy.com")); | ||
| 1785 | printf(" %s\n", _(" Exact matches with the hostname/address work.")); | 1805 | printf(" %s\n", _(" Exact matches with the hostname/address work.")); |
| 1786 | printf(" %s\n", _("no_proxy=192.168.178.0/24 ./check_curl -I 192.168.178.10 -x http://proxy.acme.org")); | 1806 | printf(" %s\n", |
| 1787 | printf(" %s\n", _("no_proxy=acme.org ./check_curl -H nonpublic.internalwebapp.acme.org -x http://proxy.acme.org")); | 1807 | _("no_proxy=192.168.178.0/24 ./check_curl -I 192.168.178.10 -x http://proxy.acme.org")); |
| 1788 | printf(" %s\n", _(" Do not use proxy when accessing internal domains/addresses, but use a default proxy when accessing public web.")); | 1808 | printf(" %s\n", _("no_proxy=acme.org ./check_curl -H nonpublic.internalwebapp.acme.org -x " |
| 1789 | printf(" %s\n", _(" IMPORTANT: Check_curl can not always determine whether itself or the proxy will " | 1809 | "http://proxy.acme.org")); |
| 1790 | "resolve a hostname before sending a request and getting an answer." | 1810 | printf(" %s\n", _(" Do not use proxy when accessing internal domains/addresses, but use a " |
| 1791 | "This can lead to DNS resolvation issues if hostname is only resolvable over proxy.")); | 1811 | "default proxy when accessing public web.")); |
| 1812 | printf(" %s\n", | ||
| 1813 | _(" IMPORTANT: Check_curl can not always determine whether itself or the proxy will " | ||
| 1814 | "resolve a hostname before sending a request and getting an answer." | ||
| 1815 | "This can lead to DNS resolvation issues if hostname is only resolvable over proxy.")); | ||
| 1792 | printf(" %s\n", _("Legacy proxy requests in check_http style still work:")); | 1816 | printf(" %s\n", _("Legacy proxy requests in check_http style still work:")); |
| 1793 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ " | 1817 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ " |
| 1794 | "-H www.monitoring-plugins.org")); | 1818 | "-H www.monitoring-plugins.org")); |
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); | ||
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index a8326f12..0f4d0de7 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t | |||
| @@ -238,100 +238,100 @@ SKIP: { | |||
| 238 | 238 | ||
| 239 | # Test if proxy works | 239 | # Test if proxy works |
| 240 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | 240 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 241 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | 241 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used, there are no preventative measures "); |
| 242 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | 242 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); |
| 243 | 243 | ||
| 244 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | 244 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 245 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | 245 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used, there are no preventative measures "); |
| 246 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_ipv4 works" ); | 246 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_ipv4 works" ); |
| 247 | 247 | ||
| 248 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | 248 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 249 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | 249 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used, there are no preventative measures "); |
| 250 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_ipv6 works" ); | 250 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_ipv6 works" ); |
| 251 | 251 | ||
| 252 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | 252 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 253 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | 253 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used, there are no preventative measures "); |
| 254 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http2 works" ); | 254 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http2 works" ); |
| 255 | 255 | ||
| 256 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | 256 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 257 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | 257 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used, there are no preventative measures "); |
| 258 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_subdomain works" ); | 258 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_subdomain works" ); |
| 259 | 259 | ||
| 260 | $res = NPTest->testCmd( "./$plugin -H $host_tls_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | 260 | $res = NPTest->testCmd( "./$plugin -H $host_tls_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 261 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | 261 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used, there are no preventative measures "); |
| 262 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tls_http works" ); | 262 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tls_http works" ); |
| 263 | 263 | ||
| 264 | # Noproxy '*' should prevent using proxy in any setting, even if its specified | 264 | # Noproxy '*' should prevent using proxy in any setting, even if its specified |
| 265 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); | 265 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); |
| 266 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since noproxy has \"\*\" "); | 266 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since noproxy has \"\*\" "); |
| 267 | is( $res->return_code, 0, "Should reach $host_tcp_http_subdomain with or without proxy." ); | 267 | is( $res->return_code, 0, "Should reach $host_tcp_http_subdomain with or without proxy." ); |
| 268 | 268 | ||
| 269 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); | 269 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); |
| 270 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since noproxy has \"\*\" "); | 270 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since noproxy has \"\*\" "); |
| 271 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | 271 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); |
| 272 | 272 | ||
| 273 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); | 273 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); |
| 274 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since noproxy has \"\*\" "); | 274 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since noproxy has \"\*\" "); |
| 275 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | 275 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); |
| 276 | 276 | ||
| 277 | # Noproxy domain should prevent using proxy for subdomains of that domain | 277 | # Noproxy domain should prevent using proxy for subdomains of that domain |
| 278 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http -v" ); | 278 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http -v" ); |
| 279 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since subdomain: $host_tcp_http_subdomain is under a noproxy domain: $host_tcp_http"); | 279 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since subdomain: $host_tcp_http_subdomain is under a noproxy domain: $host_tcp_http"); |
| 280 | is( $res->return_code, 0, "Should reach $host_tcp_http_subdomain with or without proxy." ); | 280 | is( $res->return_code, 0, "Should reach $host_tcp_http_subdomain with or without proxy." ); |
| 281 | 281 | ||
| 282 | # Noproxy should prevent using IP matches if an IP is found directly | 282 | # Noproxy should prevent using IP matches if an IP is found directly |
| 283 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4 -v" ); | 283 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4 -v" ); |
| 284 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is added into noproxy: $host_tcp_http_ipv4"); | 284 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is added into noproxy: $host_tcp_http_ipv4"); |
| 285 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | 285 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); |
| 286 | 286 | ||
| 287 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6 -v" ); | 287 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6 -v" ); |
| 288 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is added into noproxy: $host_tcp_http_ipv6"); | 288 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is added into noproxy: $host_tcp_http_ipv6"); |
| 289 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | 289 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); |
| 290 | 290 | ||
| 291 | # Noproxy should prevent using IP matches if a CIDR region that contains that Ip is used directly. | 291 | # Noproxy should prevent using IP matches if a CIDR region that contains that Ip is used directly. |
| 292 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4_cidr_1 -v" ); | 292 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4_cidr_1 -v" ); |
| 293 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is inside CIDR range: $host_tcp_http_ipv4_cidr_1"); | 293 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is inside CIDR range: $host_tcp_http_ipv4_cidr_1"); |
| 294 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | 294 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); |
| 295 | 295 | ||
| 296 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4_cidr_2 -v" ); | 296 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4_cidr_2 -v" ); |
| 297 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is inside CIDR range: $host_tcp_http_ipv4_cidr_2"); | 297 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is inside CIDR range: $host_tcp_http_ipv4_cidr_2"); |
| 298 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | 298 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); |
| 299 | 299 | ||
| 300 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6_cidr_1 -v " ); | 300 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6_cidr_1 -v " ); |
| 301 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is inside CIDR range: $host_tcp_http_ipv6_cidr_1"); | 301 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is inside CIDR range: $host_tcp_http_ipv6_cidr_1"); |
| 302 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | 302 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); |
| 303 | 303 | ||
| 304 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6_cidr_2 -v" ); | 304 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6_cidr_2 -v" ); |
| 305 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is inside CIDR range: $host_tcp_http_ipv6_cidr_2"); | 305 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is inside CIDR range: $host_tcp_http_ipv6_cidr_2"); |
| 306 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | 306 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); |
| 307 | 307 | ||
| 308 | # Noproxy should discern over different types of proxy schemes | 308 | # Noproxy should discern over different types of proxy schemes |
| 309 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | 309 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 310 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme http "); | 310 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used for resolving hostname, and is using scheme http "); |
| 311 | is( $res->return_code, 0, "Using proxy http:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | 311 | is( $res->return_code, 0, "Using proxy http:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); |
| 312 | 312 | ||
| 313 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy https://$host_tcp_proxy:$port_tcp_proxy -v" ); | 313 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy https://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 314 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme https"); | 314 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used for resolving hostname, and is using scheme https"); |
| 315 | # Squid is not configured for https | 315 | # Squid is not configured for https |
| 316 | # is( $res->return_code, 0, "Using proxy https:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | 316 | # is( $res->return_code, 0, "Using proxy https:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); |
| 317 | 317 | ||
| 318 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks4://$host_tcp_proxy:$port_tcp_proxy -v" ); | 318 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks4://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 319 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used for resolving hostname, and is using scheme socks4"); | 319 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used for resolving hostname, and is using scheme socks4"); |
| 320 | # Squid is not configured for socks4 | 320 | # Squid is not configured for socks4 |
| 321 | # is( $res->return_code, 0, "Using proxy socks4:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | 321 | # is( $res->return_code, 0, "Using proxy socks4:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); |
| 322 | 322 | ||
| 323 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks4a://$host_tcp_proxy:$port_tcp_proxy -v" ); | 323 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks4a://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 324 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme socks4a"); | 324 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used for resolving hostname, and is using scheme socks4a"); |
| 325 | # Squid is not configured for socks4a | 325 | # Squid is not configured for socks4a |
| 326 | # is( $res->return_code, 0, "Using proxy socks4a:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | 326 | # is( $res->return_code, 0, "Using proxy socks4a:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); |
| 327 | 327 | ||
| 328 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks5://$host_tcp_proxy:$port_tcp_proxy -v" ); | 328 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks5://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 329 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used for resolving hostname, and is using scheme socks5"); | 329 | like($res->output, qr/^\* have local name resolution: true/m, "proxy is not used for resolving hostname, and is using scheme socks5"); |
| 330 | # Squid is not configured for socks5 | 330 | # Squid is not configured for socks5 |
| 331 | # is( $res->return_code, 0, "Using proxy socks5:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | 331 | # is( $res->return_code, 0, "Using proxy socks5:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); |
| 332 | 332 | ||
| 333 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks5h://$host_tcp_proxy:$port_tcp_proxy -v" ); | 333 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks5h://$host_tcp_proxy:$port_tcp_proxy -v" ); |
| 334 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme socks5h"); | 334 | like($res->output, qr/^\* have local name resolution: false/m, "proxy is used for resolving hostname, and is using scheme socks5h"); |
| 335 | # Squid is not configured for socks5h | 335 | # Squid is not configured for socks5h |
| 336 | # is( $res->return_code, 0, "Using proxy socks5h:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | 336 | # is( $res->return_code, 0, "Using proxy socks5h:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); |
| 337 | } | 337 | } |
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index e027b6f4..d0a866cb 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t | |||
| @@ -833,12 +833,12 @@ sub run_common_tests { | |||
| 833 | $cmd = "$command -u /statuscode/200 --proxy http://proxy.example.com:8080 --noproxy '*' -v"; | 833 | $cmd = "$command -u /statuscode/200 --proxy http://proxy.example.com:8080 --noproxy '*' -v"; |
| 834 | $result = NPTest->testCmd( $cmd ); | 834 | $result = NPTest->testCmd( $cmd ); |
| 835 | is( $result->return_code, 0, $cmd); | 835 | is( $result->return_code, 0, $cmd); |
| 836 | like( $result->output, '/.*proxy_resolves_hostname: 0.*/', "Proxy will not be used due to '*' in noproxy: ".$result->output ); | 836 | like( $result->output, '/.*have local name resolution: true.*/', "Proxy will not be used due to '*' in noproxy: ".$result->output ); |
| 837 | 837 | ||
| 838 | $cmd = "$command -u /statuscode/200 --proxy http://proxy.example.com:8080 --noproxy '127.0.0.1' -v"; | 838 | $cmd = "$command -u /statuscode/200 --proxy http://proxy.example.com:8080 --noproxy '127.0.0.1' -v"; |
| 839 | $result = NPTest->testCmd( $cmd ); | 839 | $result = NPTest->testCmd( $cmd ); |
| 840 | is( $result->return_code, 0, $cmd); | 840 | is( $result->return_code, 0, $cmd); |
| 841 | like( $result->output, '/.*proxy_resolves_hostname: 0.*/', "Proxy will not be used due to '127.0.0.1' in noproxy: ".$result->output ); | 841 | like( $result->output, '/.*have local name resolution: true.*/', "Proxy will not be used due to '127.0.0.1' in noproxy: ".$result->output ); |
| 842 | } | 842 | } |
| 843 | 843 | ||
| 844 | } | 844 | } |
