From 65282c7685ca01c57d94d3df93c2f95d5b945e57 Mon Sep 17 00:00:00 2001 From: "M. Sean Finney" Date: Wed, 19 Oct 2005 12:59:55 +0000 Subject: [PATCH] - initial attempt at consolidating ssl-related code into netutils.{c,h} - added some #ifdefs to common.h and netutils.h to prevent multiple inclusions (as netlibs now includes common.h) - all ssl plugins (tcp/http/smtp) compile cleanly against gnutls, though certificate checking still needs to be done. - modified configure script so you can also explicitly say "without-gnutls" too (otherwise if you disable openssl you have no way of disabling gnutls too) git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1255 f882894a-f735-0410-b71e-b25c423dba1c --- configure.in | 2 +- plugins-root/Makefile.am | 4 +- plugins/Makefile.am | 10 +-- plugins/check_http.c | 17 +++-- plugins/check_smtp.c | 10 ++- plugins/check_tcp.c | 145 ++++++++------------------------------- plugins/common.h | 28 ++++++++ plugins/netutils.c | 48 +++++++++++++ plugins/netutils.h | 15 ++++ 9 files changed, 151 insertions(+), 128 deletions(-) diff --git a/configure.in b/configure.in index 7ae486c..383f178 100644 --- a/configure.in +++ b/configure.in @@ -488,7 +488,7 @@ fi dnl check for gnutls if openssl isn't found (or is disabled) FOUNDGNUTLS="no" -if ! test "$FOUNDSSL" = "yes"; then +if ! test "$FOUNDSSL" = "yes" && ! test "$with_gnutls" = "no"; then if test "$GNUTLS" = ""; then CPPFLAGS="$CPPFLAGS -I$GNUTLS" elif ! test "$LIBGNUTLS_CONFIG" = ""; then diff --git a/plugins-root/Makefile.am b/plugins-root/Makefile.am index 81679d5..54e91b0 100644 --- a/plugins-root/Makefile.am +++ b/plugins-root/Makefile.am @@ -2,12 +2,12 @@ VPATH = $(top_srcdir) $(top_srcdir)/lib $(top_srcdir)/plugins $(top_srcdir)/plugins/t -INCLUDES = -I.. -I$(top_srcdir)/lib -I$(top_srcdir)/intl -I$(top_srcdir)/plugins +INCLUDES = -I.. -I$(top_srcdir)/lib -I$(top_srcdir)/intl -I$(top_srcdir)/plugins @SSLINCLUDE@ datadir = @datadir@ localedir = $(datadir)/locale DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ -LIBS = @LIBINTL@ @LIBS@ @SSLINCLUDE@ +LIBS = @LIBINTL@ @LIBS@ @SSLLIBS@ EXTRA_PROGRAMS = check_dhcp check_icmp diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 6b7de7e..beefb32 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -2,12 +2,12 @@ VPATH = $(top_srcdir) $(top_srcdir)/lib $(top_srcdir)/plugins $(top_srcdir)/plugins/t -INCLUDES = -I.. -I$(top_srcdir)/lib -I$(top_srcdir)/intl @LDAPINCLUDE@ @PGINCLUDE@ +INCLUDES = -I.. -I$(top_srcdir)/lib -I$(top_srcdir)/intl @LDAPINCLUDE@ @PGINCLUDE@ @SSLINCLUDE@ datadir = @datadir@ localedir = $(datadir)/locale DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ -LIBS = @LIBINTL@ @LIBS@ @SSLINCLUDE@ +LIBS = @LIBINTL@ @LIBS@ @SSLLIBS@ MATHLIBS = @MATHLIBS@ libexec_PROGRAMS = check_disk check_dummy check_http check_load \ @@ -51,7 +51,7 @@ check_dns_LDADD = $(NETLIBS) popen.o check_dummy_LDADD = $(BASEOBJS) check_fping_LDADD = $(NETLIBS) popen.o check_game_LDADD = $(BASEOBJS) popen.o -check_http_LDADD = $(NETLIBS) $(SSLLIBS) +check_http_LDADD = $(NETLIBS) check_hpjd_LDADD = $(NETLIBS) popen.o check_ldap_LDADD = $(NETLIBS) $(LDAPLIBS) check_load_LDADD = $(BASEOBJS) popen.o @@ -68,10 +68,10 @@ check_procs_LDADD = $(BASEOBJS) popen.o check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) check_real_LDADD = $(NETLIBS) check_snmp_LDADD = $(BASEOBJS) popen.o -check_smtp_LDADD = $(NETLIBS) $(SSLLIBS) +check_smtp_LDADD = $(NETLIBS) check_ssh_LDADD = $(NETLIBS) check_swap_LDADD = $(MATHLIBS) $(BASEOBJS) popen.o -check_tcp_LDADD = $(NETLIBS) $(SSLLIBS) +check_tcp_LDADD = $(NETLIBS) check_time_LDADD = $(NETLIBS) check_udp_LDADD = $(NETLIBS) check_ups_LDADD = $(NETLIBS) diff --git a/plugins/check_http.c b/plugins/check_http.c index 35b2cca..d47f5ce 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c @@ -65,7 +65,9 @@ SSL_CTX *ctx; SSL *ssl; X509 *server_cert; int connect_SSL (void); +# ifdef USE_OPENSSL int check_certificate (X509 **); +# endif #endif int no_body = FALSE; int maximum_age = -1; @@ -166,7 +168,7 @@ main (int argc, char **argv) (void) alarm (socket_timeout); gettimeofday (&tv, NULL); -#ifdef HAVE_SSL +#ifdef USE_OPENSSL if (use_ssl && check_cert == TRUE) { if (connect_SSL () != OK) die (STATE_CRITICAL, _("HTTP CRITICAL - Could not make SSL connection\n")); @@ -305,7 +307,7 @@ process_arguments (int argc, char **argv) server_port = HTTPS_PORT; break; case 'C': /* Check SSL cert validity */ -#ifdef HAVE_SSL +#ifdef USE_OPENSSL if (!is_intnonneg (optarg)) usage2 (_("Invalid certificate expiration period"), optarg); else { @@ -799,10 +801,11 @@ check_http (void) if (connect_SSL () != OK) { die (STATE_CRITICAL, _("Unable to open TCP socket\n")); } - +#ifdef USE_OPENSSL if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { X509_free (server_cert); } +#endif else { printf (_("CRITICAL - Cannot retrieve server certificate.\n")); return STATE_CRITICAL; @@ -857,7 +860,9 @@ check_http (void) #ifdef HAVE_SSL if (use_ssl == TRUE) { if (SSL_write (ssl, buf, (int)strlen(buf)) == -1) { +# ifdef USE_OPENSSL ERR_print_errors_fp (stderr); +# endif return STATE_CRITICAL; } } @@ -1278,11 +1283,15 @@ int connect_SSL (void) if (my_tcp_connect (server_address, server_port, &sd) == STATE_OK) { /* Do the SSL handshake */ if ((ssl = SSL_new (ctx)) != NULL) { +#ifdef USE_OPENSSL SSL_set_cipher_list(ssl, "ALL"); +#endif SSL_set_fd (ssl, sd); if (SSL_connect (ssl) != -1) return OK; +#ifdef USE_OPENSSL ERR_print_errors_fp (stderr); +#endif } else { printf (_("CRITICAL - Cannot initiate SSL handshake.\n")); @@ -1299,7 +1308,7 @@ int connect_SSL (void) -#ifdef HAVE_SSL +#ifdef USE_OPENSSL int check_certificate (X509 ** certificate) { diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index 3bb6a32..19e9aea 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c @@ -53,7 +53,9 @@ SSL_CTX *ctx; SSL *ssl; X509 *server_cert; int connect_STARTTLS (void); +# ifdef USE_OPENSSL int check_certificate (X509 **); +# endif #endif enum { @@ -241,6 +243,7 @@ main (int argc, char **argv) } else { ssl_established = TRUE; } +# ifdef USE_OPENSSL if ( check_cert ) { if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { result = check_certificate (&server_cert); @@ -254,6 +257,7 @@ main (int argc, char **argv) my_close(); return result; } +# endif /* USE_OPENSSL */ } #endif @@ -491,7 +495,7 @@ process_arguments (int argc, char **argv) break; case 'D': /* Check SSL cert validity */ -#ifdef HAVE_SSL +#ifdef USE_OPENSSL if (!is_intnonneg (optarg)) usage2 ("Invalid certificate expiration period",optarg); days_till_exp = atoi (optarg); @@ -645,7 +649,9 @@ connect_STARTTLS (void) I look for success instead (1) */ if (SSL_connect (ssl) == 1) return OK; +# ifdef USE_OPENSSL ERR_print_errors_fp (stderr); +# endif } else { @@ -656,6 +662,7 @@ connect_STARTTLS (void) return STATE_CRITICAL; } +# ifdef USE_OPENSSL int check_certificate (X509 ** certificate) { @@ -728,6 +735,7 @@ check_certificate (X509 ** certificate) return STATE_OK; } +# endif /* USE_OPENSSL */ #endif int diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 157588f..3ffa4cd 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c @@ -28,42 +28,19 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #include "netutils.h" #include "utils.h" -#ifdef HAVE_GNUTLS_OPENSSL_H -# include -#else -# ifdef HAVE_SSL_H -# include -# include -# include -# include -# include -# include -# else -# ifdef HAVE_OPENSSL_SSL_H -# include -# include -# include -# include -# include -# include -# endif -# endif -#endif - #ifdef HAVE_SSL static int check_cert = FALSE; static int days_till_exp; static char *randbuff = ""; -static SSL_CTX *ctx; -static SSL *ssl; static X509 *server_cert; -static int connect_SSL (void); # ifdef USE_OPENSSL static int check_certificate (X509 **); # endif /* USE_OPENSSL */ -# define my_recv(buf, len) ((flags & FLAG_SSL) ? SSL_read(ssl, buf, len) : read(sd, buf, len)) +# define my_recv(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) +# define my_send(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) #else # define my_recv(buf, len) read(sd, buf, len) +# define my_send(buf, len) send(sd, buf, len, 0) #endif @@ -233,11 +210,21 @@ main (int argc, char **argv) /* try to connect to the host at the given port number */ gettimeofday (&tv, NULL); + + result = np_net_connect (server_address, server_port, &sd, PROTOCOL); + if (result == STATE_CRITICAL) return STATE_CRITICAL; + #ifdef HAVE_SSL - if (flags & FLAG_SSL && check_cert == TRUE) { - if (connect_SSL () != OK) + if (flags & FLAG_SSL){ + result = np_net_ssl_init(sd); + if(result != STATE_OK) return result; + /* XXX does np_net_ssl take care of printing an error? die (STATE_CRITICAL,_("CRITICAL - Could not make SSL connection\n")); + */ + } # ifdef USE_OPENSSL /* XXX gnutls does cert checking differently */ + /* + if (flags & FLAG_SSL && check_cert == TRUE) { if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { result = check_certificate (&server_cert); X509_free(server_cert); @@ -246,30 +233,21 @@ main (int argc, char **argv) printf(_("CRITICAL - Cannot retrieve server certificate.\n")); result = STATE_CRITICAL; } + } + */ # endif /* USE_OPENSSL */ +#endif - SSL_shutdown (ssl); - SSL_free (ssl); - SSL_CTX_free (ctx); - close (sd); + if(result != STATE_OK){ +#ifdef HAVE_SSL + np_net_ssl_cleanup(); +#endif + if(sd) close(sd); return result; } - else if (flags & FLAG_SSL) - result = connect_SSL (); - else -#endif - result = np_net_connect (server_address, server_port, &sd, PROTOCOL); - - if (result == STATE_CRITICAL) - return STATE_CRITICAL; if (server_send != NULL) { /* Something to send? */ -#ifdef HAVE_SSL - if (flags & FLAG_SSL) - SSL_write(ssl, server_send, (int)strlen(server_send)); - else -#endif - send (sd, server_send, strlen(server_send), 0); + my_send(server_send, strlen(server_send)); } if (delay > 0) { @@ -332,21 +310,12 @@ main (int argc, char **argv) } if (server_quit != NULL) { -#ifdef HAVE_SSL - if (flags & FLAG_SSL) { - SSL_write (ssl, server_quit, (int)strlen(server_quit)); - SSL_shutdown (ssl); - SSL_free (ssl); - SSL_CTX_free (ctx); - } - else -#endif - send (sd, server_quit, strlen (server_quit), 0); + my_send(server_quit, strlen(server_quit)); } - - /* close the connection */ - if (sd) - close (sd); +#ifdef HAVE_SSL + np_net_ssl_cleanup(); +#endif + if (sd) close (sd); microsec = deltime (tv); elapsed_time = (double)microsec / 1.0e6; @@ -600,61 +569,7 @@ process_arguments (int argc, char **argv) /* SSL-specific functions */ #ifdef HAVE_SSL -static int -connect_SSL (void) -{ - SSL_METHOD *meth; - - /* Initialize SSL context */ - SSLeay_add_ssl_algorithms (); - meth = SSLv23_client_method (); - SSL_load_error_strings (); - OpenSSL_add_all_algorithms(); - if ((ctx = SSL_CTX_new (meth)) == NULL) - { - printf (_("CRITICAL - Cannot create SSL context.\n")); - return STATE_CRITICAL; - } - - /* Initialize alarm signal handling */ - signal (SIGALRM, socket_timeout_alarm_handler); - - /* Set socket timeout */ - alarm (socket_timeout); - - /* Save start time */ - time (&start_time); - - /* Make TCP connection */ - if (my_tcp_connect (server_address, server_port, &sd) == STATE_OK && was_refused == FALSE) - { - /* Do the SSL handshake */ - if ((ssl = SSL_new (ctx)) != NULL) - { - SSL_set_fd (ssl, sd); - if (SSL_connect(ssl) == 1) - return OK; - /* ERR_print_errors_fp (stderr); */ - printf (_("CRITICAL - Cannot make SSL connection ")); -#ifdef USE_OPENSSL /* XXX */ - ERR_print_errors_fp (stdout); -#endif /* USE_OPENSSL */ - /* printf("\n"); */ - } - else - { - printf (_("CRITICAL - Cannot initiate SSL handshake.\n")); - } - SSL_free (ssl); - } - - SSL_CTX_free (ctx); - close (sd); - - return STATE_CRITICAL; -} - -#ifdef USE_OPENSSL /* XXX */ +# ifdef USE_OPENSSL /* XXX */ static int check_certificate (X509 ** certificate) { diff --git a/plugins/common.h b/plugins/common.h index e10586b..5eac63e 100644 --- a/plugins/common.h +++ b/plugins/common.h @@ -32,6 +32,9 @@ * *****************************************************************************/ +#ifndef _COMMON_H_ +#define _COMMON_H_ + #include "config.h" #ifdef HAVE_FEATURES_H @@ -146,6 +149,29 @@ int snprintf(char *str, size_t size, const char *format, ...); int vsnprintf(char *str, size_t size, const char *format, va_list ap); #endif +/* SSL implementations */ +#ifdef HAVE_GNUTLS_OPENSSL_H +# include +#else +# ifdef HAVE_SSL_H +# include +# include +# include +# include +# include +# include +# else +# ifdef HAVE_OPENSSL_SSL_H +# include +# include +# include +# include +# include +# include +# endif +# endif +#endif + /* * * Standard Values @@ -191,3 +217,5 @@ enum { #ifndef __GNUC__ # define __attribute__(x) /* do nothing */ #endif + +#endif /* _COMMON_H_ */ diff --git a/plugins/netutils.c b/plugins/netutils.c index 9539a7f..e3fbb3a 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c @@ -234,6 +234,54 @@ np_net_connect (const char *host_name, int port, int *sd, int proto) } } +#ifdef HAVE_SSL +static SSL_CTX *c=NULL; +static SSL *s=NULL; + +int np_net_ssl_init (int sd){ + SSL_METHOD *m=NULL; + /* Initialize SSL context */ + SSLeay_add_ssl_algorithms (); + m = SSLv23_client_method (); + SSL_load_error_strings (); + OpenSSL_add_all_algorithms(); + if ((c = SSL_CTX_new (m)) == NULL) { + printf (_("CRITICAL - Cannot create SSL context.\n")); + return STATE_CRITICAL; + } + if ((s = SSL_new (c)) != NULL){ + SSL_set_fd (s, sd); + if (SSL_connect(s) == 1){ + return OK; + } else { + printf (_("CRITICAL - Cannot make SSL connection ")); +#ifdef USE_OPENSSL /* XXX look into ERR_error_string */ + ERR_print_errors_fp (stdout); +#endif /* USE_OPENSSL */ + } + } else { + printf (_("CRITICAL - Cannot initiate SSL handshake.\n")); + } + return STATE_CRITICAL; +} + +void np_net_ssl_cleanup (){ + if(s){ + SSL_shutdown (s); + SSL_free (s); + if(c) SSL_CTX_free (c); + } +} + +int np_net_ssl_write(const void *buf, int num){ + return SSL_write(s, buf, num); +} + +int np_net_ssl_read(void *buf, int num){ + return SSL_read(s, buf, num); +} + +#endif /* HAVE_SSL */ int send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size) diff --git a/plugins/netutils.h b/plugins/netutils.h index 1a52eec..85b5aa9 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h @@ -32,7 +32,11 @@ * ******************************************************************************/ +#ifndef _NETUTILS_H_ +#define _NETUTILS_H_ + #include "config.h" +#include "common.h" #include #include @@ -77,3 +81,14 @@ extern unsigned int socket_timeout; extern int econn_refuse_state; extern int was_refused; extern int address_family; + +/* SSL-Related functionality */ +#ifdef HAVE_SSL +/* maybe this could be merged with the above np_net_connect, via some flags */ +int np_net_ssl_init(int sd); +void np_net_ssl_cleanup(); +int np_net_ssl_write(const void *buf, int num); +int np_net_ssl_read(void *buf, int num); +#endif /* HAVE_SSL */ + +#endif /* _NETUTILS_H_ */ -- 2.30.2