[nagiosplug] check_http: Support HTTP CONNECT method
Nagios Plugin Development
nagios-plugins at users.sourceforge.net
Tue Sep 10 11:20:32 CEST 2013
Module: nagiosplug
Branch: hw/http-connect
Commit: 6b28ae739b1ca9f20519f7522b52d055ce3a0902
Author: Holger Weiss <holger at zedat.fu-berlin.de>
Date: Tue Sep 10 11:09:22 2013 +0200
URL: http://nagiosplug.git.sf.net/git/gitweb.cgi?p=nagiosplug/nagiosplug;a=commit;h=6b28ae7
check_http: Support HTTP CONNECT method
Add the -Y/--http-connect[=<port>] option which tells check_http to use
the HTTP CONNECT method for tunneling an HTTPS connection through a
proxy server.
This is a modified version of a patch provided by Mark Frost in
SourceForge tracker item #2975393, updated for the current check_http
code. Changes include:
- Let the new --http-connect option imply --ssl.
- Allow for specifying the server port the proxy should connect to.
---
NEWS | 1 +
THANKS.in | 1 +
plugins/check_http.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 6c01776..17acce2 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ This file documents the major additions and syntax changes between releases.
New switch -E/--extended-perfdata for check_http to print additional performance data (Sebastian Nohn)
New check_http -d option to specify a string to expect within the response headers
New check_http -J/-K options for client certificate authentication support
+ New check_http -Y/--http-connect[=<port>] option for tunneling SSL connections through proxies
Add support for executing queries to check_pgsql
Let check_pgsql accept a UNIX socket directory as hostname
New check_pgsql -o option to specify additional connection parameters
diff --git a/THANKS.in b/THANKS.in
index 6118143..a6caa46 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -286,3 +286,4 @@ Fabio Rueda
Gabriele Tozzi
Sebastian Nohn
Emmanuel Dreyfus
+Mark Frost
diff --git a/plugins/check_http.c b/plugins/check_http.c
index c44bb3a..43c37e0 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -118,6 +118,8 @@ int use_ssl = FALSE;
int use_sni = FALSE;
int verbose = FALSE;
int show_extended_perfdata = FALSE;
+int http_connect = FALSE;
+int connect_port = HTTPS_PORT;
int sd;
int min_page_len = 0;
int max_page_len = 0;
@@ -133,6 +135,7 @@ char *client_privkey = NULL;
int process_arguments (int, char **);
int check_http (void);
void redir (char *pos, char *status_line);
+int http_connect_through_proxy (char *host_name, int port, char *user_agent, int sd);
int server_type_check(const char *type);
int server_port_check(int ssl_flag);
char *perfd_time (double microsec);
@@ -209,6 +212,7 @@ process_arguments (int argc, char **argv)
{"nohtml", no_argument, 0, 'n'},
{"ssl", optional_argument, 0, 'S'},
{"sni", no_argument, 0, SNI_OPTION},
+ {"http-connect", optional_argument, 0, 'Y'},
{"post", required_argument, 0, 'P'},
{"method", required_argument, 0, 'j'},
{"IP-address", required_argument, 0, 'I'},
@@ -257,7 +261,7 @@ process_arguments (int argc, char **argv)
}
while (1) {
- c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:N:E", longopts, &option);
+ c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:Y::T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:N:E", longopts, &option);
if (c == -1 || c == EOF)
break;
@@ -336,6 +340,13 @@ process_arguments (int argc, char **argv)
client_privkey = optarg;
goto enable_ssl;
#endif
+ case 'Y': /* Use HTTP CONNECT */
+#ifdef HAVE_SSL
+ if (optarg != NULL && ((connect_port = atoi (optarg)) < 1 || connect_port > 65535))
+ usage2 (_("Invalid HTTP CONNECT port number"), optarg);
+ http_connect = TRUE;
+ goto enable_ssl;
+#endif
case 'S': /* use SSL */
#ifdef HAVE_SSL
enable_ssl:
@@ -879,6 +890,8 @@ check_http (void)
elapsed_time_connect = (double)microsec_connect / 1.0e6;
if (use_ssl == TRUE) {
gettimeofday (&tv_temp, NULL);
+ if (http_connect == TRUE && http_connect_through_proxy (host_name, connect_port, user_agent, sd) != STATE_OK)
+ die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open proxy tunnel TCP socket\n"));
result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
if (result != STATE_OK)
return result;
@@ -1369,6 +1382,41 @@ redir (char *pos, char *status_line)
check_http ();
}
+/* start the HTTP CONNECT method exchange with a proxy host */
+int
+http_connect_through_proxy (char *host_name, int port, char *user_agent, int sd)
+{
+ int result;
+ char *send_buffer=NULL;
+ char recv_buffer[MAX_INPUT_BUFFER];
+ char *status_line;
+ char *status_code;
+ int http_status;
+
+ asprintf( &send_buffer, "CONNECT %s:%d HTTP/1.0\r\nUser-agent: %s\r\n\r\n", host_name, port, user_agent);
+
+ result = STATE_OK;
+ result = send_tcp_request (sd, send_buffer, recv_buffer, sizeof(recv_buffer));
+ if (result != STATE_OK)
+ return result;
+
+ status_line = recv_buffer;
+ status_line[strcspn(status_line, "\r\n")] = 0;
+ strip (status_line);
+ if (verbose)
+ printf ("HTTP_CONNECT STATUS: %s\n", status_line);
+
+ status_code = strchr (status_line, ' ') + sizeof (char);
+ if (strspn (status_code, "1234567890") != 3)
+ die (STATE_CRITICAL, _("HTTP CRITICAL: HTTP_CONNECT Returns Invalid Status Line (%s)\n"), status_line);
+
+ http_status = atoi (status_code);
+
+ if (http_status != 200)
+ die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid HTTP Connect Proxy Status (%s)\n"), status_line);
+
+ return STATE_OK;
+}
int
server_type_check (const char *type)
@@ -1479,6 +1527,10 @@ print_help (void)
printf (" %s\n", "-K, --private-key=FILE");
printf (" %s\n", _("Name of file containing the private key (PEM format)"));
printf (" %s\n", _("matching the client certificate"));
+ printf (" %s\n", "-Y, --http-connect=PORT");
+ printf (" %s\n", _("Connect to a proxy using the HTTP CONNECT method (SSL tunnel)."));
+ printf (" %s\n", _("Implies -S. The optional PORT number specifies the port on the server the"));
+ printf (" %s\n\n", _("proxy should connect to (default: 443)."));
#endif
printf (" %s\n", "-e, --expect=STRING");
@@ -1589,7 +1641,7 @@ print_usage (void)
{
printf ("%s\n", _("Usage:"));
printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
- printf (" [-J <client certificate file>] [-K <private key>]\n");
+ printf (" [-J <client certificate file>] [-K <private key>] [-Y <port>]\n");
printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n");
printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
More information about the Commits
mailing list