4
0
John C. Frickson 9 жил өмнө
parent
commit
73591ad448

+ 15 - 0
NEWS

@@ -1,5 +1,20 @@
 This file documents the major additions and syntax changes between releases.
 
+2.1.x 2016-xx-xx
+	FIXES
+	check_http: Don't include default Accept header if one is provided
+	check_disk: added "fuse.gvfsd-fuse" to list of fs types to ignore
+	check_http: Fixed non-text chunked-encoded decoding
+	check_http: segmentation fault (FreeBSD)
+	check_dns: Update IF_RECORD to not erase query_found
+	check_http: SSL Certificate check returns 12:00:00AM <local timezone>
+	check_http: -u is misleading. Changed help text
+	check_file_age: does not handle filenames with space
+	check_snmp: units label option outputs the label in the incorrect location
+	plugins-root/check_dhcp.c: fix a potential segfault
+    check_users: not correctly detecting thresholds
+
+
 2.1.3 2016-09-12
 	ENHANCEMENTS
 	SNI support in check_tcp (ddbilik)

+ 3 - 0
THANKS.in

@@ -34,6 +34,7 @@ Ben Timby
 Ben Whaley
 Benjamin Schmid
 Bernhard Fischer
+Bill Blough
 Bill Kunkel
 Bo Kersey
 Bob Ingraham
@@ -111,6 +112,7 @@ Gerd Mueller
 Gerhard Lausser
 Gianluca Varisco
 Grant Byers
+Greg Bowser
 Guenther Mair
 Gunnar Beutner
 Gunnar Hellekson
@@ -272,6 +274,7 @@ Peter Hoogendijk
 Peter Pramberger
 Phil Dibowitz
 Phil Randal
+Peter (pirtoo)
 Ragnar Hojland Espinosa
 Rainer Duffner
 Ralph Rye

+ 7 - 28
plugins-root/check_dhcp.c

@@ -228,7 +228,6 @@ struct in_addr requested_address;
 
 
 int process_arguments(int, char **);
-int call_getopt(int, char **);
 int validate_arguments(void);
 void print_usage(void);
 void print_help(void);
@@ -1072,30 +1071,9 @@ int get_results(void){
 
 /* process command-line arguments */
 int process_arguments(int argc, char **argv){
-	int c;
-
-	if(argc<1)
-		return ERROR;
-
-	c=0;
-	while((c+=(call_getopt(argc-c,&argv[c])))<argc){
-
-		/*
-		if(is_option(argv[c]))
-			continue;
-		*/
-		}
-
-	return validate_arguments();
-        }
-
-
-
-int call_getopt(int argc, char **argv){
-	int c=0;
-	int i=0;
-
+	int c = 0;
 	int option_index = 0;
+
 	static struct option long_options[] =
 	{
 		{"serverip",       required_argument,0,'s'},
@@ -1110,11 +1088,12 @@ int call_getopt(int argc, char **argv){
 		{0,0,0,0}
 	};
 
+	if(argc<1)
+		return ERROR;
+
 	while(1){
 		c=getopt_long(argc,argv,"+hVvt:s:r:t:i:m:u",long_options,&option_index);
 
-		i++;
-
 		if(c==-1||c==EOF||c==1)
 			break;
 
@@ -1123,7 +1102,6 @@ int call_getopt(int argc, char **argv){
 		case 'r':
 		case 't':
 		case 'i':
-			i++;
 			break;
 		default:
 			break;
@@ -1195,7 +1173,8 @@ int call_getopt(int argc, char **argv){
 		        }
 	        }
 
-	return i+1;
+
+	return validate_arguments();
         }
 
 

+ 2 - 0
plugins-scripts/check_file_age.pl

@@ -77,6 +77,8 @@ if (! $opt_f) {
 	exit $ERRORS{'UNKNOWN'};
 }
 
+$opt_f = '"' . $opt_f . '"';
+
 # Check that file(s) exists (can be directory or link)
 $perfdata = "";
 $output = "";

+ 5 - 2
plugins/check_disk.c

@@ -109,6 +109,8 @@ static struct parameter_list *path_select_list = NULL;
 /* Linked list of mounted filesystems. */
 static struct mount_entry *mount_list;
 
+static const char *always_exclude[] = { "iso9600", "fuse.gvfsd-fuse", NULL };
+
 /* For long options that have no equivalent short option, use a
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
@@ -436,7 +438,7 @@ double calculate_percent(uintmax_t value, uintmax_t total) {
 int
 process_arguments (int argc, char **argv)
 {
-  int c, err;
+  int c, err, i;
   struct parameter_list *se;
   struct parameter_list *temp_list = NULL, *previous = NULL;
   struct parameter_list *temp_path_select_list = NULL;
@@ -492,7 +494,8 @@ process_arguments (int argc, char **argv)
   if (argc < 2)
     return ERROR;
 
-  np_add_name(&fs_exclude_list, "iso9660");
+	for (i = 0; always_exclude[i]; ++i)
+		np_add_name(&fs_exclude_list, always_exclude[i]);
 
   for (c = 1; c < argc; c++)
     if (strcmp ("-to", argv[c]) == 0)

+ 2 - 2
plugins/check_dns.c

@@ -32,8 +32,8 @@
       if (verbose) printf(verb_str); \
       temp_buffer = rindex (chld_out.line[i], ' '); \
       addresses[n_addresses++] = check_new_address(temp_buffer); \
-      strncpy(query_found, querytype, sizeof(query_found)); \
-      memset(query_found, '\0', sizeof(query_found));
+      memset(query_found, '\0', sizeof(query_found)); \
+      strncpy(query_found, querytype, sizeof(query_found)); 
 
 const char *progname = "check_dns";
 const char *copyright = "2000-2014";

+ 43 - 45
plugins/check_http.c

@@ -110,8 +110,9 @@ thresholds *thlds;
 char user_auth[MAX_INPUT_BUFFER] = "";
 char proxy_auth[MAX_INPUT_BUFFER] = "";
 int display_html = FALSE;
-char **http_opt_headers;
+char **http_opt_headers = NULL;
 int http_opt_headers_count = 0;
+int have_accept = FALSE;
 int onredirect = STATE_OK;
 int followsticky = STICKY_NONE;
 int use_ssl = FALSE;
@@ -213,6 +214,7 @@ process_arguments (int argc, char **argv)
     {"method", required_argument, 0, 'j'},
     {"IP-address", required_argument, 0, 'I'},
     {"url", required_argument, 0, 'u'},
+    {"uri", required_argument, 0, 'u'},
     {"port", required_argument, 0, 'p'},
     {"authorization", required_argument, 0, 'a'},
     {"proxy-authorization", required_argument, 0, 'b'},
@@ -286,12 +288,13 @@ process_arguments (int argc, char **argv)
       xasprintf (&user_agent, "User-Agent: %s", optarg);
       break;
     case 'k': /* Additional headers */
-      if (http_opt_headers_count == 0)
+/*      if (http_opt_headers_count == 0)
         http_opt_headers = malloc (sizeof (char *) * (++http_opt_headers_count));
-      else
-        http_opt_headers = realloc (http_opt_headers, sizeof (char *) * (++http_opt_headers_count));
+      else */
+      http_opt_headers = realloc (http_opt_headers, sizeof(char *) * (++http_opt_headers_count));
       http_opt_headers[http_opt_headers_count - 1] = optarg;
-      /* xasprintf (&http_opt_headers, "%s", optarg); */
+      if (!strncmp(optarg, "Accept:", 7))
+        have_accept = TRUE;
       break;
     case 'L': /* show html link */
       display_html = TRUE;
@@ -684,53 +687,45 @@ expected_statuscode (const char *reply, const char *statuscodes)
   return result;
 }
 
-char *
-decode_chunked_page (const char *raw, char *dst)
+int chunk_header(char **buf)
 {
-  unsigned long int chunksize;
-  char *raw_pos = (char *)raw;
-  char *dst_pos = (char *)dst;
-  const char *raw_end = raw + strlen(raw);
+  int lth = strtol(*buf, buf, 16);
 
-  while (chunksize = strtoul(raw_pos, NULL, 16)) {
-    if (chunksize <= 0) {
-      die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse chunked body, invalid chunk size\n"));
-    }
+  if (lth <= 0)
+	 return lth;
 
-    // soak up the optional chunk params (which we will ignore)
-    while (*raw_pos && *raw_pos != '\r' && *raw_pos != '\n') raw_pos++;
+  while (**buf != '\r' && **buf != '\n')
+    ++*buf;
 
-    // soak up the leading CRLF
-    if (*raw_pos && *raw_pos == '\r' && *(++raw_pos) && *raw_pos == '\n') {
-      raw_pos++;
-    }
-    else {
-      die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse chunked body, invalid format\n"));
-    }
+  // soak up the leading CRLF
+  if (**buf && **buf == '\r' && *(++*buf) && **buf == '\n')
+    ++*buf;
+  else
+    die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse chunked body, invalid format\n"));
 
-    // move chunk from raw into dst, only if we can fit within the buffer
-    if (*raw_pos && *dst_pos && (raw_pos + chunksize) < raw_end ) {
-      strncpy(dst_pos, raw_pos, chunksize);
-    }
-    else {
-      die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse chunked body, too large for destination\n"));
-    }
+  return lth;
+}
 
+char *
+decode_chunked_page (const char *raw, char *dst)
+{
+  int  chunksize;
+  char *raw_pos = (char*)raw;
+  char *dst_pos = (char*)dst;
+
+  for (;;) {
+    if ((chunksize = chunk_header(&raw_pos)) == 0)
+      break;
+    if (chunksize < 0)
+      die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse chunked body, invalid chunk size\n"));
+
+    memmove(dst_pos, raw_pos, chunksize);
     raw_pos += chunksize;
     dst_pos += chunksize;
+    *dst_pos = '\0';
 
-    // soak up the ending CRLF
-    if (*raw_pos && *raw_pos == '\r' && *(++raw_pos) && *raw_pos == '\n') {
+    if (*raw_pos && *raw_pos == '\r' && *(++raw_pos) && *raw_pos == '\n')
       raw_pos++;
-    }
-    else {
-      die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse chunked body, invalid format\n"));
-    }
-  }
-
-  if (*dst_pos) *dst_pos = '\0';
-  else {
-    die (STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n"));
   }
 
   return dst;
@@ -1076,7 +1071,8 @@ check_http (void)
    * TODO: Take an arguement to determine what type(s) to accept,
    * so that we can alert if a response is of an invalid type.
   */
-  xasprintf(&buf, "%sAccept: */*\r\n", buf);
+  if (!have_accept)
+    xasprintf(&buf, "%sAccept: */*\r\n", buf);
 
   /* optionally send any other header tag */
   if (http_opt_headers_count) {
@@ -1673,8 +1669,10 @@ print_help (void)
   printf ("    %s\n", _("String to expect in the response headers"));
   printf (" %s\n", "-s, --string=STRING");
   printf ("    %s\n", _("String to expect in the content"));
-  printf (" %s\n", "-u, --url=PATH");
-  printf ("    %s\n", _("URL to GET or POST (default: /)"));
+  printf (" %s\n", "-u, --uri=PATH");
+  printf ("    %s\n", _("URI to GET or POST (default: /)"));
+  printf (" %s\n", "--url=PATH");
+  printf ("    %s\n", _("(deprecated) URL to GET or POST (default: /)"));
   printf (" %s\n", "-P, --post=STRING");
   printf ("    %s\n", _("URL encoded http POST data"));
   printf (" %s\n", "-j, --method=STRING  (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)");

+ 6 - 6
plugins/check_snmp.c

@@ -479,7 +479,7 @@ main (int argc, char **argv)
 			is_ticks = 1;
 		}
 		else
-			show = response + 3;
+			show = response;
 
 		iresult = STATE_DEPENDENT;
 
@@ -594,6 +594,11 @@ main (int argc, char **argv)
 			len = sizeof(perfstr)-strlen(perfstr)-1;
 			strncat(perfstr, show, len>ptr-show ? ptr-show : len);
 
+			if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL) {
+				xasprintf (&temp_string, "%s", unitv[i]);
+				strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
+				}
+
 			if (warning_thresholds) {
 				strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
 				strncat(perfstr, warning_thresholds, sizeof(perfstr)-strlen(perfstr)-1);
@@ -607,11 +612,6 @@ main (int argc, char **argv)
 
 			if (type)
 				strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
-			if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL) {
-				xasprintf (&temp_string, "%s", unitv[i]);
-				strncat(perfstr, temp_string, sizeof(perfstr)-strlen(perfstr)-1);
-				}
-
 
 			if (thlds[i]->warning || thlds[i]->critical) {
 				strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);

+ 22 - 38
plugins/check_users.c

@@ -54,15 +54,15 @@ int process_arguments (int, char **);
 void print_help (void);
 void print_usage (void);
 
-int wusers = -1;
-int cusers = -1;
+char *warning_range = NULL;
+char *critical_range = NULL;
+thresholds *thlds = NULL;
 
 int
 main (int argc, char **argv)
 {
 	int users = -1;
 	int result = STATE_UNKNOWN;
-	char *perf;
 #if HAVE_WTSAPI32_H
 	WTS_SESSION_INFO *wtsinfo;
 	DWORD wtscount;
@@ -77,8 +77,6 @@ main (int argc, char **argv)
 	bindtextdomain (PACKAGE, LOCALEDIR);
 	textdomain (PACKAGE);
 
-	perf = strdup ("");
-
 	/* Parse extra opts if any */
 	argv = np_extra_opts (&argc, argv, progname);
 
@@ -160,23 +158,15 @@ main (int argc, char **argv)
 #endif
 
 	/* check the user count against warning and critical thresholds */
-	if (users > cusers)
-		result = STATE_CRITICAL;
-	else if (users > wusers)
-		result = STATE_WARNING;
-	else if (users >= 0)
-		result = STATE_OK;
+	result = get_status((double)users, thlds);
 
 	if (result == STATE_UNKNOWN)
 		printf ("%s\n", _("Unable to read output"));
 	else {
-		xasprintf (&perf, "%s", perfdata ("users", users, "",
-		  TRUE, wusers,
-		  TRUE, cusers,
-		  TRUE, 0,
-		  FALSE, 0));
-		printf (_("USERS %s - %d users currently logged in |%s\n"), state_text (result),
-		  users, perf);
+		printf (_("USERS %s - %d users currently logged in |%s\n"), 
+				state_text(result), users,
+				sperfdata_int("users", users, "", warning_range,
+							critical_range, TRUE, 0, FALSE, 0));
 	}
 
 	return result;
@@ -215,33 +205,27 @@ process_arguments (int argc, char **argv)
 			print_revision (progname, NP_VERSION);
 			exit (STATE_OK);
 		case 'c':									/* critical */
-			if (!is_intnonneg (optarg))
-				usage4 (_("Critical threshold must be a positive integer"));
-			else
-				cusers = atoi (optarg);
+			critical_range = optarg;
 			break;
 		case 'w':									/* warning */
-			if (!is_intnonneg (optarg))
-				usage4 (_("Warning threshold must be a positive integer"));
-			else
-				wusers = atoi (optarg);
+			warning_range = optarg;
 			break;
 		}
 	}
 
 	c = optind;
-	if (wusers == -1 && argc > c) {
-		if (is_intnonneg (argv[c]) == FALSE)
-			usage4 (_("Warning threshold must be a positive integer"));
-		else
-			wusers = atoi (argv[c++]);
-	}
-	if (cusers == -1 && argc > c) {
-		if (is_intnonneg (argv[c]) == FALSE)
-			usage4 (_("Warning threshold must be a positive integer"));
-		else
-			cusers = atoi (argv[c]);
-	}
+	if (warning_range == NULL && argc > c)
+		warning_range = argv[c++];
+	if (critical_range == NULL && argc > c)
+		critical_range = argv[c++];
+
+	/* this will abort in case of invalid ranges */
+	set_thresholds (&thlds, warning_range, critical_range);
+
+	if (thlds->warning->end <= 0)
+		usage4 (_("Warning threshold must be a positive integer"));
+	if (thlds->critical->end <= 0)
+		usage4 (_("Critical threshold must be a positive integer"));
 
 	return OK;
 }

+ 5 - 4
plugins/netutils.c

@@ -179,7 +179,7 @@ int
 np_net_connect (const char *host_name, int port, int *sd, int proto)
 {
 	struct addrinfo hints;
-	struct addrinfo *res;
+	struct addrinfo *res, *orig_res;
 	struct sockaddr_un su;
 	char port_str[6], host[MAX_HOST_ADDRESS_LENGTH];
 	size_t len;
@@ -206,7 +206,7 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
 		memcpy (host, host_name, len);
 		host[len] = '\0';
 		snprintf (port_str, sizeof (port_str), "%d", port);
-		result = getaddrinfo (host, port_str, &hints, &res);
+		result = getaddrinfo (host, port_str, &hints, &orig_res);
 
 		if (result != 0) {
 			if (result == EAI_NONAME)
@@ -216,13 +216,14 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
 			return STATE_UNKNOWN;
 		}
 
+		res = orig_res;
 		while (res) {
 			/* attempt to create a socket */
 			*sd = socket (res->ai_family, socktype, res->ai_protocol);
 
 			if (*sd < 0) {
 				printf ("%s\n", _("Socket creation failed"));
-				freeaddrinfo (res);
+				freeaddrinfo (orig_res);
 				return STATE_UNKNOWN;
 			}
 
@@ -245,7 +246,7 @@ np_net_connect (const char *host_name, int port, int *sd, int proto)
 			close (*sd);
 			res = res->ai_next;
 		}
-		freeaddrinfo (res);
+		freeaddrinfo (orig_res);
 	}
 	/* else the hostname is interpreted as a path to a unix socket */
 	else {

+ 3 - 3
plugins/sslutils.c

@@ -266,10 +266,10 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit){
 		(tm->data[10 + offset] - '0') * 10 + (tm->data[11 + offset] - '0');
 	stamp.tm_isdst = -1;
 
-	time_left = difftime(timegm(&stamp), time(NULL));
+	tm_t = timegm(&stamp);
+	time_left = difftime(tm_t, time(NULL));
 	days_left = time_left / 86400;
-	tm_t = mktime (&stamp);
-	strftime(timestamp, 50, "%c", localtime(&tm_t));
+	strftime(timestamp, 50, "%F %R %z/%Z", localtime(&tm_t));
 
 	if (days_left > 0 && days_left <= days_till_exp_warn) {
 		printf (_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left>days_till_exp_crit)?"WARNING":"CRITICAL", cn, days_left, timestamp);

+ 40 - 0
plugins/utils.c

@@ -728,6 +728,46 @@ char *sperfdata (const char *label,
 	return data;
 }
 
+char *sperfdata_int (const char *label,
+ int val,
+ const char *uom,
+ char *warn,
+ char *crit,
+ int minp,
+ int minv,
+ int maxp,
+ int maxv)
+{
+	char *data = NULL;
+	if (strpbrk (label, "'= "))
+		xasprintf (&data, "'%s'=", label);
+	else
+		xasprintf (&data, "%s=", label);
+
+	xasprintf (&data, "%s%d", data, val);
+	xasprintf (&data, "%s%s;", data, uom);
+
+	if (warn!=NULL)
+		xasprintf (&data, "%s%s", data, warn);
+
+	xasprintf (&data, "%s;", data);
+
+	if (crit!=NULL)
+		xasprintf (&data, "%s%s", data, crit);
+
+	xasprintf (&data, "%s;", data);
+
+	if (minp)
+		xasprintf (&data, "%s%d", data, minv);
+
+	if (maxp) {
+		xasprintf (&data, "%s;", data);
+		xasprintf (&data, "%s%d", data, maxv);
+	}
+
+	return data;
+}
+
 /* set entire string to lower, no need to return as it works on string in place */
 void strntolower (char * test_char, int size) {
 

+ 11 - 23
plugins/utils.h

@@ -96,29 +96,17 @@ int parse_timeout_string (char *timeout_str);
 #define max(a,b) (((a)>(b))?(a):(b))
 #define min(a,b) (((a)<(b))?(a):(b))
 
-char *perfdata (const char *,
- long int,
- const char *,
- int,
- long int,
- int,
- long int,
- int,
- long int,
- int,
- long int);
-
-char *fperfdata (const char *,
- double,
- const char *,
- int,
- double,
- int,
- double,
- int,
- double,
- int,
- double);
+char *perfdata (const char *, long int, const char *, int, long int,
+                int, long int, int, long int, int, long int);
+
+char *fperfdata (const char *, double, const char *, int, double,
+                 int, double, int, double, int, double);
+
+char *sperfdata (const char *, double, const char *, char *, char *,
+                 int, double, int, double);
+
+char *sperfdata_int (const char *, int, const char *, char *, char *,
+                     int, int, int, int);
 
 /* string case changes */
 void strntoupper (char * test_char, int size);

+ 6 - 2
po/fr.po

@@ -1409,8 +1409,12 @@ msgid "String to expect in the content"
 msgstr "Chaîne de caractère attendue dans le contenu"
 
 #: plugins/check_http.c:1355
-msgid "URL to GET or POST (default: /)"
-msgstr "URL pour le GET ou le POST (défaut: /)"
+msgid "(deprecated) URL to GET or POST (default: /)"
+msgstr "(obsolète) URL pour le GET ou le POST (défaut: /)"
+
+#: plugins/check_http.c:1355
+msgid "URI to GET or POST (default: /)"
+msgstr "URI pour le GET ou le POST (défaut: /)"
 
 #: plugins/check_http.c:1357
 msgid "URL encoded http POST data"