hi jeroen,

attached is a new patch.

On Mon, Oct 10, 2005 at 03:13:18AM -0400, sean finney wrote:
> > Anyway, it doesn't work yet over here completely. I get a segmentation fault
> > in the call to SSL_CTX_free(ctx).
> 
> sounds like some error checking isn't catching the ssl connection not
> being properly established.

there was a double SSL_something_free in there if it couldn't establish
an ssl connection, and other SSL_*_free calls that weren't necessarily
properly checking to see if they should even be called.  the latest
patch fixes this.

> > Feel free to use mail.wolffelaar.nl as test SMTP server as much as you like,
> > by the way. It's default sarge exim4 with TLS enabled, otherwise nothing
> > really special that should be relevant for this check.
> 
> cool, thanks.  i suspect that it actually is relevant though, as i see
> something later on about gnutls, and istr reading another bug report
> about openssl extensions causing problems in non-openssl environments.
> don't know it well enough to know whether or not that could be the
> case here though, i'll look into it.

r'ing tfm on SSL_CTX_new, i found the following change seems to have
fixed the gnutls issue:

-  meth = SSLv2_client_method ();
+  meth = SSLv23_client_method ();

> i'll put some more error checking in there.  out of curiosity though,
> how can calling gethostname set the hostname?

now added.



        sean

-- 
#! /bin/sh /usr/share/dpatch/dpatch-run
## 16_check_smtp_protocolfix.dpatch by  <[EMAIL PROTECTED]>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.

@DPATCH@
diff -urNad nagios-plugins~/plugins/check_smtp.c 
nagios-plugins/plugins/check_smtp.c
--- nagios-plugins~/plugins/check_smtp.c        2005-10-10 09:52:49.000000000 
+0200
+++ nagios-plugins/plugins/check_smtp.c 2005-10-10 09:54:53.000000000 +0200
@@ -59,10 +59,17 @@
 enum {
        SMTP_PORT       = 25
 };
-const char *SMTP_EXPECT = "220";
-const char *SMTP_HELO = "HELO ";
-const char *SMTP_QUIT  = "QUIT\r\n";
-const char *SMTP_STARTTLS = "STARTTLS\r\n";
+#define SMTP_EXPECT "220"
+#define SMTP_HELO "HELO "
+#define SMTP_EHLO "EHLO "
+#define SMTP_QUIT "QUIT\r\n"
+#define SMTP_STARTTLS "STARTTLS\r\n"
+
+#ifndef HOST_MAX_BYTES
+#define HOST_MAX_BYTES 255
+#endif
+
+#define EHLO_SUPPORTS_STARTTLS 1
 
 int process_arguments (int, char **);
 int validate_arguments (void);
@@ -101,6 +108,9 @@
 int check_critical_time = FALSE;
 int verbose = 0;
 int use_ssl = FALSE;
+short use_ehlo = FALSE;
+short ssl_established = TRUE;
+char *localhostname = NULL;
 int sd;
 char buffer[MAX_INPUT_BUFFER];
 enum {
@@ -112,7 +122,7 @@
 int
 main (int argc, char **argv)
 {
-
+       short supports_tls=FALSE;
        int n = 0;
        double elapsed_time;
        long microsec;
@@ -120,6 +130,7 @@
        char *cmd_str = NULL;
        char *helocmd = NULL;
        struct timeval tv;
+       struct hostent *hp;
 
        setlocale (LC_ALL, "");
        bindtextdomain (PACKAGE, LOCALEDIR);
@@ -129,12 +140,26 @@
                usage4 (_("Could not parse arguments"));
 
        /* initialize the HELO command with the localhostname */
-#ifndef HOST_MAX_BYTES
-#define HOST_MAX_BYTES 255
-#endif
-       helocmd = malloc (HOST_MAX_BYTES);
-       gethostname(helocmd, HOST_MAX_BYTES);
-       asprintf (&helocmd, "%s%s%s", SMTP_HELO, helocmd, "\r\n");
+       if(! localhostname){
+               localhostname = malloc (HOST_MAX_BYTES);
+               if(!localhostname){
+                       printf(_("malloc() failed!\n"));
+                       return STATE_CRITICAL;
+               }
+               if(gethostname(localhostname, HOST_MAX_BYTES)){
+                       printf(_("gethostname() failed!\n"));
+                       return STATE_CRITICAL;
+               }
+               hp = gethostbyname(localhostname);
+               if(!hp) helocmd = localhostname;
+               else helocmd = hp->h_name;
+       } else {
+               helocmd = localhostname;
+       }
+       if(use_ehlo)
+               asprintf (&helocmd, "%s%s%s", SMTP_EHLO, helocmd, "\r\n");
+       else
+               asprintf (&helocmd, "%s%s%s", SMTP_HELO, helocmd, "\r\n");
 
        /* initialize the MAIL command with optional FROM command  */
        asprintf (&cmd_str, "%sFROM: %s%s", mail_command, from_arg, "\r\n");
@@ -178,11 +203,26 @@
                        }
                }
 
-               /* send the HELO command */
+               /* send the HELO/EHLO command */
                send(sd, helocmd, strlen(helocmd), 0);
 
                /* allow for response to helo command to reach us */
-               read (sd, buffer, MAXBUF - 1);
+               if(read (sd, buffer, MAXBUF - 1) < 0){
+                       printf (_("recv() failed\n"));
+                       return STATE_WARNING;
+               } else if(use_ehlo){
+                       buffer[MAXBUF-1]='\0';
+                       if(strstr(buffer, "250 STARTTLS") != NULL ||
+                          strstr(buffer, "250-STARTTLS") != NULL){
+                               supports_tls=TRUE;
+                       }
+               }
+
+               if(use_ssl && ! supports_tls){
+                       printf(_("WARNING - TLS not supported by server\n"));
+                       send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0);
+                       return STATE_WARNING;
+               }
 
 #ifdef HAVE_SSL
                if(use_ssl) {
@@ -192,11 +232,14 @@
                  recv(sd,buffer, MAX_INPUT_BUFFER-1, 0); /* wait for it */
                  if (!strstr (buffer, server_expect)) {
                    printf (_("Server does not support STARTTLS\n"));
+                   send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0);
                    return STATE_UNKNOWN;
                  }
                  if(connect_STARTTLS() != OK) {
                    printf (_("CRITICAL - Cannot create SSL context.\n"));
                    return STATE_CRITICAL;
+                 } else {
+                       ssl_established = TRUE;
                  }
                  if ( check_cert ) {
                    if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) 
{
@@ -333,6 +376,7 @@
                {"timeout", required_argument, 0, 't'},
                {"port", required_argument, 0, 'p'},
                {"from", required_argument, 0, 'f'},
+               {"fqdn", required_argument, 0, 'F'},
                {"command", required_argument, 0, 'C'},
                {"response", required_argument, 0, 'R'},
                {"nocommand", required_argument, 0, 'n'},
@@ -359,7 +403,7 @@
        }
 
        while (1) {
-               c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:",
+               c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:F:",
                                 longopts, &option);
 
                if (c == -1 || c == EOF)
@@ -380,6 +424,10 @@
                        else
                                usage4 (_("Port must be a positive integer"));
                        break;
+               case 'F':
+               /* localhostname */
+                       localhostname = strdup(optarg);
+                       break;
                case 'f':                                                       
                /* from argument */
                        from_arg = optarg;
                        smtp_use_dummycmd = 1;
@@ -439,6 +487,7 @@
                case 'S':
                /* starttls */
                        use_ssl = TRUE;
+                       use_ehlo = TRUE;
                        break;
                case 'D':
                /* Check SSL cert validity */
@@ -581,7 +630,7 @@
 
   /* Initialize SSL context */
   SSLeay_add_ssl_algorithms ();
-  meth = SSLv2_client_method ();
+  meth = SSLv23_client_method ();
   SSL_load_error_strings ();
   if ((ctx = SSL_CTX_new (meth)) == NULL)
     {
@@ -602,11 +651,6 @@
     {
       printf (_("CRITICAL - Cannot initiate SSL handshake.\n"));
     }
-  /* this causes a seg faul
-     not sure why, being sloppy
-     and commenting it out */
-  /*  SSL_free (ssl); */
-  SSL_CTX_free(ctx);
   my_close();
   
   return STATE_CRITICAL;
@@ -708,7 +752,7 @@
 my_close (void)
 {
 #ifdef HAVE_SSL
-  if (use_ssl == TRUE) {
+  if (use_ssl == TRUE && ssl_established == TRUE) {
     SSL_shutdown (ssl);
     SSL_free (ssl);
     SSL_CTX_free (ctx);

Attachment: signature.asc
Description: Digital signature

Reply via email to