diff options
Diffstat (limited to 'plugins/check_curl.c')
-rw-r--r-- | plugins/check_curl.c | 1162 |
1 files changed, 574 insertions, 588 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 8ef48d0c..8ed1aeeb 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * normal (http) and secure (https) servers, follow redirects, search for | 13 | * normal (http) and secure (https) servers, follow redirects, search for |
14 | * strings and regular expressions, check connection times, and report on | 14 | * strings and regular expressions, check connection times, and report on |
15 | * certificate expiration times. | 15 | * certificate expiration times. |
16 | * | 16 | * |
17 | * This plugin uses functions from the curl library, see | 17 | * This plugin uses functions from the curl library, see |
18 | * http://curl.haxx.se | 18 | * http://curl.haxx.se |
19 | * | 19 | * |
@@ -40,20 +40,6 @@ const char *email = "devel@monitoring-plugins.org"; | |||
40 | #include "common.h" | 40 | #include "common.h" |
41 | #include "utils.h" | 41 | #include "utils.h" |
42 | 42 | ||
43 | #ifdef HAVE_SYS_TYPES_H | ||
44 | #include <sys/types.h> | ||
45 | #else | ||
46 | #define unsigned int size_t | ||
47 | #endif | ||
48 | |||
49 | #ifdef HAVE_STRING_H | ||
50 | #include <string.h> | ||
51 | #endif | ||
52 | |||
53 | #ifdef HAVE_STDLIB_H | ||
54 | #include <stdlib.h> | ||
55 | #endif | ||
56 | |||
57 | #ifndef LIBCURL_PROTOCOL_HTTP | 43 | #ifndef LIBCURL_PROTOCOL_HTTP |
58 | #error libcurl compiled without HTTP support, compiling check_curl plugin makes not much sense | 44 | #error libcurl compiled without HTTP support, compiling check_curl plugin makes not much sense |
59 | #endif | 45 | #endif |
@@ -69,21 +55,21 @@ const char *email = "devel@monitoring-plugins.org"; | |||
69 | 55 | ||
70 | /* for buffers for header and body */ | 56 | /* for buffers for header and body */ |
71 | typedef struct { | 57 | typedef struct { |
72 | char *buf; | 58 | char *buf; |
73 | size_t buflen; | 59 | size_t buflen; |
74 | size_t bufsize; | 60 | size_t bufsize; |
75 | } curlhelp_curlbuf; | 61 | } curlhelp_curlbuf; |
76 | 62 | ||
77 | /* for parsing the HTTP status line */ | 63 | /* for parsing the HTTP status line */ |
78 | typedef struct { | 64 | typedef struct { |
79 | int http_major; /* major version of the protocol, always 1 (HTTP/0.9 | 65 | int http_major; /* major version of the protocol, always 1 (HTTP/0.9 |
80 | * never reached the big internet most likely) */ | 66 | * never reached the big internet most likely) */ |
81 | int http_minor; /* minor version of the protocol, usually 0 or 1 */ | 67 | int http_minor; /* minor version of the protocol, usually 0 or 1 */ |
82 | int http_code; /* HTTP return code as in RFC 2145 */ | 68 | int http_code; /* HTTP return code as in RFC 2145 */ |
83 | int http_subcode; /* Microsoft IIS extension, HTTP subcodes, see | 69 | int http_subcode; /* Microsoft IIS extension, HTTP subcodes, see |
84 | * http://support.microsoft.com/kb/318380/en-us */ | 70 | * http://support.microsoft.com/kb/318380/en-us */ |
85 | char *msg; /* the human readable message */ | 71 | char *msg; /* the human readable message */ |
86 | char *first_line; /* a copy of the first line */ | 72 | char *first_line; /* a copy of the first line */ |
87 | } curlhelp_statusline; | 73 | } curlhelp_statusline; |
88 | 74 | ||
89 | char *server_address; | 75 | char *server_address; |
@@ -137,587 +123,587 @@ void test_file (char *); | |||
137 | int | 123 | int |
138 | main (int argc, char **argv) | 124 | main (int argc, char **argv) |
139 | { | 125 | { |
140 | int result = STATE_OK; | 126 | int result = STATE_OK; |
141 | 127 | ||
142 | setlocale (LC_ALL, ""); | 128 | setlocale (LC_ALL, ""); |
143 | bindtextdomain (PACKAGE, LOCALEDIR); | 129 | bindtextdomain (PACKAGE, LOCALEDIR); |
144 | textdomain (PACKAGE); | 130 | textdomain (PACKAGE); |
145 | 131 | ||
146 | /* Parse extra opts if any */ | 132 | /* Parse extra opts if any */ |
147 | argv = np_extra_opts (&argc, argv, progname); | 133 | argv = np_extra_opts (&argc, argv, progname); |
148 | 134 | ||
149 | /* set defaults */ | 135 | /* set defaults */ |
150 | snprintf( user_agent, DEFAULT_BUFFER_SIZE, "%s/v%s (monitoring-plugins %s)", | 136 | snprintf( user_agent, DEFAULT_BUFFER_SIZE, "%s/v%s (monitoring-plugins %s)", |
151 | progname, NP_VERSION, VERSION); | 137 | progname, NP_VERSION, VERSION); |
152 | 138 | ||
153 | /* parse arguments */ | 139 | /* parse arguments */ |
154 | if (process_arguments (argc, argv) == ERROR) | 140 | if (process_arguments (argc, argv) == ERROR) |
155 | usage4 (_("Could not parse arguments")); | 141 | usage4 (_("Could not parse arguments")); |
156 | 142 | ||
157 | /* initialize curl */ | 143 | /* initialize curl */ |
158 | if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK) | 144 | if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK) |
159 | die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); | 145 | die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); |
160 | 146 | ||
161 | if ((curl = curl_easy_init()) == NULL) | 147 | if ((curl = curl_easy_init()) == NULL) |
162 | die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n"); | 148 | die (STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n"); |
163 | 149 | ||
164 | if (verbose >= 3) | 150 | if (verbose >= 3) |
165 | curl_easy_setopt (curl, CURLOPT_VERBOSE, TRUE); | 151 | curl_easy_setopt (curl, CURLOPT_VERBOSE, TRUE); |
166 | 152 | ||
167 | /* initialize buffer for body of the answer */ | 153 | /* initialize buffer for body of the answer */ |
168 | if (curlhelp_initbuffer(&body_buf) < 0) | 154 | if (curlhelp_initbuffer(&body_buf) < 0) |
169 | die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); | 155 | die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); |
170 | curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curlhelp_buffer_callback); | 156 | curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curlhelp_buffer_callback); |
171 | curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf); | 157 | curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *)&body_buf); |
172 | 158 | ||
173 | /* initialize buffer for header of the answer */ | 159 | /* initialize buffer for header of the answer */ |
174 | if (curlhelp_initbuffer( &header_buf ) < 0) | 160 | if (curlhelp_initbuffer( &header_buf ) < 0) |
175 | die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" ); | 161 | die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n" ); |
176 | curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, curlhelp_buffer_callback); | 162 | curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, curlhelp_buffer_callback); |
177 | curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf); | 163 | curl_easy_setopt (curl, CURLOPT_WRITEHEADER, (void *)&header_buf); |
178 | 164 | ||
179 | /* set the error buffer */ | 165 | /* set the error buffer */ |
180 | curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, errbuf); | 166 | curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, errbuf); |
181 | 167 | ||
182 | /* set timeouts */ | 168 | /* set timeouts */ |
183 | curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, socket_timeout); | 169 | curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, socket_timeout); |
184 | curl_easy_setopt (curl, CURLOPT_TIMEOUT, socket_timeout); | 170 | curl_easy_setopt (curl, CURLOPT_TIMEOUT, socket_timeout); |
185 | 171 | ||
186 | /* compose URL */ | 172 | /* compose URL */ |
187 | snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s%s", use_ssl ? "https" : "http", | 173 | snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s%s", use_ssl ? "https" : "http", |
188 | server_address, server_url); | 174 | server_address, server_url); |
189 | curl_easy_setopt (curl, CURLOPT_URL, url); | 175 | curl_easy_setopt (curl, CURLOPT_URL, url); |
190 | 176 | ||
191 | /* set port */ | 177 | /* set port */ |
192 | curl_easy_setopt (curl, CURLOPT_PORT, server_port); | 178 | curl_easy_setopt (curl, CURLOPT_PORT, server_port); |
193 | 179 | ||
194 | /* compose HTTP headers */ | 180 | /* compose HTTP headers */ |
195 | snprintf (http_header, DEFAULT_BUFFER_SIZE, "Host: %s", host_name); | 181 | snprintf (http_header, DEFAULT_BUFFER_SIZE, "Host: %s", host_name); |
196 | header_list = curl_slist_append (header_list, http_header); | 182 | header_list = curl_slist_append (header_list, http_header); |
197 | curl_easy_setopt( curl, CURLOPT_HTTPHEADER, header_list ); | 183 | curl_easy_setopt( curl, CURLOPT_HTTPHEADER, header_list ); |
198 | 184 | ||
199 | /* set SSL version, warn about unsecure or unsupported versions */ | 185 | /* set SSL version, warn about unsecure or unsupported versions */ |
200 | if (use_ssl) { | 186 | if (use_ssl) { |
201 | curl_easy_setopt (curl, CURLOPT_SSLVERSION, ssl_version); | 187 | curl_easy_setopt (curl, CURLOPT_SSLVERSION, ssl_version); |
202 | } | 188 | } |
203 | 189 | ||
204 | /* client certificate and key to present to server (SSL) */ | 190 | /* client certificate and key to present to server (SSL) */ |
205 | if (client_cert) | 191 | if (client_cert) |
206 | curl_easy_setopt (curl, CURLOPT_SSLCERT, client_cert); | 192 | curl_easy_setopt (curl, CURLOPT_SSLCERT, client_cert); |
207 | if (client_privkey) | 193 | if (client_privkey) |
208 | curl_easy_setopt (curl, CURLOPT_SSLKEY, client_privkey); | 194 | curl_easy_setopt (curl, CURLOPT_SSLKEY, client_privkey); |
209 | 195 | ||
210 | /* per default if we have a CA verify both the peer and the | 196 | /* per default if we have a CA verify both the peer and the |
211 | * hostname in the certificate, can be switched off later */ | 197 | * hostname in the certificate, can be switched off later */ |
212 | curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 2); | 198 | curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 2); |
213 | curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2); | 199 | curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2); |
214 | 200 | ||
215 | /* backward-compatible behaviour, be tolerant in checks */ | 201 | /* backward-compatible behaviour, be tolerant in checks */ |
216 | if (!check_cert) { | 202 | if (!check_cert) { |
217 | //TODO: depending on more options have aspects we want | 203 | //TODO: depending on more options have aspects we want |
218 | //to be tolerant about | 204 | //to be tolerant about |
219 | //curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1 ); | 205 | //curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1 ); |
220 | curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0); | 206 | curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0); |
221 | curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0); | 207 | curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0); |
222 | } | 208 | } |
223 | 209 | ||
224 | /* set default or user-given user agent identification */ | 210 | /* set default or user-given user agent identification */ |
225 | curl_easy_setopt (curl, CURLOPT_USERAGENT, user_agent); | 211 | curl_easy_setopt (curl, CURLOPT_USERAGENT, user_agent); |
226 | 212 | ||
227 | /* authentication */ | 213 | /* authentication */ |
228 | if (strcmp(user_auth, "")) | 214 | if (strcmp(user_auth, "")) |
229 | curl_easy_setopt (curl, CURLOPT_USERPWD, user_auth); | 215 | curl_easy_setopt (curl, CURLOPT_USERPWD, user_auth); |
230 | 216 | ||
231 | /* TODO: parameter auth method, bitfield of following methods: | 217 | /* TODO: parameter auth method, bitfield of following methods: |
232 | * CURLAUTH_BASIC (default) | 218 | * CURLAUTH_BASIC (default) |
233 | * CURLAUTH_DIGEST | 219 | * CURLAUTH_DIGEST |
234 | * CURLAUTH_DIGEST_IE | 220 | * CURLAUTH_DIGEST_IE |
235 | * CURLAUTH_NEGOTIATE | 221 | * CURLAUTH_NEGOTIATE |
236 | * CURLAUTH_NTLM | 222 | * CURLAUTH_NTLM |
237 | * CURLAUTH_NTLM_WB | 223 | * CURLAUTH_NTLM_WB |
238 | * | 224 | * |
239 | * convenience tokens for typical sets of methods: | 225 | * convenience tokens for typical sets of methods: |
240 | * CURLAUTH_ANYSAFE: most secure, without BASIC | 226 | * CURLAUTH_ANYSAFE: most secure, without BASIC |
241 | * or CURLAUTH_ANY: most secure, even BASIC if necessary | 227 | * or CURLAUTH_ANY: most secure, even BASIC if necessary |
242 | * | 228 | * |
243 | * curl_easy_setopt( curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST ); | 229 | * curl_easy_setopt( curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST ); |
244 | */ | 230 | */ |
245 | 231 | ||
246 | /* TODO: --cacert: CA certificate file to verify SSL connection against (SSL) */ | 232 | /* TODO: --cacert: CA certificate file to verify SSL connection against (SSL) */ |
247 | //~ if( args_info.cacert_given ) { | 233 | //~ if( args_info.cacert_given ) { |
248 | //~ curl_easy_setopt( curl, CURLOPT_CAINFO, args_info.cacert_arg ); | 234 | //~ curl_easy_setopt( curl, CURLOPT_CAINFO, args_info.cacert_arg ); |
249 | //~ } | 235 | //~ } |
250 | 236 | ||
251 | /* handle redirections */ | 237 | /* handle redirections */ |
252 | if (onredirect == STATE_DEPENDENT) { | 238 | if (onredirect == STATE_DEPENDENT) { |
253 | curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); | 239 | curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); |
254 | /* TODO: handle the following aspects of redirection | 240 | /* TODO: handle the following aspects of redirection |
255 | CURLOPT_POSTREDIR: method switch | 241 | CURLOPT_POSTREDIR: method switch |
256 | CURLINFO_REDIRECT_URL: custom redirect option | 242 | CURLINFO_REDIRECT_URL: custom redirect option |
257 | CURLOPT_REDIRECT_PROTOCOLS | 243 | CURLOPT_REDIRECT_PROTOCOLS |
258 | CURLINFO_REDIRECT_COUNT | 244 | CURLINFO_REDIRECT_COUNT |
259 | */ | 245 | */ |
260 | } | 246 | } |
261 | 247 | ||
262 | /* do the request */ | 248 | /* do the request */ |
263 | res = curl_easy_perform(curl); | 249 | res = curl_easy_perform(curl); |
264 | 250 | ||
265 | /* free header list, we don't need it anymore */ | 251 | /* free header list, we don't need it anymore */ |
266 | curl_slist_free_all (header_list); | 252 | curl_slist_free_all (header_list); |
267 | 253 | ||
268 | /* Curl errors, result in critical Nagios state */ | 254 | /* Curl errors, result in critical Nagios state */ |
269 | if (res != CURLE_OK) { | 255 | if (res != CURLE_OK) { |
270 | remove_newlines (errbuf); | 256 | remove_newlines (errbuf); |
271 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s\n"), | 257 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s\n"), |
272 | server_port, res, curl_easy_strerror(res)); | 258 | server_port, res, curl_easy_strerror(res)); |
273 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 259 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); |
274 | } | 260 | } |
275 | 261 | ||
276 | /* we got the data and we executed the request in a given time, so we can append | 262 | /* we got the data and we executed the request in a given time, so we can append |
277 | * performance data to the answer always | 263 | * performance data to the answer always |
278 | */ | 264 | */ |
279 | curl_easy_getinfo (curl, CURLINFO_TOTAL_TIME, &total_time); | 265 | curl_easy_getinfo (curl, CURLINFO_TOTAL_TIME, &total_time); |
280 | snprintf (perfstring, DEFAULT_BUFFER_SIZE, "time=%.6gs;%.6g;%.6g;%.6g size=%dB;;;0", | 266 | snprintf (perfstring, DEFAULT_BUFFER_SIZE, "time=%.6gs;%.6g;%.6g;%.6g size=%dB;;;0", |
281 | total_time, | 267 | total_time, |
282 | 0.0, 0.0, | 268 | 0.0, 0.0, |
283 | //~ args_info.warning_given ? args_info.warning_arg : 0.0, | 269 | //~ args_info.warning_given ? args_info.warning_arg : 0.0, |
284 | //~ args_info.critical_given ? args_info.critical_arg : 0.0, | 270 | //~ args_info.critical_given ? args_info.critical_arg : 0.0, |
285 | 0.0, | 271 | 0.0, |
286 | (int)body_buf.buflen); | 272 | (int)body_buf.buflen); |
287 | 273 | ||
288 | /* return a CRITICAL status if we couldn't read any data */ | 274 | /* return a CRITICAL status if we couldn't read any data */ |
289 | if (strlen(header_buf.buf) == 0 && strlen(body_buf.buf) == 0) | 275 | if (strlen(header_buf.buf) == 0 && strlen(body_buf.buf) == 0) |
290 | die (STATE_CRITICAL, _("HTTP CRITICAL - No header received from host\n")); | 276 | die (STATE_CRITICAL, _("HTTP CRITICAL - No header received from host\n")); |
291 | 277 | ||
292 | /* get status line of answer, check sanity of HTTP code */ | 278 | /* get status line of answer, check sanity of HTTP code */ |
293 | if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) { | 279 | if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) { |
294 | snprintf (msg, DEFAULT_BUFFER_SIZE, "Unparseable status line in %.3g seconds response time|%s\n", | 280 | snprintf (msg, DEFAULT_BUFFER_SIZE, "Unparseable status line in %.3g seconds response time|%s\n", |
295 | code, total_time, perfstring); | 281 | code, total_time, perfstring); |
296 | die (STATE_CRITICAL, "HTTP CRITICAL HTTP/1.x %d unknown - %s", code, msg); | 282 | die (STATE_CRITICAL, "HTTP CRITICAL HTTP/1.x %d unknown - %s", code, msg); |
297 | } | 283 | } |
298 | 284 | ||
299 | /* get result code from cURL */ | 285 | /* get result code from cURL */ |
300 | curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code); | 286 | curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &code); |
301 | if (verbose>=2) | 287 | if (verbose>=2) |
302 | printf ("* curl CURLINFO_RESPONSE_CODE is %d\n", code); | 288 | printf ("* curl CURLINFO_RESPONSE_CODE is %d\n", code); |
303 | 289 | ||
304 | /* print status line, header, body if verbose */ | 290 | /* print status line, header, body if verbose */ |
305 | if (verbose >= 2) { | 291 | if (verbose >= 2) { |
306 | puts ("--- HEADER ---"); | 292 | puts ("--- HEADER ---"); |
307 | puts (header_buf.buf); | 293 | puts (header_buf.buf); |
308 | puts ("--- BODY ---"); | 294 | puts ("--- BODY ---"); |
309 | puts (body_buf.buf); | 295 | puts (body_buf.buf); |
310 | } | 296 | } |
311 | 297 | ||
312 | /* illegal return codes result in a critical state */ | 298 | /* illegal return codes result in a critical state */ |
313 | if (code >= 600 || code < 100) { | 299 | if (code >= 600 || code < 100) { |
314 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg); | 300 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg); |
315 | /* server errors result in a critical state */ | 301 | /* server errors result in a critical state */ |
316 | } else if (code >= 500) { | 302 | } else if (code >= 500) { |
317 | result = STATE_CRITICAL; | 303 | result = STATE_CRITICAL; |
318 | /* client errors result in a warning state */ | 304 | /* client errors result in a warning state */ |
319 | } else if (code >= 400) { | 305 | } else if (code >= 400) { |
320 | result = STATE_WARNING; | 306 | result = STATE_WARNING; |
321 | /* check redirected page if specified */ | 307 | /* check redirected page if specified */ |
322 | } else if (code >= 300) { | 308 | } else if (code >= 300) { |
323 | if (onredirect == STATE_DEPENDENT) { | 309 | if (onredirect == STATE_DEPENDENT) { |
324 | code = status_line.http_code; | 310 | code = status_line.http_code; |
325 | } | 311 | } |
326 | result = max_state_alt (onredirect, result); | 312 | result = max_state_alt (onredirect, result); |
327 | /* TODO: make sure the last status line has been | 313 | /* TODO: make sure the last status line has been |
328 | parsed into the status_line structure | 314 | parsed into the status_line structure |
329 | */ | 315 | */ |
330 | /* all other codes are considered ok */ | 316 | /* all other codes are considered ok */ |
331 | } else { | 317 | } else { |
332 | result = STATE_OK; | 318 | result = STATE_OK; |
333 | } | 319 | } |
334 | 320 | ||
335 | /* check status codes, set exit status accordingly */ | 321 | /* check status codes, set exit status accordingly */ |
336 | if( status_line.http_code != code ) { | 322 | if( status_line.http_code != code ) { |
337 | die (STATE_CRITICAL, _("HTTP CRITICAL HTTP/%d.%d %d %s - different HTTP codes (cUrl has %ld)\n"), | 323 | die (STATE_CRITICAL, _("HTTP CRITICAL HTTP/%d.%d %d %s - different HTTP codes (cUrl has %ld)\n"), |
338 | status_line.http_major, status_line.http_minor, | 324 | status_line.http_major, status_line.http_minor, |
339 | status_line.http_code, status_line.msg, code); | 325 | status_line.http_code, status_line.msg, code); |
340 | } | 326 | } |
341 | 327 | ||
342 | /* Page and Header content checks go here */ | 328 | /* Page and Header content checks go here */ |
343 | if (strlen (string_expect)) { | 329 | if (strlen (string_expect)) { |
344 | if (!strstr (body_buf.buf, string_expect)) { | 330 | if (!strstr (body_buf.buf, string_expect)) { |
345 | strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); | 331 | strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); |
346 | if(output_string_search[sizeof(output_string_search)-1]!='\0') { | 332 | if(output_string_search[sizeof(output_string_search)-1]!='\0') { |
347 | bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); | 333 | bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); |
348 | } | 334 | } |
349 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); | 335 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); |
350 | result = STATE_CRITICAL; | 336 | result = STATE_CRITICAL; |
351 | } | 337 | } |
352 | } | 338 | } |
353 | 339 | ||
354 | /* -w, -c: check warning and critical level */ | 340 | /* -w, -c: check warning and critical level */ |
355 | result = max_state_alt(get_status(total_time, thlds), result); | 341 | result = max_state_alt(get_status(total_time, thlds), result); |
356 | 342 | ||
357 | //~ die (result, "HTTP %s: %s\n", state_text(result), msg); | 343 | //~ die (result, "HTTP %s: %s\n", state_text(result), msg); |
358 | die (result, "HTTP %s HTTP/%d.%d %d %s - %s - %.3g seconds response time|%s\n", | 344 | die (result, "HTTP %s HTTP/%d.%d %d %s - %s - %.3g seconds response time|%s\n", |
359 | state_text(result), status_line.http_major, status_line.http_minor, | 345 | state_text(result), status_line.http_major, status_line.http_minor, |
360 | status_line.http_code, status_line.msg, msg, | 346 | status_line.http_code, status_line.msg, msg, |
361 | total_time, perfstring); | 347 | total_time, perfstring); |
362 | 348 | ||
363 | /* proper cleanup after die? */ | 349 | /* proper cleanup after die? */ |
364 | curlhelp_free_statusline(&status_line); | 350 | curlhelp_free_statusline(&status_line); |
365 | curl_easy_cleanup (curl); | 351 | curl_easy_cleanup (curl); |
366 | curl_global_cleanup (); | 352 | curl_global_cleanup (); |
367 | curlhelp_freebuffer(&body_buf); | 353 | curlhelp_freebuffer(&body_buf); |
368 | curlhelp_freebuffer(&header_buf); | 354 | curlhelp_freebuffer(&header_buf); |
369 | 355 | ||
370 | return result; | 356 | return result; |
371 | } | 357 | } |
372 | 358 | ||
373 | /* check whether a file exists */ | 359 | /* check whether a file exists */ |
374 | void | 360 | void |
375 | test_file (char *path) | 361 | test_file (char *path) |
376 | { | 362 | { |
377 | if (access(path, R_OK) == 0) | 363 | if (access(path, R_OK) == 0) |
378 | return; | 364 | return; |
379 | usage2 (_("file does not exist or is not readable"), path); | 365 | usage2 (_("file does not exist or is not readable"), path); |
380 | } | 366 | } |
381 | 367 | ||
382 | int | 368 | int |
383 | process_arguments (int argc, char **argv) | 369 | process_arguments (int argc, char **argv) |
384 | { | 370 | { |
385 | int c; | 371 | int c; |
386 | 372 | ||
387 | enum { | 373 | enum { |
388 | SNI_OPTION | 374 | SNI_OPTION |
389 | }; | 375 | }; |
390 | 376 | ||
391 | int option=0; | 377 | int option=0; |
392 | static struct option longopts[] = { | 378 | static struct option longopts[] = { |
393 | {"ssl", optional_argument, 0, 'S'}, | 379 | {"ssl", optional_argument, 0, 'S'}, |
394 | {"sni", no_argument, 0, SNI_OPTION}, | 380 | {"sni", no_argument, 0, SNI_OPTION}, |
395 | {"IP-address", required_argument, 0, 'I'}, | 381 | {"IP-address", required_argument, 0, 'I'}, |
396 | {"url", required_argument, 0, 'u'}, | 382 | {"url", required_argument, 0, 'u'}, |
397 | {"port", required_argument, 0, 'p'}, | 383 | {"port", required_argument, 0, 'p'}, |
398 | {"authorization", required_argument, 0, 'a'}, | 384 | {"authorization", required_argument, 0, 'a'}, |
399 | {"string", required_argument, 0, 's'}, | 385 | {"string", required_argument, 0, 's'}, |
400 | {"onredirect", required_argument, 0, 'f'}, | 386 | {"onredirect", required_argument, 0, 'f'}, |
401 | {"client-cert", required_argument, 0, 'J'}, | 387 | {"client-cert", required_argument, 0, 'J'}, |
402 | {"private-key", required_argument, 0, 'K'}, | 388 | {"private-key", required_argument, 0, 'K'}, |
403 | {"useragent", required_argument, 0, 'A'}, | 389 | {"useragent", required_argument, 0, 'A'}, |
404 | {"certificate", required_argument, 0, 'C'}, | 390 | {"certificate", required_argument, 0, 'C'}, |
405 | {0, 0, 0, 0} | 391 | {0, 0, 0, 0} |
406 | }; | 392 | }; |
407 | 393 | ||
408 | if (argc < 2) | 394 | if (argc < 2) |
409 | usage ("\n"); | 395 | usage ("\n"); |
410 | 396 | ||
411 | while (1) { | 397 | while (1) { |
412 | c = getopt_long (argc, argv, "Vvht:c:w:A:H:I:a:p:s:u:f:C:J:K:S::", longopts, &option); | 398 | c = getopt_long (argc, argv, "Vvht:c:w:A:H:I:a:p:s:u:f:C:J:K:S::", longopts, &option); |
413 | if (c == -1 || c == EOF || c == 1) | 399 | if (c == -1 || c == EOF || c == 1) |
414 | break; | 400 | break; |
415 | 401 | ||
416 | switch (c) { | 402 | switch (c) { |
417 | case 'h': | 403 | case 'h': |
418 | print_help(); | 404 | print_help(); |
419 | exit(STATE_UNKNOWN); | 405 | exit(STATE_UNKNOWN); |
420 | break; | 406 | break; |
421 | case 'V': | 407 | case 'V': |
422 | print_revision(progname, NP_VERSION); | 408 | print_revision(progname, NP_VERSION); |
423 | print_curl_version(); | 409 | print_curl_version(); |
424 | exit(STATE_UNKNOWN); | 410 | exit(STATE_UNKNOWN); |
425 | break; | 411 | break; |
426 | case 'v': | 412 | case 'v': |
427 | verbose++; | 413 | verbose++; |
428 | break; | 414 | break; |
429 | case 't': /* timeout period */ | 415 | case 't': /* timeout period */ |
430 | if (!is_intnonneg (optarg)) | 416 | if (!is_intnonneg (optarg)) |
431 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 417 | usage2 (_("Timeout interval must be a positive integer"), optarg); |
432 | else | 418 | else |
433 | socket_timeout = (int)strtol (optarg, NULL, 10); | 419 | socket_timeout = (int)strtol (optarg, NULL, 10); |
434 | break; | 420 | break; |
435 | case 'c': /* critical time threshold */ | 421 | case 'c': /* critical time threshold */ |
436 | critical_thresholds = optarg; | 422 | critical_thresholds = optarg; |
437 | break; | 423 | break; |
438 | case 'w': /* warning time threshold */ | 424 | case 'w': /* warning time threshold */ |
439 | warning_thresholds = optarg; | 425 | warning_thresholds = optarg; |
440 | break; | 426 | break; |
441 | case 'H': /* virtual host */ | 427 | case 'H': /* virtual host */ |
442 | host_name = strdup (optarg); | 428 | host_name = strdup (optarg); |
443 | break; | 429 | break; |
444 | case 'I': /* internet address */ | 430 | case 'I': /* internet address */ |
445 | server_address = strdup (optarg); | 431 | server_address = strdup (optarg); |
446 | break; | 432 | break; |
447 | case 'u': /* URL path */ | 433 | case 'u': /* URL path */ |
448 | server_url = strdup (optarg); | 434 | server_url = strdup (optarg); |
449 | break; | 435 | break; |
450 | case 'p': /* Server port */ | 436 | case 'p': /* Server port */ |
451 | if (!is_intnonneg (optarg)) | 437 | if (!is_intnonneg (optarg)) |
452 | usage2 (_("Invalid port number, expecting a non-negative number"), optarg); | 438 | usage2 (_("Invalid port number, expecting a non-negative number"), optarg); |
453 | else { | 439 | else { |
454 | if( strtol(optarg, NULL, 10) > MAX_PORT) | 440 | if( strtol(optarg, NULL, 10) > MAX_PORT) |
455 | usage2 (_("Invalid port number, supplied port number is too big"), optarg); | 441 | usage2 (_("Invalid port number, supplied port number is too big"), optarg); |
456 | server_port = (unsigned short)strtol(optarg, NULL, 10); | 442 | server_port = (unsigned short)strtol(optarg, NULL, 10); |
457 | } | 443 | } |
458 | break; | 444 | break; |
459 | case 'a': /* authorization info */ | 445 | case 'a': /* authorization info */ |
460 | strncpy (user_auth, optarg, MAX_INPUT_BUFFER - 1); | 446 | strncpy (user_auth, optarg, MAX_INPUT_BUFFER - 1); |
461 | user_auth[MAX_INPUT_BUFFER - 1] = 0; | 447 | user_auth[MAX_INPUT_BUFFER - 1] = 0; |
462 | break; | 448 | break; |
463 | case 'A': /* useragent */ | 449 | case 'A': /* useragent */ |
464 | snprintf (user_agent, DEFAULT_BUFFER_SIZE, optarg); | 450 | snprintf (user_agent, DEFAULT_BUFFER_SIZE, optarg); |
465 | break; | 451 | break; |
466 | case 'C': /* Check SSL cert validity */ | 452 | case 'C': /* Check SSL cert validity */ |
467 | #ifdef LIBCURL_FEATURE_SSL | 453 | #ifdef LIBCURL_FEATURE_SSL |
468 | /* TODO: C:, check age of certificate for backward compatible | 454 | /* TODO: C:, check age of certificate for backward compatible |
469 | * behaviour, but we would later add more check conditions */ | 455 | * behaviour, but we would later add more check conditions */ |
470 | check_cert = TRUE; | 456 | check_cert = TRUE; |
471 | goto enable_ssl; | 457 | goto enable_ssl; |
472 | #endif | 458 | #endif |
473 | case 'J': /* use client certificate */ | 459 | case 'J': /* use client certificate */ |
474 | #ifdef LIBCURL_FEATURE_SSL | 460 | #ifdef LIBCURL_FEATURE_SSL |
475 | test_file(optarg); | 461 | test_file(optarg); |
476 | client_cert = optarg; | 462 | client_cert = optarg; |
477 | goto enable_ssl; | 463 | goto enable_ssl; |
478 | #endif | 464 | #endif |
479 | case 'K': /* use client private key */ | 465 | case 'K': /* use client private key */ |
480 | #ifdef LIBCURL_FEATURE_SSL | 466 | #ifdef LIBCURL_FEATURE_SSL |
481 | test_file(optarg); | 467 | test_file(optarg); |
482 | client_privkey = optarg; | 468 | client_privkey = optarg; |
483 | goto enable_ssl; | 469 | goto enable_ssl; |
484 | #endif | 470 | #endif |
485 | case 'S': /* use SSL */ | 471 | case 'S': /* use SSL */ |
486 | #ifdef LIBCURL_FEATURE_SSL | 472 | #ifdef LIBCURL_FEATURE_SSL |
487 | enable_ssl: | 473 | enable_ssl: |
488 | use_ssl = TRUE; | 474 | use_ssl = TRUE; |
489 | /* ssl_version initialized to CURL_SSLVERSION_TLSv1_0 as a default. Only set if it's non-zero. This helps when we include multiple | 475 | /* ssl_version initialized to CURL_SSLVERSION_TLSv1_0 as a default. Only set if it's non-zero. This helps when we include multiple |
490 | parameters, like -S and -C combinations */ | 476 | parameters, like -S and -C combinations */ |
491 | ssl_version = CURL_SSLVERSION_TLSv1_0; | 477 | ssl_version = CURL_SSLVERSION_TLSv1_0; |
492 | if (c=='S' && optarg != NULL) { | 478 | if (c=='S' && optarg != NULL) { |
493 | int got_plus = strchr(optarg, '+') != NULL; | 479 | int got_plus = strchr(optarg, '+') != NULL; |
494 | 480 | ||
495 | if (!strncmp (optarg, "1.2", 3)) | 481 | if (!strncmp (optarg, "1.2", 3)) |
496 | ssl_version = CURL_SSLVERSION_TLSv1_2; | 482 | ssl_version = CURL_SSLVERSION_TLSv1_2; |
497 | else if (!strncmp (optarg, "1.1", 3)) | 483 | else if (!strncmp (optarg, "1.1", 3)) |
498 | ssl_version = CURL_SSLVERSION_TLSv1_1; | 484 | ssl_version = CURL_SSLVERSION_TLSv1_1; |
499 | else if (optarg[0] == '1') | 485 | else if (optarg[0] == '1') |
500 | ssl_version = CURL_SSLVERSION_TLSv1_0; | 486 | ssl_version = CURL_SSLVERSION_TLSv1_0; |
501 | else if (optarg[0] == '3') | 487 | else if (optarg[0] == '3') |
502 | ssl_version = CURL_SSLVERSION_SSLv3; | 488 | ssl_version = CURL_SSLVERSION_SSLv3; |
503 | else if (optarg[0] == '2') | 489 | else if (optarg[0] == '2') |
504 | ssl_version = CURL_SSLVERSION_SSLv2; | 490 | ssl_version = CURL_SSLVERSION_SSLv2; |
505 | else | 491 | else |
506 | usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); | 492 | usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); |
507 | } | 493 | } |
508 | if (server_port == DEFAULT_HTTP_PORT) | 494 | if (server_port == DEFAULT_HTTP_PORT) |
509 | server_port = DEFAULT_HTTPS_PORT; | 495 | server_port = DEFAULT_HTTPS_PORT; |
510 | #else | 496 | #else |
511 | /* -C -J and -K fall through to here without SSL */ | 497 | /* -C -J and -K fall through to here without SSL */ |
512 | usage4 (_("Invalid option - SSL is not available")); | 498 | usage4 (_("Invalid option - SSL is not available")); |
513 | #endif | 499 | #endif |
514 | break; | 500 | break; |
515 | case SNI_OPTION: /* --sni is parsed, but ignored, the default is TRUE with libcurl */ | 501 | case SNI_OPTION: /* --sni is parsed, but ignored, the default is TRUE with libcurl */ |
516 | use_sni = TRUE; | 502 | use_sni = TRUE; |
517 | break; | 503 | break; |
518 | case 'f': /* onredirect */ | 504 | case 'f': /* onredirect */ |
519 | if (!strcmp (optarg, "ok")) | 505 | if (!strcmp (optarg, "ok")) |
520 | onredirect = STATE_OK; | 506 | onredirect = STATE_OK; |
521 | else if (!strcmp (optarg, "warning")) | 507 | else if (!strcmp (optarg, "warning")) |
522 | onredirect = STATE_WARNING; | 508 | onredirect = STATE_WARNING; |
523 | else if (!strcmp (optarg, "critical")) | 509 | else if (!strcmp (optarg, "critical")) |
524 | onredirect = STATE_CRITICAL; | 510 | onredirect = STATE_CRITICAL; |
525 | else if (!strcmp (optarg, "unknown")) | 511 | else if (!strcmp (optarg, "unknown")) |
526 | onredirect = STATE_UNKNOWN; | 512 | onredirect = STATE_UNKNOWN; |
527 | else if (!strcmp (optarg, "follow")) | 513 | else if (!strcmp (optarg, "follow")) |
528 | onredirect = STATE_DEPENDENT; | 514 | onredirect = STATE_DEPENDENT; |
529 | else usage2 (_("Invalid onredirect option"), optarg); | 515 | else usage2 (_("Invalid onredirect option"), optarg); |
530 | //~ if (!strcmp (optarg, "stickyport")) | 516 | //~ if (!strcmp (optarg, "stickyport")) |
531 | //~ onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT; | 517 | //~ onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT; |
532 | //~ else if (!strcmp (optarg, "sticky")) | 518 | //~ else if (!strcmp (optarg, "sticky")) |
533 | //~ onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST; | 519 | //~ onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST; |
534 | //~ else if (!strcmp (optarg, "follow")) | 520 | //~ else if (!strcmp (optarg, "follow")) |
535 | //~ onredirect = STATE_DEPENDENT, followsticky = STICKY_NONE; | 521 | //~ onredirect = STATE_DEPENDENT, followsticky = STICKY_NONE; |
536 | if (verbose >= 2) | 522 | if (verbose >= 2) |
537 | printf(_("* Following redirects set to %s\n"), state_text(onredirect)); | 523 | printf(_("* Following redirects set to %s\n"), state_text(onredirect)); |
538 | break; | 524 | break; |
539 | case 's': /* string or substring */ | 525 | case 's': /* string or substring */ |
540 | strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); | 526 | strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); |
541 | string_expect[MAX_INPUT_BUFFER - 1] = 0; | 527 | string_expect[MAX_INPUT_BUFFER - 1] = 0; |
542 | break; | 528 | break; |
543 | case '?': | 529 | case '?': |
544 | /* print short usage statement if args not parsable */ | 530 | /* print short usage statement if args not parsable */ |
545 | usage5 (); | 531 | usage5 (); |
546 | break; | 532 | break; |
547 | } | 533 | } |
548 | } | 534 | } |
549 | 535 | ||
550 | c = optind; | 536 | c = optind; |
551 | 537 | ||
552 | if (server_address == NULL && c < argc) | 538 | if (server_address == NULL && c < argc) |
553 | server_address = strdup (argv[c++]); | 539 | server_address = strdup (argv[c++]); |
554 | 540 | ||
555 | if (host_name == NULL && c < argc) | 541 | if (host_name == NULL && c < argc) |
556 | host_name = strdup (argv[c++]); | 542 | host_name = strdup (argv[c++]); |
557 | 543 | ||
558 | if (server_address == NULL) { | 544 | if (server_address == NULL) { |
559 | if (host_name == NULL) | 545 | if (host_name == NULL) |
560 | usage4 (_("You must specify a server address or host name")); | 546 | usage4 (_("You must specify a server address or host name")); |
561 | else | 547 | else |
562 | server_address = strdup (host_name); | 548 | server_address = strdup (host_name); |
563 | } | 549 | } |
564 | 550 | ||
565 | set_thresholds(&thlds, warning_thresholds, critical_thresholds); | 551 | set_thresholds(&thlds, warning_thresholds, critical_thresholds); |
566 | 552 | ||
567 | if (critical_thresholds && thlds->critical->end>(double)socket_timeout) | 553 | if (critical_thresholds && thlds->critical->end>(double)socket_timeout) |
568 | socket_timeout = (int)thlds->critical->end + 1; | 554 | socket_timeout = (int)thlds->critical->end + 1; |
569 | if (verbose >= 2) | 555 | if (verbose >= 2) |
570 | printf ("* Socket timeout set to %d seconds\n", socket_timeout); | 556 | printf ("* Socket timeout set to %d seconds\n", socket_timeout); |
571 | 557 | ||
572 | //~ if (http_method == NULL) | 558 | //~ if (http_method == NULL) |
573 | //~ http_method = strdup ("GET"); | 559 | //~ http_method = strdup ("GET"); |
574 | 560 | ||
575 | if (client_cert && !client_privkey) | 561 | if (client_cert && !client_privkey) |
576 | usage4 (_("If you use a client certificate you must also specify a private key file")); | 562 | usage4 (_("If you use a client certificate you must also specify a private key file")); |
577 | 563 | ||
578 | //~ if (virtual_port == 0) | 564 | //~ if (virtual_port == 0) |
579 | //~ virtual_port = server_port; | 565 | //~ virtual_port = server_port; |
580 | 566 | ||
581 | return TRUE; | 567 | return TRUE; |
582 | } | 568 | } |
583 | 569 | ||
584 | void | 570 | void |
585 | print_help (void) | 571 | print_help (void) |
586 | { | 572 | { |
587 | print_revision(progname, NP_VERSION); | 573 | print_revision(progname, NP_VERSION); |
574 | |||
575 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | ||
576 | printf ("Copyright (c) 2017 Andreas Baumann <abaumann@yahoo.com>\n"); | ||
577 | printf (COPYRIGHT, copyright, email); | ||
588 | 578 | ||
589 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 579 | printf ("%s\n", _("This plugin tests the HTTP service on the specified host. It can test")); |
590 | printf ("Copyright (c) 2017 Andreas Baumann <abaumann@yahoo.com>\n"); | 580 | printf ("%s\n", _("normal (http) and secure (https) servers, follow redirects, search for")); |
591 | printf (COPYRIGHT, copyright, email); | 581 | printf ("%s\n", _("strings and regular expressions, check connection times, and report on")); |
582 | printf ("%s\n", _("certificate expiration times.")); | ||
583 | printf ("\n"); | ||
584 | printf ("%s\n", _("It makes use of libcurl to do so. It tries to be as compatible to check_http")); | ||
585 | printf ("%s\n", _("as possible.")); | ||
592 | 586 | ||
593 | printf ("%s\n", _("This plugin tests the HTTP service on the specified host. It can test")); | 587 | printf ("\n\n"); |
594 | printf ("%s\n", _("normal (http) and secure (https) servers, follow redirects, search for")); | ||
595 | printf ("%s\n", _("strings and regular expressions, check connection times, and report on")); | ||
596 | printf ("%s\n", _("certificate expiration times.")); | ||
597 | printf ("\n"); | ||
598 | printf ("%s\n", _("It makes use of libcurl to do so. It tries to be as compatible to check_http")); | ||
599 | printf ("%s\n", _("as possible.")); | ||
600 | 588 | ||
601 | printf ("\n\n"); | 589 | print_usage(); |
602 | 590 | ||
603 | print_usage(); | 591 | printf (_("NOTE: One or both of -H and -I must be specified")); |
604 | |||
605 | printf (_("NOTE: One or both of -H and -I must be specified")); | ||
606 | 592 | ||
607 | printf ("\n"); | 593 | printf ("\n"); |
608 | 594 | ||
609 | printf (UT_HELP_VRSN); | 595 | printf (UT_HELP_VRSN); |
610 | printf (UT_EXTRA_OPTS); | 596 | printf (UT_EXTRA_OPTS); |
611 | 597 | ||
612 | printf (" %s\n", "-H, --hostname=ADDRESS"); | 598 | printf (" %s\n", "-H, --hostname=ADDRESS"); |
613 | printf (" %s\n", _("Host name argument for servers using host headers (virtual host)")); | 599 | printf (" %s\n", _("Host name argument for servers using host headers (virtual host)")); |
614 | printf (" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); | 600 | printf (" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); |
615 | printf (" %s\n", "-I, --IP-address=ADDRESS"); | 601 | printf (" %s\n", "-I, --IP-address=ADDRESS"); |
616 | printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); | 602 | printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); |
617 | printf (" %s\n", "-p, --port=INTEGER"); | 603 | printf (" %s\n", "-p, --port=INTEGER"); |
618 | printf (" %s", _("Port number (default: ")); | 604 | printf (" %s", _("Port number (default: ")); |
619 | printf ("%d)\n", DEFAULT_HTTP_PORT); | 605 | printf ("%d)\n", DEFAULT_HTTP_PORT); |
620 | 606 | ||
621 | #ifdef LIBCURL_FEATURE_SSL | 607 | #ifdef LIBCURL_FEATURE_SSL |
622 | printf (" %s\n", "-S, --ssl=VERSION[+]"); | 608 | printf (" %s\n", "-S, --ssl=VERSION[+]"); |
623 | printf (" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); | 609 | printf (" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); |
624 | printf (" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); | 610 | printf (" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); |
625 | printf (" %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted.")); | 611 | printf (" %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted.")); |
626 | printf (" %s\n", _("Note: SSLv2 and SSLv3 are deprecated and are usually disabled in libcurl")); | 612 | printf (" %s\n", _("Note: SSLv2 and SSLv3 are deprecated and are usually disabled in libcurl")); |
627 | printf (" %s\n", "--sni"); | 613 | printf (" %s\n", "--sni"); |
628 | printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); | 614 | printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); |
629 | #if LIBCURL_VERSION_NUM >= 0x071801 | 615 | #if LIBCURL_VERSION_NUM >= 0x071801 |
630 | printf (" %s\n", _("Note: --sni is the default in libcurl as SSLv2 and SSLV3 are deprecated and")); | 616 | printf (" %s\n", _("Note: --sni is the default in libcurl as SSLv2 and SSLV3 are deprecated and")); |
631 | printf (" %s\n", _(" SNI only really works since TLSv1.0")); | 617 | printf (" %s\n", _(" SNI only really works since TLSv1.0")); |
632 | #else | 618 | #else |
633 | printf (" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); | 619 | printf (" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); |
634 | #endif | 620 | #endif |
635 | printf (" %s\n", "-C, --certificate"); | 621 | printf (" %s\n", "-C, --certificate"); |
636 | printf (" %s\n", _("Check validity of certificate")); | 622 | printf (" %s\n", _("Check validity of certificate")); |
637 | printf (" %s\n", "-J, --client-cert=FILE"); | 623 | printf (" %s\n", "-J, --client-cert=FILE"); |
638 | printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); | 624 | printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); |
639 | printf (" %s\n", _("to be used in establishing the SSL session")); | 625 | printf (" %s\n", _("to be used in establishing the SSL session")); |
640 | printf (" %s\n", "-K, --private-key=FILE"); | 626 | printf (" %s\n", "-K, --private-key=FILE"); |
641 | printf (" %s\n", _("Name of file containing the private key (PEM format)")); | 627 | printf (" %s\n", _("Name of file containing the private key (PEM format)")); |
642 | printf (" %s\n", _("matching the client certificate")); | 628 | printf (" %s\n", _("matching the client certificate")); |
643 | #endif | 629 | #endif |
644 | 630 | ||
645 | printf (" %s\n", "-s, --string=STRING"); | 631 | printf (" %s\n", "-s, --string=STRING"); |
646 | printf (" %s\n", _("String to expect in the content")); | 632 | printf (" %s\n", _("String to expect in the content")); |
647 | printf (" %s\n", "-u, --url=PATH"); | 633 | printf (" %s\n", "-u, --url=PATH"); |
648 | printf (" %s\n", _("URL to GET or POST (default: /)")); | 634 | printf (" %s\n", _("URL to GET or POST (default: /)")); |
649 | 635 | ||
650 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); | 636 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); |
651 | printf (" %s\n", _("Username:password on sites with basic authentication")); | 637 | printf (" %s\n", _("Username:password on sites with basic authentication")); |
652 | printf (" %s\n", "-A, --useragent=STRING"); | 638 | printf (" %s\n", "-A, --useragent=STRING"); |
653 | printf (" %s\n", _("String to be sent in http header as \"User Agent\"")); | 639 | printf (" %s\n", _("String to be sent in http header as \"User Agent\"")); |
654 | printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); | 640 | printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); |
655 | printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); | 641 | printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); |
656 | printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); | 642 | printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); |
657 | 643 | ||
658 | printf (UT_WARN_CRIT); | 644 | printf (UT_WARN_CRIT); |
659 | 645 | ||
660 | printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 646 | printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
661 | 647 | ||
662 | printf (UT_VERBOSE); | 648 | printf (UT_VERBOSE); |
663 | 649 | ||
664 | printf (UT_SUPPORT); | 650 | printf (UT_SUPPORT); |
665 | } | 651 | } |
666 | 652 | ||
667 | void | 653 | void |
668 | print_usage (void) | 654 | print_usage (void) |
669 | { | 655 | { |
670 | printf ("%s\n", _("Usage:")); | 656 | printf ("%s\n", _("Usage:")); |
671 | printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); | 657 | printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); |
672 | printf (" [-J <client certificate file>] [-K <private key>]\n"); | 658 | printf (" [-J <client certificate file>] [-K <private key>]\n"); |
673 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-a auth]\n"); | 659 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-a auth]\n"); |
674 | printf (" [-f <ok|warning|critcal|follow>]\n"); | 660 | printf (" [-f <ok|warning|critcal|follow>]\n"); |
675 | printf (" [-A string] [-S <version>] [-C]\n"); | 661 | printf (" [-A string] [-S <version>] [-C]\n"); |
676 | printf (" [-v verbose]\n", progname); | 662 | printf (" [-v verbose]\n", progname); |
677 | printf ("\n"); | 663 | printf ("\n"); |
678 | printf ("%s\n", _("WARNING: check_curl is experimental. Please use")); | 664 | printf ("%s\n", _("WARNING: check_curl is experimental. Please use")); |
679 | printf ("%s\n\n", _("check_http if you need a stable version.")); | 665 | printf ("%s\n\n", _("check_http if you need a stable version.")); |
680 | } | 666 | } |
681 | 667 | ||
682 | void | 668 | void |
683 | print_curl_version (void) | 669 | print_curl_version (void) |
684 | { | 670 | { |
685 | printf( "%s\n", curl_version()); | 671 | printf( "%s\n", curl_version()); |
686 | } | 672 | } |
687 | 673 | ||
688 | int | 674 | int |
689 | curlhelp_initbuffer (curlhelp_curlbuf *buf) | 675 | curlhelp_initbuffer (curlhelp_curlbuf *buf) |
690 | { | 676 | { |
691 | buf->bufsize = DEFAULT_BUFFER_SIZE; | 677 | buf->bufsize = DEFAULT_BUFFER_SIZE; |
692 | buf->buflen = 0; | 678 | buf->buflen = 0; |
693 | buf->buf = (char *)malloc ((size_t)buf->bufsize); | 679 | buf->buf = (char *)malloc ((size_t)buf->bufsize); |
694 | if (buf->buf == NULL) return -1; | 680 | if (buf->buf == NULL) return -1; |
695 | return 0; | 681 | return 0; |
696 | } | 682 | } |
697 | 683 | ||
698 | int | 684 | int |
699 | curlhelp_buffer_callback (void *buffer, size_t size, size_t nmemb, void *stream) | 685 | curlhelp_buffer_callback (void *buffer, size_t size, size_t nmemb, void *stream) |
700 | { | 686 | { |
701 | curlhelp_curlbuf *buf = (curlhelp_curlbuf *)stream; | 687 | curlhelp_curlbuf *buf = (curlhelp_curlbuf *)stream; |
702 | 688 | ||
703 | while (buf->bufsize < buf->buflen + size * nmemb + 1) { | 689 | while (buf->bufsize < buf->buflen + size * nmemb + 1) { |
704 | buf->bufsize *= buf->bufsize * 2; | 690 | buf->bufsize *= buf->bufsize * 2; |
705 | buf->buf = (char *)realloc (buf->buf, buf->bufsize); | 691 | buf->buf = (char *)realloc (buf->buf, buf->bufsize); |
706 | if (buf->buf == NULL) return -1; | 692 | if (buf->buf == NULL) return -1; |
707 | } | 693 | } |
708 | 694 | ||
709 | memcpy (buf->buf + buf->buflen, buffer, size * nmemb); | 695 | memcpy (buf->buf + buf->buflen, buffer, size * nmemb); |
710 | buf->buflen += size * nmemb; | 696 | buf->buflen += size * nmemb; |
711 | buf->buf[buf->buflen] = '\0'; | 697 | buf->buf[buf->buflen] = '\0'; |
712 | 698 | ||
713 | return (int)(size * nmemb); | 699 | return (int)(size * nmemb); |
714 | } | 700 | } |
715 | 701 | ||
716 | void | 702 | void |
717 | curlhelp_freebuffer (curlhelp_curlbuf *buf) | 703 | curlhelp_freebuffer (curlhelp_curlbuf *buf) |
718 | { | 704 | { |
719 | free (buf->buf); | 705 | free (buf->buf); |
720 | buf->buf = NULL; | 706 | buf->buf = NULL; |
721 | } | 707 | } |
722 | 708 | ||
723 | /* TODO: when redirecting we get more than one HTTP header, make sure | 709 | /* TODO: when redirecting we get more than one HTTP header, make sure |
@@ -726,76 +712,76 @@ curlhelp_freebuffer (curlhelp_curlbuf *buf) | |||
726 | int | 712 | int |
727 | curlhelp_parse_statusline (char *buf, curlhelp_statusline *status_line) | 713 | curlhelp_parse_statusline (char *buf, curlhelp_statusline *status_line) |
728 | { | 714 | { |
729 | char *first_line_end; | 715 | char *first_line_end; |
730 | char *p; | 716 | char *p; |
731 | size_t first_line_len; | 717 | size_t first_line_len; |
732 | char *pp; | 718 | char *pp; |
733 | 719 | ||
734 | first_line_end = strstr(buf, "\r\n"); | 720 | first_line_end = strstr(buf, "\r\n"); |
735 | if (first_line_end == NULL) return -1; | 721 | if (first_line_end == NULL) return -1; |
736 | 722 | ||
737 | first_line_len = (size_t)(first_line_end - buf); | 723 | first_line_len = (size_t)(first_line_end - buf); |
738 | status_line->first_line = (char *)malloc (first_line_len + 1); | 724 | status_line->first_line = (char *)malloc (first_line_len + 1); |
739 | if (status_line->first_line == NULL) return -1; | 725 | if (status_line->first_line == NULL) return -1; |
740 | memcpy (status_line->first_line, buf, first_line_len); | 726 | memcpy (status_line->first_line, buf, first_line_len); |
741 | status_line->first_line[first_line_len] = '\0'; | 727 | status_line->first_line[first_line_len] = '\0'; |
742 | 728 | ||
743 | /* protocol and version: "HTTP/x.x" SP */ | 729 | /* protocol and version: "HTTP/x.x" SP */ |
744 | 730 | ||
745 | p = strtok(status_line->first_line, "/"); | 731 | p = strtok(status_line->first_line, "/"); |
746 | if( p == NULL ) { free( status_line->first_line ); return -1; } | 732 | if( p == NULL ) { free( status_line->first_line ); return -1; } |
747 | if( strcmp( p, "HTTP" ) != 0 ) { free( status_line->first_line ); return -1; } | 733 | if( strcmp( p, "HTTP" ) != 0 ) { free( status_line->first_line ); return -1; } |
748 | 734 | ||
749 | p = strtok( NULL, "." ); | 735 | p = strtok( NULL, "." ); |
750 | if( p == NULL ) { free( status_line->first_line ); return -1; } | 736 | if( p == NULL ) { free( status_line->first_line ); return -1; } |
751 | status_line->http_major = (int)strtol( p, &pp, 10 ); | 737 | status_line->http_major = (int)strtol( p, &pp, 10 ); |
752 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } | 738 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } |
753 | 739 | ||
754 | p = strtok( NULL, " " ); | 740 | p = strtok( NULL, " " ); |
755 | if( p == NULL ) { free( status_line->first_line ); return -1; } | 741 | if( p == NULL ) { free( status_line->first_line ); return -1; } |
756 | status_line->http_minor = (int)strtol( p, &pp, 10 ); | 742 | status_line->http_minor = (int)strtol( p, &pp, 10 ); |
757 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } | 743 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } |
758 | 744 | ||
759 | /* status code: "404" or "404.1", then SP */ | 745 | /* status code: "404" or "404.1", then SP */ |
760 | 746 | ||
761 | p = strtok( NULL, " ." ); | 747 | p = strtok( NULL, " ." ); |
762 | if( p == NULL ) { free( status_line->first_line ); return -1; } | 748 | if( p == NULL ) { free( status_line->first_line ); return -1; } |
763 | if( strchr( p, '.' ) != NULL ) { | 749 | if( strchr( p, '.' ) != NULL ) { |
764 | char *ppp; | 750 | char *ppp; |
765 | ppp = strtok( p, "." ); | 751 | ppp = strtok( p, "." ); |
766 | status_line->http_code = (int)strtol( ppp, &pp, 10 ); | 752 | status_line->http_code = (int)strtol( ppp, &pp, 10 ); |
767 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } | 753 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } |
768 | 754 | ||
769 | ppp = strtok( NULL, "" ); | 755 | ppp = strtok( NULL, "" ); |
770 | status_line->http_subcode = (int)strtol( ppp, &pp, 10 ); | 756 | status_line->http_subcode = (int)strtol( ppp, &pp, 10 ); |
771 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } | 757 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } |
772 | } else { | 758 | } else { |
773 | status_line->http_code = (int)strtol( p, &pp, 10 ); | 759 | status_line->http_code = (int)strtol( p, &pp, 10 ); |
774 | status_line->http_subcode = -1; | 760 | status_line->http_subcode = -1; |
775 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } | 761 | if( *pp != '\0' ) { free( status_line->first_line ); return -1; } |
776 | } | 762 | } |
777 | 763 | ||
778 | /* Human readable message: "Not Found" CRLF */ | 764 | /* Human readable message: "Not Found" CRLF */ |
779 | 765 | ||
780 | p = strtok( NULL, "" ); | 766 | p = strtok( NULL, "" ); |
781 | if( p == NULL ) { free( status_line->first_line ); return -1; } | 767 | if( p == NULL ) { free( status_line->first_line ); return -1; } |
782 | status_line->msg = p; | 768 | status_line->msg = p; |
783 | 769 | ||
784 | return 0; | 770 | return 0; |
785 | } | 771 | } |
786 | 772 | ||
787 | void | 773 | void |
788 | curlhelp_free_statusline (curlhelp_statusline *status_line) | 774 | curlhelp_free_statusline (curlhelp_statusline *status_line) |
789 | { | 775 | { |
790 | free (status_line->first_line); | 776 | free (status_line->first_line); |
791 | } | 777 | } |
792 | 778 | ||
793 | void | 779 | void |
794 | remove_newlines (char *s) | 780 | remove_newlines (char *s) |
795 | { | 781 | { |
796 | char *p; | 782 | char *p; |
797 | 783 | ||
798 | for (p = s; *p != '\0'; p++) | 784 | for (p = s; *p != '\0'; p++) |
799 | if (*p == '\r' || *p == '\n') | 785 | if (*p == '\r' || *p == '\n') |
800 | *p = ' '; | 786 | *p = ' '; |
801 | } | 787 | } |