rpms/nagios-plugins/F-7 check_smtp.recvline.diff.2, NONE, 1.1 nagios-plugins.spec, 1.23, 1.24

Michael Patrick McGrath (mmcgrath) fedora-extras-commits at redhat.com
Tue Aug 7 16:18:44 UTC 2007


Author: mmcgrath

Update of /cvs/extras/rpms/nagios-plugins/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv15630/F-7

Modified Files:
	nagios-plugins.spec 
Added Files:
	check_smtp.recvline.diff.2 
Log Message:
fix for #251049


--- NEW FILE check_smtp.recvline.diff.2 ---
Index: check_smtp.c
===================================================================
--- check_smtp.c	(revision 1769)
+++ check_smtp.c	(working copy)
@@ -40,6 +40,8 @@
 const char *copyright = "2000-2006";
 const char *email = "nagiosplug-devel at lists.sourceforge.net";
 
+#include <ctype.h>
+
 #include "common.h"
 #include "netutils.h"
 #include "utils.h"
@@ -74,6 +76,8 @@
 int validate_arguments (void);
 void print_help (void);
 void print_usage (void);
+int recvline(char *, size_t);
+int recvlines(char *, size_t);
 int my_close(void);
 
 #include "regex.h"
@@ -115,7 +119,6 @@
 enum {
   TCP_PROTOCOL = 1,
   UDP_PROTOCOL = 2,
-  MAXBUF = 1024
 };
 
 /* written by lauri alanko */
@@ -221,7 +224,7 @@
 
 		/* watch for the SMTP connection string and */
 		/* return a WARNING status if we couldn't read any data */
-		if (recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0) == -1) {
+		if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) {
 			printf (_("recv() failed\n"));
 			result = STATE_WARNING;
 		}
@@ -245,11 +248,10 @@
 		send(sd, helocmd, strlen(helocmd), 0);
 
 		/* allow for response to helo command to reach us */
-		if(read (sd, buffer, MAXBUF - 1) < 0){
+		if (recvlines(buffer, MAX_INPUT_BUFFER) <= 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;
@@ -267,7 +269,7 @@
 		  /* send the STARTTLS command */
 		  send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0);
 
-		  recv(sd,buffer, MAX_INPUT_BUFFER-1, 0); /* wait for it */
+		  recvlines(buffer, MAX_INPUT_BUFFER); /* wait for it */
 		  if (!strstr (buffer, server_expect)) {
 		    printf (_("Server does not support STARTTLS\n"));
 		    send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0);
@@ -301,13 +303,12 @@
 		}
 		if (verbose)
 			printf(_("sent %s"), helocmd);
-		if ((n = my_recv(buffer, MAX_INPUT_BUFFER - 1)) <= 0) {
+		if ((n = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) {
 			printf("%s\n", _("SMTP UNKNOWN - Cannot read EHLO response via TLS."));
 			my_close();
 			return STATE_UNKNOWN;
 		}
 		if (verbose) {
-			buffer[n] = '\0';
 			printf("%s", buffer);
 		}
 
@@ -336,16 +337,14 @@
 		 */
 		if (smtp_use_dummycmd) {
 		  my_send(cmd_str, strlen(cmd_str));
-		  my_recv(buffer, MAX_INPUT_BUFFER-1);
-		  if (verbose) 
+		  if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose)
 		    printf("%s", buffer);
 		}
 
 		while (n < ncommands) {
 			asprintf (&cmd_str, "%s%s", commands[n], "\r\n");
 			my_send(cmd_str, strlen(cmd_str));
-			my_recv(buffer, MAX_INPUT_BUFFER-1);
-			if (verbose) 
+			if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose)
 				printf("%s", buffer);
 			strip (buffer);
 			if (n < nresponses) {
@@ -394,12 +393,11 @@
 					if (verbose)
 						printf (_("sent %s\n"), "AUTH LOGIN");
 
-					if((ret = my_recv(buffer, MAXBUF - 1)) < 0){
+					if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) {
 						asprintf(&error_msg, _("recv() failed after AUTH LOGIN, "));
 						result = STATE_WARNING;
 						break;
 					}
-					buffer[ret] = 0;
 					if (verbose)
 						printf (_("received %s\n"), buffer);
 
@@ -416,12 +414,11 @@
 					if (verbose)
 						printf (_("sent %s\n"), abuf);
 
-					if ((ret = my_recv(buffer, MAX_INPUT_BUFFER-1)) == -1) {
+					if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) {
 						result = STATE_CRITICAL;
 						asprintf(&error_msg, _("recv() failed after sending authuser, "));
 						break;
 					}
-					buffer[ret] = 0;
 					if (verbose) {
 						printf (_("received %s\n"), buffer);
 					}
@@ -437,12 +434,11 @@
 					if (verbose) {
 						printf (_("sent %s\n"), abuf);
 					}
-					if ((ret = my_recv(buffer, MAX_INPUT_BUFFER-1)) == -1) {
+					if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) {
 						result = STATE_CRITICAL;
 						asprintf(&error_msg, _("recv() failed after sending authpass, "));
 						break;
 					}
-					buffer[ret] = 0;
 					if (verbose) {
 						printf (_("received %s\n"), buffer);
 					}
@@ -700,6 +696,65 @@
 }
 
 
+/*
+ * Receive one line, copy it into buf and nul-terminate it.  Returns the
+ * number of bytes written to buf (excluding the '\0') or 0 on EOF or <0 on
+ * error.
+ *
+ * TODO: Reading one byte at a time is very inefficient.  Replace this by a
+ * function which buffers the data, move that to netutils.c and change
+ * check_smtp and other plugins to use that.  Also, remove (\r)\n.
+ */
+int
+recvline(char *buf, size_t bufsize)
+{
+	int result;
+	unsigned i;
+
+	for (i = result = 0; i < bufsize - 1; i++) {
+		if ((result = my_recv(&buf[i], 1)) != 1)
+			break;
+		if (buf[i] == '\n') {
+			buf[++i] = '\0';
+			return i;
+		}
+	}
+	return (result == 1 || i == 0) ? -2 : result;	/* -2 if out of space */
+}
+
+
+/*
+ * Receive one or more lines, copy them into buf and nul-terminate it.  Returns
+ * the number of bytes written to buf (excluding the '\0') or 0 on EOF or <0 on
+ * error.  Works for all protocols which format multiline replies as follows:
+ *
+ * ``The format for multiline replies requires that every line, except the last,
+ * begin with the reply code, followed immediately by a hyphen, `-' (also known
+ * as minus), followed by text.  The last line will begin with the reply code,
+ * followed immediately by <SP>, optionally some text, and <CRLF>.  As noted
+ * above, servers SHOULD send the <SP> if subsequent text is not sent, but
+ * clients MUST be prepared for it to be omitted.'' (RFC 2821, 4.2.1)
+ *
+ * TODO: Move this to netutils.c.  Also, remove \r and possibly the final \n.
+ */
+int
+recvlines(char *buf, size_t bufsize)
+{
+	int result;
+	unsigned i;
+
+	for (i = 0; /* forever */; i += result)
+		if (!((result = recvline(buf + i, bufsize - i)) > 3 &&
+		    isdigit(buf[i]) &&
+		    isdigit(buf[i + 1]) &&
+		    isdigit(buf[i + 2]) &&
+		    buf[i + 3] == '-'))
+			break;
+
+	return (result <= 0) ? result : result + (int)i;
+}
+
+
 int 
 my_close (void)
 {


Index: nagios-plugins.spec
===================================================================
RCS file: /cvs/extras/rpms/nagios-plugins/F-7/nagios-plugins.spec,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- nagios-plugins.spec	14 Apr 2007 18:15:28 -0000	1.23
+++ nagios-plugins.spec	7 Aug 2007 16:18:11 -0000	1.24
@@ -1,6 +1,6 @@
 Name: nagios-plugins
 Version: 1.4.8
-Release: 1%{?dist}
+Release: 2%{?dist}
 Summary: Host/service/network monitoring program plugins for Nagios
 
 Group: Applications/System
@@ -13,6 +13,7 @@
 Patch2: nagios-plugins-1.4.3-ntpd.patch
 Patch3: nagios-plugins-1.4.4-check_ide_smart.patch
 Patch4: nagios-plugins-1.4.4-linux_raid.patch
+Patch5: check_smtp.recvline.diff.2
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 BuildRequires: openldap-devel
@@ -507,6 +508,7 @@
 %patch2 -p0
 %patch3 -p1
 %patch4 -p0
+%patch5 -p0
 
 %build
 %configure \
@@ -786,6 +788,9 @@
 %{_libdir}/nagios/plugins/utils.sh
 
 %changelog
+* Tue Aug 07 2007 Mike McGrath <mmcgrath at redhat.com> 1.4.8-2
+- Fix for check_smtp - #251049
+
 * Fri Apr 13 2007 Mike McGrath <mmcgrath at redhat.com> 1.4.8-1
 - Upstream released new version
 




More information about the fedora-extras-commits mailing list