diff options
author | Lionel Cons <lionel.cons@cern.ch> | 2013-05-17 15:00:09 +0200 |
---|---|---|
committer | Lionel Cons <lionel.cons@cern.ch> | 2013-05-17 15:00:09 +0200 |
commit | 2f92d0dab77a3f3b1005dae3401ea1316d6789b2 (patch) | |
tree | 09dc9a8967680b8d2b27cea698f629b40bc1aab7 /plugins | |
parent | 1fd504b6117af25d3baa0c1afc5dbf7fc3c66f2c (diff) | |
download | monitoring-plugins-2f92d0dab77a3f3b1005dae3401ea1316d6789b2.tar.gz |
added support for client authentication via SSL
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/check_http.c | 45 | ||||
-rw-r--r-- | plugins/netutils.h | 2 | ||||
-rw-r--r-- | plugins/sslutils.c | 12 |
3 files changed, 54 insertions, 5 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c index 9231a559..ddaca337 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
@@ -124,6 +124,8 @@ char *http_method; | |||
124 | char *http_post_data; | 124 | char *http_post_data; |
125 | char *http_content_type; | 125 | char *http_content_type; |
126 | char buffer[MAX_INPUT_BUFFER]; | 126 | char buffer[MAX_INPUT_BUFFER]; |
127 | char *client_cert = NULL; | ||
128 | char *client_privkey = NULL; | ||
127 | 129 | ||
128 | int process_arguments (int, char **); | 130 | int process_arguments (int, char **); |
129 | int check_http (void); | 131 | int check_http (void); |
@@ -170,7 +172,14 @@ main (int argc, char **argv) | |||
170 | return result; | 172 | return result; |
171 | } | 173 | } |
172 | 174 | ||
173 | 175 | /* check whether a file exists */ | |
176 | void | ||
177 | test_file (char *path) | ||
178 | { | ||
179 | if (access(path, R_OK) == 0) | ||
180 | return; | ||
181 | usage2 (_("file does not exist or is not readable"), path); | ||
182 | } | ||
174 | 183 | ||
175 | /* process command-line arguments */ | 184 | /* process command-line arguments */ |
176 | int | 185 | int |
@@ -207,6 +216,8 @@ process_arguments (int argc, char **argv) | |||
207 | {"linespan", no_argument, 0, 'l'}, | 216 | {"linespan", no_argument, 0, 'l'}, |
208 | {"onredirect", required_argument, 0, 'f'}, | 217 | {"onredirect", required_argument, 0, 'f'}, |
209 | {"certificate", required_argument, 0, 'C'}, | 218 | {"certificate", required_argument, 0, 'C'}, |
219 | {"client-cert", required_argument, 0, 'E'}, | ||
220 | {"private-key", required_argument, 0, 'K'}, | ||
210 | {"useragent", required_argument, 0, 'A'}, | 221 | {"useragent", required_argument, 0, 'A'}, |
211 | {"header", required_argument, 0, 'k'}, | 222 | {"header", required_argument, 0, 'k'}, |
212 | {"no-body", no_argument, 0, 'N'}, | 223 | {"no-body", no_argument, 0, 'N'}, |
@@ -236,7 +247,7 @@ process_arguments (int argc, char **argv) | |||
236 | } | 247 | } |
237 | 248 | ||
238 | while (1) { | 249 | while (1) { |
239 | c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:e:p:s:R:r:u:f:C:nlLS::m:M:N", longopts, &option); | 250 | c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:e:p:s:R:r:u:f:C:E:K:nlLS::m:M:N", longopts, &option); |
240 | if (c == -1 || c == EOF) | 251 | if (c == -1 || c == EOF) |
241 | break; | 252 | break; |
242 | 253 | ||
@@ -301,10 +312,23 @@ process_arguments (int argc, char **argv) | |||
301 | days_till_exp_warn = atoi (optarg); | 312 | days_till_exp_warn = atoi (optarg); |
302 | } | 313 | } |
303 | check_cert = TRUE; | 314 | check_cert = TRUE; |
304 | /* Fall through to -S option */ | 315 | goto enable_ssl; |
316 | #endif | ||
317 | case 'E': /* use client certificate */ | ||
318 | #ifdef HAVE_SSL | ||
319 | test_file(optarg); | ||
320 | client_cert = optarg; | ||
321 | goto enable_ssl; | ||
322 | #endif | ||
323 | case 'K': /* use client private key */ | ||
324 | #ifdef HAVE_SSL | ||
325 | test_file(optarg); | ||
326 | client_privkey = optarg; | ||
327 | goto enable_ssl; | ||
305 | #endif | 328 | #endif |
306 | case 'S': /* use SSL */ | 329 | case 'S': /* use SSL */ |
307 | #ifdef HAVE_SSL | 330 | #ifdef HAVE_SSL |
331 | enable_ssl: | ||
308 | use_ssl = TRUE; | 332 | use_ssl = TRUE; |
309 | if (optarg == NULL || c != 'S') | 333 | if (optarg == NULL || c != 'S') |
310 | ssl_version = 0; | 334 | ssl_version = 0; |
@@ -316,6 +340,7 @@ process_arguments (int argc, char **argv) | |||
316 | if (specify_port == FALSE) | 340 | if (specify_port == FALSE) |
317 | server_port = HTTPS_PORT; | 341 | server_port = HTTPS_PORT; |
318 | #else | 342 | #else |
343 | /* -C -E and -K fall through to here without SSL */ | ||
319 | usage4 (_("Invalid option - SSL is not available")); | 344 | usage4 (_("Invalid option - SSL is not available")); |
320 | #endif | 345 | #endif |
321 | break; | 346 | break; |
@@ -497,6 +522,9 @@ process_arguments (int argc, char **argv) | |||
497 | if (http_method == NULL) | 522 | if (http_method == NULL) |
498 | http_method = strdup ("GET"); | 523 | http_method = strdup ("GET"); |
499 | 524 | ||
525 | if (client_cert && !client_privkey) | ||
526 | usage4 (_("If you use a client certificate you must also specify a private key file")); | ||
527 | |||
500 | return TRUE; | 528 | return TRUE; |
501 | } | 529 | } |
502 | 530 | ||
@@ -820,7 +848,7 @@ check_http (void) | |||
820 | die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n")); | 848 | die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n")); |
821 | #ifdef HAVE_SSL | 849 | #ifdef HAVE_SSL |
822 | if (use_ssl == TRUE) { | 850 | if (use_ssl == TRUE) { |
823 | result = np_net_ssl_init_with_hostname_and_version(sd, (use_sni ? host_name : NULL), ssl_version); | 851 | result = np_net_ssl_init_with_hostname_version_and_certificate(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey); |
824 | if (result != STATE_OK) | 852 | if (result != STATE_OK) |
825 | return result; | 853 | return result; |
826 | if (check_cert == TRUE) { | 854 | if (check_cert == TRUE) { |
@@ -1354,7 +1382,13 @@ print_help (void) | |||
1354 | printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); | 1382 | printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); |
1355 | printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); | 1383 | printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); |
1356 | printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); | 1384 | printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); |
1357 | printf (" %s\n", _("(when this option is used the URL is not checked.)\n")); | 1385 | printf (" %s\n", _("(when this option is used the URL is not checked.)")); |
1386 | printf (" %s\n", "-E, --client-cert=FILE"); | ||
1387 | printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); | ||
1388 | printf (" %s\n", _("to be used in establishing the SSL session")); | ||
1389 | printf (" %s\n", "-K, --private-key=FILE"); | ||
1390 | printf (" %s\n", _("Name of file containing the private key (PEM format)")); | ||
1391 | printf (" %s\n", _("matching the client certificate")); | ||
1358 | #endif | 1392 | #endif |
1359 | 1393 | ||
1360 | printf (" %s\n", "-e, --expect=STRING"); | 1394 | printf (" %s\n", "-e, --expect=STRING"); |
@@ -1461,6 +1495,7 @@ print_usage (void) | |||
1461 | { | 1495 | { |
1462 | printf ("%s\n", _("Usage:")); | 1496 | printf ("%s\n", _("Usage:")); |
1463 | printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); | 1497 | printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); |
1498 | printf (" [-E <client certificate file>] [-K <private key>]\n"); | ||
1464 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-a auth]\n"); | 1499 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-a auth]\n"); |
1465 | printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n"); | 1500 | printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n"); |
1466 | printf (" [-e <expect>] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); | 1501 | printf (" [-e <expect>] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); |
diff --git a/plugins/netutils.h b/plugins/netutils.h index 21017f1f..765b3d5f 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h | |||
@@ -100,6 +100,8 @@ extern int address_family; | |||
100 | /* maybe this could be merged with the above np_net_connect, via some flags */ | 100 | /* maybe this could be merged with the above np_net_connect, via some flags */ |
101 | int np_net_ssl_init(int sd); | 101 | int np_net_ssl_init(int sd); |
102 | int np_net_ssl_init_with_hostname(int sd, char *host_name); | 102 | int np_net_ssl_init_with_hostname(int sd, char *host_name); |
103 | int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version); | ||
104 | int np_net_ssl_init_with_hostname_version_and_certificate(int sd, char *host_name, int version, char *cert, char *privkey); | ||
103 | void np_net_ssl_cleanup(); | 105 | void np_net_ssl_cleanup(); |
104 | int np_net_ssl_write(const void *buf, int num); | 106 | int np_net_ssl_write(const void *buf, int num); |
105 | int np_net_ssl_read(void *buf, int num); | 107 | int np_net_ssl_read(void *buf, int num); |
diff --git a/plugins/sslutils.c b/plugins/sslutils.c index a1ce560d..4927e361 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c | |||
@@ -45,6 +45,10 @@ int np_net_ssl_init_with_hostname(int sd, char *host_name) { | |||
45 | } | 45 | } |
46 | 46 | ||
47 | int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) { | 47 | int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) { |
48 | return np_net_ssl_init_with_hostname_version_and_certificate(sd, host_name, version, NULL, NULL); | ||
49 | } | ||
50 | |||
51 | int np_net_ssl_init_with_hostname_version_and_certificate(int sd, char *host_name, int version, char *cert, char *privkey) { | ||
48 | const SSL_METHOD *method = NULL; | 52 | const SSL_METHOD *method = NULL; |
49 | 53 | ||
50 | switch (version) { | 54 | switch (version) { |
@@ -80,6 +84,14 @@ int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int versi | |||
80 | printf("%s\n", _("CRITICAL - Cannot create SSL context.")); | 84 | printf("%s\n", _("CRITICAL - Cannot create SSL context.")); |
81 | return STATE_CRITICAL; | 85 | return STATE_CRITICAL; |
82 | } | 86 | } |
87 | if (cert && privkey) { | ||
88 | SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM); | ||
89 | SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM); | ||
90 | if (!SSL_CTX_check_private_key(c)) { | ||
91 | printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n")); | ||
92 | return STATE_CRITICAL; | ||
93 | } | ||
94 | } | ||
83 | #ifdef SSL_OP_NO_TICKET | 95 | #ifdef SSL_OP_NO_TICKET |
84 | SSL_CTX_set_options(c, SSL_OP_NO_TICKET); | 96 | SSL_CTX_set_options(c, SSL_OP_NO_TICKET); |
85 | #endif | 97 | #endif |