tags 285554 patch
thanks

On Sun, Oct 09, 2005 at 11:21:01PM +0200, Jeroen van Wolffelaar wrote:
> > okay, so then then that's two problems, as even though the starttls
> > was refused to the first error, it blindly kept on going regardless of
> > the 5xx error.
> 
> Yup, and the EHLO thingy being the primary one -- if all things go right, the
> second one doesn't matter (but yeah, should still be fixed -- and result in a
> nagios check failure).

okay, i've attached a patch which should work around this.  i've
verified it on my end, but i'd appreciate if you could try it out as
well and point out any issues it may have.  it does the following:

- send ehlo if starttls is required
- exit with STATE_WARNING if STARTTLS isn't listed as a server capability
- send QUIT commands in all premature return points.
- provide a -F/--fqdn option to pass to helo/ehlo
- if not specified, use a gethostbyname(hostname) method similar to what you
  suggested for the helo/ehlo.

i'm still not quite happy with that last one, as gethostbyname isn't
defined by posix/sus/iso, but it's being used elsewhere in the
code base already, so oh well.



        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 00:55:39.000000000 
+0200
+++ nagios-plugins/plugins/check_smtp.c 2005-10-10 01:05:31.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,8 @@
 int check_critical_time = FALSE;
 int verbose = 0;
 int use_ssl = FALSE;
+short use_ehlo = FALSE;
+char *localhostname = NULL;
 int sd;
 char buffer[MAX_INPUT_BUFFER];
 enum {
@@ -112,14 +121,16 @@
 int
 main (int argc, char **argv)
 {
-
+       short supports_tls=FALSE;
        int n = 0;
        double elapsed_time;
        long microsec;
-       int result = STATE_UNKNOWN;
+       int amt_read=0, result = STATE_UNKNOWN;
        char *cmd_str = NULL;
        char *helocmd = NULL;
+       char *ehlo_resp = NULL;
        struct timeval tv;
+       struct hostent *hp;
 
        setlocale (LC_ALL, "");
        bindtextdomain (PACKAGE, LOCALEDIR);
@@ -129,12 +140,19 @@
                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);
+               gethostname(localhostname, HOST_MAX_BYTES);
+               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 +196,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,6 +225,7 @@
                  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) {
@@ -333,6 +367,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 +394,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 +415,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 +478,7 @@
                case 'S':
                /* starttls */
                        use_ssl = TRUE;
+                       use_ehlo = TRUE;
                        break;
                case 'D':
                /* Check SSL cert validity */

Attachment: signature.asc
Description: Digital signature

Reply via email to