diff options
Diffstat (limited to 'plugins/check_http.c')
-rw-r--r-- | plugins/check_http.c | 297 |
1 files changed, 29 insertions, 268 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c index 294866b0..413d501d 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
@@ -37,38 +37,17 @@ enum { | |||
37 | HTTPS_PORT = 443 | 37 | HTTPS_PORT = 443 |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #ifdef HAVE_SSL_H | ||
41 | #include <rsa.h> | ||
42 | #include <crypto.h> | ||
43 | #include <x509.h> | ||
44 | #include <pem.h> | ||
45 | #include <ssl.h> | ||
46 | #include <err.h> | ||
47 | #include <rand.h> | ||
48 | #else | ||
49 | # ifdef HAVE_OPENSSL_SSL_H | ||
50 | # include <openssl/rsa.h> | ||
51 | # include <openssl/crypto.h> | ||
52 | # include <openssl/x509.h> | ||
53 | # include <openssl/pem.h> | ||
54 | # include <openssl/ssl.h> | ||
55 | # include <openssl/err.h> | ||
56 | # include <openssl/rand.h> | ||
57 | # endif | ||
58 | #endif | ||
59 | |||
60 | #ifdef HAVE_SSL | 40 | #ifdef HAVE_SSL |
61 | int check_cert = FALSE; | 41 | int check_cert = FALSE; |
62 | int days_till_exp; | 42 | int days_till_exp; |
63 | char *randbuff; | 43 | char *randbuff; |
64 | SSL_CTX *ctx; | ||
65 | SSL *ssl; | ||
66 | X509 *server_cert; | 44 | X509 *server_cert; |
67 | int connect_SSL (void); | 45 | # define my_recv(buf, len) ((use_ssl) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) |
68 | # ifdef USE_OPENSSL | 46 | # define my_send(buf, len) ((use_ssl) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) |
69 | int check_certificate (X509 **); | 47 | #else /* ifndef HAVE_SSL */ |
70 | # endif | 48 | # define my_recv(buf, len) read(sd, buf, len) |
71 | #endif | 49 | # define my_send(buf, len) send(sd, buf, len, 0) |
50 | #endif /* HAVE_SSL */ | ||
72 | int no_body = FALSE; | 51 | int no_body = FALSE; |
73 | int maximum_age = -1; | 52 | int maximum_age = -1; |
74 | 53 | ||
@@ -132,8 +111,6 @@ int server_type_check(const char *type); | |||
132 | int server_port_check(int ssl_flag); | 111 | int server_port_check(int ssl_flag); |
133 | char *perfd_time (double microsec); | 112 | char *perfd_time (double microsec); |
134 | char *perfd_size (int page_len); | 113 | char *perfd_size (int page_len); |
135 | int my_recv (void); | ||
136 | int my_close (void); | ||
137 | void print_help (void); | 114 | void print_help (void); |
138 | void print_usage (void); | 115 | void print_usage (void); |
139 | 116 | ||
@@ -168,29 +145,7 @@ main (int argc, char **argv) | |||
168 | (void) alarm (socket_timeout); | 145 | (void) alarm (socket_timeout); |
169 | gettimeofday (&tv, NULL); | 146 | gettimeofday (&tv, NULL); |
170 | 147 | ||
171 | #ifdef USE_OPENSSL | ||
172 | if (use_ssl && check_cert == TRUE) { | ||
173 | if (connect_SSL () != OK) | ||
174 | die (STATE_CRITICAL, _("HTTP CRITICAL - Could not make SSL connection\n")); | ||
175 | if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { | ||
176 | result = check_certificate (&server_cert); | ||
177 | X509_free (server_cert); | ||
178 | } | ||
179 | else { | ||
180 | printf (_("CRITICAL - Cannot retrieve server certificate.\n")); | ||
181 | result = STATE_CRITICAL; | ||
182 | } | ||
183 | SSL_shutdown (ssl); | ||
184 | SSL_free (ssl); | ||
185 | SSL_CTX_free (ctx); | ||
186 | close (sd); | ||
187 | } | ||
188 | else { | ||
189 | result = check_http (); | ||
190 | } | ||
191 | #else | ||
192 | result = check_http (); | 148 | result = check_http (); |
193 | #endif | ||
194 | return result; | 149 | return result; |
195 | } | 150 | } |
196 | 151 | ||
@@ -790,34 +745,27 @@ check_http (void) | |||
790 | long microsec; | 745 | long microsec; |
791 | double elapsed_time; | 746 | double elapsed_time; |
792 | int page_len = 0; | 747 | int page_len = 0; |
748 | int result = STATE_UNKNOWN; | ||
793 | #ifdef HAVE_SSL | 749 | #ifdef HAVE_SSL |
794 | int sslerr; | 750 | int sslerr; |
795 | #endif | 751 | #endif |
796 | 752 | ||
797 | /* try to connect to the host at the given port number */ | 753 | /* try to connect to the host at the given port number */ |
754 | if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) | ||
755 | die (STATE_CRITICAL, _("Unable to open TCP socket\n")); | ||
798 | #ifdef HAVE_SSL | 756 | #ifdef HAVE_SSL |
799 | if (use_ssl == TRUE) { | 757 | if (use_ssl == TRUE) { |
800 | 758 | np_net_ssl_init(sd); | |
801 | if (connect_SSL () != OK) { | 759 | if (check_cert == TRUE) { |
802 | die (STATE_CRITICAL, _("Unable to open TCP socket\n")); | 760 | result = np_net_ssl_check_cert(days_till_exp); |
803 | } | 761 | if(result != STATE_OK){ |
804 | # ifdef USE_OPENSSL | 762 | np_net_ssl_cleanup(); |
805 | if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { | 763 | if(sd) close(sd); |
806 | X509_free (server_cert); | 764 | return result; |
807 | } | 765 | } |
808 | else { | ||
809 | printf (_("CRITICAL - Cannot retrieve server certificate.\n")); | ||
810 | return STATE_CRITICAL; | ||
811 | } | 766 | } |
812 | # endif /* USE_OPENSSL */ | ||
813 | } | ||
814 | else { | ||
815 | #endif | ||
816 | if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) | ||
817 | die (STATE_CRITICAL, _("Unable to open TCP socket\n")); | ||
818 | #ifdef HAVE_SSL | ||
819 | } | 767 | } |
820 | #endif | 768 | #endif /* HAVE_SSL */ |
821 | 769 | ||
822 | asprintf (&buf, "%s %s HTTP/1.0\r\n%s\r\n", http_method, server_url, user_agent); | 770 | asprintf (&buf, "%s %s HTTP/1.0\r\n%s\r\n", http_method, server_url, user_agent); |
823 | 771 | ||
@@ -853,28 +801,12 @@ check_http (void) | |||
853 | asprintf (&buf, "%s%s", buf, CRLF); | 801 | asprintf (&buf, "%s%s", buf, CRLF); |
854 | } | 802 | } |
855 | 803 | ||
856 | if (verbose) | 804 | if (verbose) printf ("%s\n", buf); |
857 | printf ("%s\n", buf); | 805 | my_send (buf, strlen (buf)); |
858 | |||
859 | #ifdef HAVE_SSL | ||
860 | if (use_ssl == TRUE) { | ||
861 | if (SSL_write (ssl, buf, (int)strlen(buf)) == -1) { | ||
862 | # ifdef USE_OPENSSL | ||
863 | ERR_print_errors_fp (stderr); | ||
864 | # endif | ||
865 | return STATE_CRITICAL; | ||
866 | } | ||
867 | } | ||
868 | else { | ||
869 | #endif | ||
870 | send (sd, buf, strlen (buf), 0); | ||
871 | #ifdef HAVE_SSL | ||
872 | } | ||
873 | #endif | ||
874 | 806 | ||
875 | /* fetch the page */ | 807 | /* fetch the page */ |
876 | full_page = strdup(""); | 808 | full_page = strdup(""); |
877 | while ((i = my_recv ()) > 0) { | 809 | while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) { |
878 | buffer[i] = '\0'; | 810 | buffer[i] = '\0'; |
879 | asprintf (&full_page, "%s%s", full_page, buffer); | 811 | asprintf (&full_page, "%s%s", full_page, buffer); |
880 | pagesize += i; | 812 | pagesize += i; |
@@ -887,6 +819,7 @@ check_http (void) | |||
887 | 819 | ||
888 | if (i < 0 && errno != ECONNRESET) { | 820 | if (i < 0 && errno != ECONNRESET) { |
889 | #ifdef HAVE_SSL | 821 | #ifdef HAVE_SSL |
822 | /* | ||
890 | if (use_ssl) { | 823 | if (use_ssl) { |
891 | sslerr=SSL_get_error(ssl, i); | 824 | sslerr=SSL_get_error(ssl, i); |
892 | if ( sslerr == SSL_ERROR_SSL ) { | 825 | if ( sslerr == SSL_ERROR_SSL ) { |
@@ -896,10 +829,13 @@ check_http (void) | |||
896 | } | 829 | } |
897 | } | 830 | } |
898 | else { | 831 | else { |
832 | */ | ||
899 | #endif | 833 | #endif |
900 | die (STATE_CRITICAL, _("Error on receive\n")); | 834 | die (STATE_CRITICAL, _("Error on receive\n")); |
901 | #ifdef HAVE_SSL | 835 | #ifdef HAVE_SSL |
836 | /* XXX | ||
902 | } | 837 | } |
838 | */ | ||
903 | #endif | 839 | #endif |
904 | } | 840 | } |
905 | 841 | ||
@@ -908,7 +844,10 @@ check_http (void) | |||
908 | die (STATE_CRITICAL, _("No data received %s\n"), timestamp); | 844 | die (STATE_CRITICAL, _("No data received %s\n"), timestamp); |
909 | 845 | ||
910 | /* close the connection */ | 846 | /* close the connection */ |
911 | my_close (); | 847 | #ifdef HAVE_SSL |
848 | np_net_ssl_cleanup(); | ||
849 | #endif | ||
850 | if(sd) close(sd); | ||
912 | 851 | ||
913 | /* reset the alarm */ | 852 | /* reset the alarm */ |
914 | alarm (0); | 853 | alarm (0); |
@@ -1248,143 +1187,6 @@ server_port_check (int ssl_flag) | |||
1248 | return HTTP_PORT; | 1187 | return HTTP_PORT; |
1249 | } | 1188 | } |
1250 | 1189 | ||
1251 | |||
1252 | |||
1253 | #ifdef HAVE_SSL | ||
1254 | int connect_SSL (void) | ||
1255 | { | ||
1256 | SSL_METHOD *meth; | ||
1257 | |||
1258 | asprintf (&randbuff, "%s", "qwertyuiopasdfghjklqwertyuiopasdfghjkl"); | ||
1259 | RAND_seed (randbuff, (int)strlen(randbuff)); | ||
1260 | if (verbose) | ||
1261 | printf(_("SSL seeding: %s\n"), (RAND_status()==1 ? _("OK") : _("Failed")) ); | ||
1262 | |||
1263 | /* Initialize SSL context */ | ||
1264 | SSLeay_add_ssl_algorithms (); | ||
1265 | meth = SSLv23_client_method (); | ||
1266 | SSL_load_error_strings (); | ||
1267 | if ((ctx = SSL_CTX_new (meth)) == NULL) { | ||
1268 | printf (_("CRITICAL - Cannot create SSL context.\n")); | ||
1269 | return STATE_CRITICAL; | ||
1270 | } | ||
1271 | |||
1272 | /* Initialize alarm signal handling */ | ||
1273 | signal (SIGALRM, socket_timeout_alarm_handler); | ||
1274 | |||
1275 | /* Set socket timeout */ | ||
1276 | alarm (socket_timeout); | ||
1277 | |||
1278 | /* Save start time */ | ||
1279 | gettimeofday (&tv, NULL); | ||
1280 | |||
1281 | /* Make TCP connection */ | ||
1282 | if (my_tcp_connect (server_address, server_port, &sd) == STATE_OK) { | ||
1283 | /* Do the SSL handshake */ | ||
1284 | if ((ssl = SSL_new (ctx)) != NULL) { | ||
1285 | #ifdef USE_OPENSSL | ||
1286 | SSL_set_cipher_list(ssl, "ALL"); | ||
1287 | #endif | ||
1288 | SSL_set_fd (ssl, sd); | ||
1289 | if (SSL_connect (ssl) != -1) | ||
1290 | return OK; | ||
1291 | #ifdef USE_OPENSSL | ||
1292 | ERR_print_errors_fp (stderr); | ||
1293 | #endif | ||
1294 | } | ||
1295 | else { | ||
1296 | printf (_("CRITICAL - Cannot initiate SSL handshake.\n")); | ||
1297 | } | ||
1298 | SSL_free (ssl); | ||
1299 | } | ||
1300 | |||
1301 | SSL_CTX_free (ctx); | ||
1302 | close (sd); | ||
1303 | |||
1304 | return STATE_CRITICAL; | ||
1305 | } | ||
1306 | #endif | ||
1307 | |||
1308 | |||
1309 | |||
1310 | #ifdef USE_OPENSSL | ||
1311 | int | ||
1312 | check_certificate (X509 ** certificate) | ||
1313 | { | ||
1314 | ASN1_STRING *tm; | ||
1315 | int offset; | ||
1316 | struct tm stamp; | ||
1317 | int days_left; | ||
1318 | |||
1319 | |||
1320 | /* Retrieve timestamp of certificate */ | ||
1321 | tm = X509_get_notAfter (*certificate); | ||
1322 | |||
1323 | /* Generate tm structure to process timestamp */ | ||
1324 | if (tm->type == V_ASN1_UTCTIME) { | ||
1325 | if (tm->length < 10) { | ||
1326 | printf (_("CRITICAL - Wrong time format in certificate.\n")); | ||
1327 | return STATE_CRITICAL; | ||
1328 | } | ||
1329 | else { | ||
1330 | stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); | ||
1331 | if (stamp.tm_year < 50) | ||
1332 | stamp.tm_year += 100; | ||
1333 | offset = 0; | ||
1334 | } | ||
1335 | } | ||
1336 | else { | ||
1337 | if (tm->length < 12) { | ||
1338 | printf (_("CRITICAL - Wrong time format in certificate.\n")); | ||
1339 | return STATE_CRITICAL; | ||
1340 | } | ||
1341 | else { | ||
1342 | stamp.tm_year = | ||
1343 | (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + | ||
1344 | (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); | ||
1345 | stamp.tm_year -= 1900; | ||
1346 | offset = 2; | ||
1347 | } | ||
1348 | } | ||
1349 | stamp.tm_mon = | ||
1350 | (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; | ||
1351 | stamp.tm_mday = | ||
1352 | (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); | ||
1353 | stamp.tm_hour = | ||
1354 | (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0'); | ||
1355 | stamp.tm_min = | ||
1356 | (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0'); | ||
1357 | stamp.tm_sec = 0; | ||
1358 | stamp.tm_isdst = -1; | ||
1359 | |||
1360 | days_left = (mktime (&stamp) - time (NULL)) / 86400; | ||
1361 | snprintf | ||
1362 | (timestamp, 17, "%02d/%02d/%04d %02d:%02d", | ||
1363 | stamp.tm_mon + 1, | ||
1364 | stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min); | ||
1365 | |||
1366 | if (days_left > 0 && days_left <= days_till_exp) { | ||
1367 | printf (_("WARNING - Certificate expires in %d day(s) (%s).\n"), days_left, timestamp); | ||
1368 | return STATE_WARNING; | ||
1369 | } | ||
1370 | if (days_left < 0) { | ||
1371 | printf (_("CRITICAL - Certificate expired on %s.\n"), timestamp); | ||
1372 | return STATE_CRITICAL; | ||
1373 | } | ||
1374 | |||
1375 | if (days_left == 0) { | ||
1376 | printf (_("WARNING - Certificate expires today (%s).\n"), timestamp); | ||
1377 | return STATE_WARNING; | ||
1378 | } | ||
1379 | |||
1380 | printf (_("OK - Certificate will expire on %s.\n"), timestamp); | ||
1381 | |||
1382 | return STATE_OK; | ||
1383 | } | ||
1384 | #endif | ||
1385 | |||
1386 | |||
1387 | |||
1388 | char *perfd_time (double elapsed_time) | 1190 | char *perfd_time (double elapsed_time) |
1389 | { | 1191 | { |
1390 | return fperfdata ("time", elapsed_time, "s", | 1192 | return fperfdata ("time", elapsed_time, "s", |
@@ -1403,47 +1205,6 @@ char *perfd_size (int page_len) | |||
1403 | TRUE, 0, FALSE, 0); | 1205 | TRUE, 0, FALSE, 0); |
1404 | } | 1206 | } |
1405 | 1207 | ||
1406 | |||
1407 | |||
1408 | int | ||
1409 | my_recv (void) | ||
1410 | { | ||
1411 | int i; | ||
1412 | #ifdef HAVE_SSL | ||
1413 | if (use_ssl) { | ||
1414 | i = SSL_read (ssl, buffer, MAX_INPUT_BUFFER - 1); | ||
1415 | } | ||
1416 | else { | ||
1417 | i = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); | ||
1418 | } | ||
1419 | #else | ||
1420 | i = recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0); | ||
1421 | #endif | ||
1422 | return i; | ||
1423 | } | ||
1424 | |||
1425 | |||
1426 | |||
1427 | int | ||
1428 | my_close (void) | ||
1429 | { | ||
1430 | #ifdef HAVE_SSL | ||
1431 | if (use_ssl == TRUE) { | ||
1432 | SSL_shutdown (ssl); | ||
1433 | SSL_free (ssl); | ||
1434 | SSL_CTX_free (ctx); | ||
1435 | return 0; | ||
1436 | } | ||
1437 | else { | ||
1438 | #endif | ||
1439 | return close (sd); | ||
1440 | #ifdef HAVE_SSL | ||
1441 | } | ||
1442 | #endif | ||
1443 | } | ||
1444 | |||
1445 | |||
1446 | |||
1447 | void | 1208 | void |
1448 | print_help (void) | 1209 | print_help (void) |
1449 | { | 1210 | { |