diff options
| author | M. Sean Finney <seanius@users.sourceforge.net> | 2005-10-19 20:22:00 +0000 |
|---|---|---|
| committer | M. Sean Finney <seanius@users.sourceforge.net> | 2005-10-19 20:22:00 +0000 |
| commit | cf66a717e9e8f55315d50b3b33a70b8a6f140981 (patch) | |
| tree | 54dda3e4c83988c27cbc6f08a1d8da586032b4ac /plugins/check_smtp.c | |
| parent | 5dd7b5dff439ab19119efd24d7822ca19b3e5bf7 (diff) | |
| download | monitoring-plugins-cf66a717e9e8f55315d50b3b33a70b8a6f140981.tar.gz | |
all plugins now using centralized ssl functions in netutils.c
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1257 f882894a-f735-0410-b71e-b25c423dba1c
Diffstat (limited to 'plugins/check_smtp.c')
| -rw-r--r-- | plugins/check_smtp.c | 218 |
1 files changed, 20 insertions, 198 deletions
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index 19e9aea8..ad85c7f6 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c | |||
| @@ -27,35 +27,14 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
| 27 | #include "netutils.h" | 27 | #include "netutils.h" |
| 28 | #include "utils.h" | 28 | #include "utils.h" |
| 29 | 29 | ||
| 30 | #ifdef HAVE_SSL_H | ||
| 31 | # include <rsa.h> | ||
| 32 | # include <crypto.h> | ||
| 33 | # include <x509.h> | ||
| 34 | # include <pem.h> | ||
| 35 | # include <ssl.h> | ||
| 36 | # include <err.h> | ||
| 37 | #else | ||
| 38 | # ifdef HAVE_OPENSSL_SSL_H | ||
| 39 | # include <openssl/rsa.h> | ||
| 40 | # include <openssl/crypto.h> | ||
| 41 | # include <openssl/x509.h> | ||
| 42 | # include <openssl/pem.h> | ||
| 43 | # include <openssl/ssl.h> | ||
| 44 | # include <openssl/err.h> | ||
| 45 | # endif | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #ifdef HAVE_SSL | 30 | #ifdef HAVE_SSL |
| 49 | |||
| 50 | int check_cert = FALSE; | 31 | int check_cert = FALSE; |
| 51 | int days_till_exp; | 32 | int days_till_exp; |
| 52 | SSL_CTX *ctx; | 33 | # define my_recv(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) |
| 53 | SSL *ssl; | 34 | # define my_send(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) |
| 54 | X509 *server_cert; | 35 | #else /* ifndef HAVE_SSL */ |
| 55 | int connect_STARTTLS (void); | 36 | # define my_recv(buf, len) read(sd, buf, len) |
| 56 | # ifdef USE_OPENSSL | 37 | # define my_send(buf, len) send(sd, buf, len, 0) |
| 57 | int check_certificate (X509 **); | ||
| 58 | # endif | ||
| 59 | #endif | 38 | #endif |
| 60 | 39 | ||
| 61 | enum { | 40 | enum { |
| @@ -77,7 +56,6 @@ int process_arguments (int, char **); | |||
| 77 | int validate_arguments (void); | 56 | int validate_arguments (void); |
| 78 | void print_help (void); | 57 | void print_help (void); |
| 79 | void print_usage (void); | 58 | void print_usage (void); |
| 80 | int myrecv(void); | ||
| 81 | int my_close(void); | 59 | int my_close(void); |
| 82 | 60 | ||
| 83 | #ifdef HAVE_REGEX_H | 61 | #ifdef HAVE_REGEX_H |
| @@ -111,7 +89,7 @@ int check_critical_time = FALSE; | |||
| 111 | int verbose = 0; | 89 | int verbose = 0; |
| 112 | int use_ssl = FALSE; | 90 | int use_ssl = FALSE; |
| 113 | short use_ehlo = FALSE; | 91 | short use_ehlo = FALSE; |
| 114 | short ssl_established = TRUE; | 92 | short ssl_established = 0; |
| 115 | char *localhostname = NULL; | 93 | char *localhostname = NULL; |
| 116 | int sd; | 94 | int sd; |
| 117 | char buffer[MAX_INPUT_BUFFER]; | 95 | char buffer[MAX_INPUT_BUFFER]; |
| @@ -237,22 +215,20 @@ main (int argc, char **argv) | |||
| 237 | send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0); | 215 | send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0); |
| 238 | return STATE_UNKNOWN; | 216 | return STATE_UNKNOWN; |
| 239 | } | 217 | } |
| 240 | if(connect_STARTTLS() != OK) { | 218 | result = np_net_ssl_init(sd); |
| 219 | if(result != STATE_OK) { | ||
| 241 | printf (_("CRITICAL - Cannot create SSL context.\n")); | 220 | printf (_("CRITICAL - Cannot create SSL context.\n")); |
| 221 | np_net_ssl_cleanup(); | ||
| 222 | close(sd); | ||
| 242 | return STATE_CRITICAL; | 223 | return STATE_CRITICAL; |
| 243 | } else { | 224 | } else { |
| 244 | ssl_established = TRUE; | 225 | ssl_established = 1; |
| 245 | } | 226 | } |
| 246 | # ifdef USE_OPENSSL | 227 | # ifdef USE_OPENSSL |
| 247 | if ( check_cert ) { | 228 | if ( check_cert ) { |
| 248 | if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { | 229 | result = np_net_ssl_check_cert(days_till_exp); |
| 249 | result = check_certificate (&server_cert); | 230 | if(result != STATE_OK){ |
| 250 | X509_free(server_cert); | ||
| 251 | } | ||
| 252 | else { | ||
| 253 | printf (_("CRITICAL - Cannot retrieve server certificate.\n")); | 231 | printf (_("CRITICAL - Cannot retrieve server certificate.\n")); |
| 254 | result = STATE_CRITICAL; | ||
| 255 | |||
| 256 | } | 232 | } |
| 257 | my_close(); | 233 | my_close(); |
| 258 | return result; | 234 | return result; |
| @@ -272,26 +248,16 @@ main (int argc, char **argv) | |||
| 272 | * Use the -f option to provide a FROM address | 248 | * Use the -f option to provide a FROM address |
| 273 | */ | 249 | */ |
| 274 | if (smtp_use_dummycmd) { | 250 | if (smtp_use_dummycmd) { |
| 275 | #ifdef HAVE_SSL | 251 | my_send(cmd_str, strlen(cmd_str)); |
| 276 | if (use_ssl) | 252 | my_recv(buffer, MAX_INPUT_BUFFER-1); |
| 277 | SSL_write(ssl, cmd_str, strlen(cmd_str)); | ||
| 278 | else | ||
| 279 | #endif | ||
| 280 | send(sd, cmd_str, strlen(cmd_str), 0); | ||
| 281 | myrecv(); | ||
| 282 | if (verbose) | 253 | if (verbose) |
| 283 | printf("%s", buffer); | 254 | printf("%s", buffer); |
| 284 | } | 255 | } |
| 285 | 256 | ||
| 286 | while (n < ncommands) { | 257 | while (n < ncommands) { |
| 287 | asprintf (&cmd_str, "%s%s", commands[n], "\r\n"); | 258 | asprintf (&cmd_str, "%s%s", commands[n], "\r\n"); |
| 288 | #ifdef HAVE_SSL | 259 | my_send(cmd_str, strlen(cmd_str)); |
| 289 | if (use_ssl) | 260 | my_recv(buffer, MAX_INPUT_BUFFER-1); |
| 290 | SSL_write(ssl,cmd_str, strlen(cmd_str)); | ||
| 291 | else | ||
| 292 | #endif | ||
| 293 | send(sd, cmd_str, strlen(cmd_str), 0); | ||
| 294 | myrecv(); | ||
| 295 | if (verbose) | 261 | if (verbose) |
| 296 | printf("%s", buffer); | 262 | printf("%s", buffer); |
| 297 | strip (buffer); | 263 | strip (buffer); |
| @@ -328,12 +294,7 @@ main (int argc, char **argv) | |||
| 328 | } | 294 | } |
| 329 | 295 | ||
| 330 | /* tell the server we're done */ | 296 | /* tell the server we're done */ |
| 331 | #ifdef HAVE_SSL | 297 | my_send (SMTP_QUIT, strlen (SMTP_QUIT)); |
| 332 | if (use_ssl) | ||
| 333 | SSL_write(ssl,SMTP_QUIT, strlen (SMTP_QUIT)); | ||
| 334 | else | ||
| 335 | #endif | ||
| 336 | send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0); | ||
| 337 | 298 | ||
| 338 | /* finally close the connection */ | 299 | /* finally close the connection */ |
| 339 | close (sd); | 300 | close (sd); |
| @@ -626,150 +587,11 @@ Usage: %s -H host [-p port] [-e expect] [-C command] [-f from addr]\n\ | |||
| 626 | [-w warn] [-c crit] [-t timeout] [-S] [-D days] [-n] [-v] [-4|-6]\n", progname); | 587 | [-w warn] [-c crit] [-t timeout] [-S] [-D days] [-n] [-v] [-4|-6]\n", progname); |
| 627 | } | 588 | } |
| 628 | 589 | ||
| 629 | #ifdef HAVE_SSL | ||
| 630 | int | ||
| 631 | connect_STARTTLS (void) | ||
| 632 | { | ||
| 633 | SSL_METHOD *meth; | ||
| 634 | |||
| 635 | /* Initialize SSL context */ | ||
| 636 | SSLeay_add_ssl_algorithms (); | ||
| 637 | meth = SSLv23_client_method (); | ||
| 638 | SSL_load_error_strings (); | ||
| 639 | if ((ctx = SSL_CTX_new (meth)) == NULL) | ||
| 640 | { | ||
| 641 | printf(_("CRITICAL - Cannot create SSL context.\n")); | ||
| 642 | return STATE_CRITICAL; | ||
| 643 | } | ||
| 644 | /* do the SSL handshake */ | ||
| 645 | if ((ssl = SSL_new (ctx)) != NULL) | ||
| 646 | { | ||
| 647 | SSL_set_fd (ssl, sd); | ||
| 648 | /* original version checked for -1 | ||
| 649 | I look for success instead (1) */ | ||
| 650 | if (SSL_connect (ssl) == 1) | ||
| 651 | return OK; | ||
| 652 | # ifdef USE_OPENSSL | ||
| 653 | ERR_print_errors_fp (stderr); | ||
| 654 | # endif | ||
| 655 | } | ||
| 656 | else | ||
| 657 | { | ||
| 658 | printf (_("CRITICAL - Cannot initiate SSL handshake.\n")); | ||
| 659 | } | ||
| 660 | my_close(); | ||
| 661 | |||
| 662 | return STATE_CRITICAL; | ||
| 663 | } | ||
| 664 | |||
| 665 | # ifdef USE_OPENSSL | ||
| 666 | int | ||
| 667 | check_certificate (X509 ** certificate) | ||
| 668 | { | ||
| 669 | ASN1_STRING *tm; | ||
| 670 | int offset; | ||
| 671 | struct tm stamp; | ||
| 672 | int days_left; | ||
| 673 | |||
| 674 | /* Retrieve timestamp of certificate */ | ||
| 675 | tm = X509_get_notAfter (*certificate); | ||
| 676 | |||
| 677 | /* Generate tm structure to process timestamp */ | ||
| 678 | if (tm->type == V_ASN1_UTCTIME) { | ||
| 679 | if (tm->length < 10) { | ||
| 680 | printf (_("CRITICAL - Wrong time format in certificate.\n")); | ||
| 681 | return STATE_CRITICAL; | ||
| 682 | } | ||
| 683 | else { | ||
| 684 | stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); | ||
| 685 | if (stamp.tm_year < 50) | ||
| 686 | stamp.tm_year += 100; | ||
| 687 | offset = 0; | ||
| 688 | } | ||
| 689 | } | ||
| 690 | else { | ||
| 691 | if (tm->length < 12) { | ||
| 692 | printf (_("CRITICAL - Wrong time format in certificate.\n")); | ||
| 693 | return STATE_CRITICAL; | ||
| 694 | } | ||
| 695 | else { | ||
| 696 | stamp.tm_year = | ||
| 697 | (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + | ||
| 698 | (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); | ||
| 699 | stamp.tm_year -= 1900; | ||
| 700 | offset = 2; | ||
| 701 | } | ||
| 702 | } | ||
| 703 | stamp.tm_mon = | ||
| 704 | (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; | ||
| 705 | stamp.tm_mday = | ||
| 706 | (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); | ||
| 707 | stamp.tm_hour = | ||
| 708 | (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0'); | ||
| 709 | stamp.tm_min = | ||
| 710 | (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0'); | ||
| 711 | stamp.tm_sec = 0; | ||
| 712 | stamp.tm_isdst = -1; | ||
| 713 | |||
| 714 | days_left = (mktime (&stamp) - time (NULL)) / 86400; | ||
| 715 | snprintf | ||
| 716 | (timestamp, sizeof(timestamp), "%02d/%02d/%04d %02d:%02d", | ||
| 717 | stamp.tm_mon + 1, | ||
| 718 | stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min); | ||
| 719 | |||
| 720 | if (days_left > 0 && days_left <= days_till_exp) { | ||
| 721 | printf ("Certificate expires in %d day(s) (%s).\n", days_left, timestamp); | ||
| 722 | return STATE_WARNING; | ||
| 723 | } | ||
| 724 | if (days_left < 0) { | ||
| 725 | printf ("Certificate expired on %s.\n", timestamp); | ||
| 726 | return STATE_CRITICAL; | ||
| 727 | } | ||
| 728 | |||
| 729 | if (days_left == 0) { | ||
| 730 | printf ("Certificate expires today (%s).\n", timestamp); | ||
| 731 | return STATE_WARNING; | ||
| 732 | } | ||
| 733 | |||
| 734 | printf ("Certificate will expire on %s.\n", timestamp); | ||
| 735 | |||
| 736 | return STATE_OK; | ||
| 737 | } | ||
| 738 | # endif /* USE_OPENSSL */ | ||
| 739 | #endif | ||
| 740 | |||
| 741 | int | ||
| 742 | myrecv (void) | ||
| 743 | { | ||
| 744 | int i; | ||
| 745 | |||
| 746 | #ifdef HAVE_SSL | ||
| 747 | if (use_ssl) { | ||
| 748 | i = SSL_read (ssl, buffer, MAXBUF - 1); | ||
| 749 | } | ||
| 750 | else { | ||
| 751 | #endif | ||
| 752 | i = read (sd, buffer, MAXBUF - 1); | ||
| 753 | #ifdef HAVE_SSL | ||
| 754 | } | ||
| 755 | #endif | ||
| 756 | return i; | ||
| 757 | } | ||
| 758 | |||
| 759 | int | 590 | int |
| 760 | my_close (void) | 591 | my_close (void) |
| 761 | { | 592 | { |
| 762 | #ifdef HAVE_SSL | 593 | #ifdef HAVE_SSL |
| 763 | if (use_ssl == TRUE && ssl_established == TRUE) { | 594 | np_net_ssl_cleanup(); |
| 764 | SSL_shutdown (ssl); | ||
| 765 | SSL_free (ssl); | ||
| 766 | SSL_CTX_free (ctx); | ||
| 767 | return 0; | ||
| 768 | } | ||
| 769 | else { | ||
| 770 | #endif | ||
| 771 | return close(sd); | ||
| 772 | #ifdef HAVE_SSL | ||
| 773 | } | ||
| 774 | #endif | 595 | #endif |
| 596 | return close(sd); | ||
| 775 | } | 597 | } |
