[pkg-nagios-changes] [Git][nagios-team/pkg-nrpe][upstream] New upstream version 4.0.0

Bas Couwenberg gitlab at salsa.debian.org
Thu Jan 16 05:23:40 GMT 2020



Bas Couwenberg pushed to branch upstream at Debian Nagios Maintainer Group / pkg-nrpe


Commits:
c80db299 by Bas Couwenberg at 2020-01-16T06:04:21+01:00
New upstream version 4.0.0
- - - - -


18 changed files:

- CHANGELOG.md
- + CONTRIBUTING.md
- configure
- configure.ac
- docs/NRPE.odt
- docs/NRPE.pdf
- include/common.h.in
- include/nrpe.h
- include/utils.h
- nrpe.spec.in
- sample-config/nrpe.cfg.in
- src/acl.c
- src/check_nrpe.c
- src/nrpe.c
- src/utils.c
- startup/default-xinetd.in
- startup/openrc-init.in
- update-version


Changes:

=====================================
CHANGELOG.md
=====================================
@@ -1,6 +1,30 @@
 NRPE Changelog
 ==============
 
+[4.0.0](https://github.com/NagiosEnterprises/nrpe/releases/tag/nrpe-4.0.0) - 2019-01-13
+---------------------------------------------------------------------------------------
+Note: This update includes security fixes which affect both the check_nrpe plugin and 
+the NRPE daemon. The latest version of NRPE is still able to interoperate with previous
+versions, but for best results, both programs should be updated.
+
+**ENHANCEMENTS**
+* Added TLSv1.3 and TLSv1.3+ support for systems that have it (Nigel Yong, Rahul Golam)
+* Added IPv6 ip address to list of default allow_from hosts (Troy Lea)
+* Added -D option to disable logging to syslog (Tom Griep, Sebastian Wolf)
+* Added -3 option to force check_nrpe to use NRPE v3 packets
+* OpenRC: provide a default path for nrpe.cfg (Michael Orlitzky)
+* OpenRC: Use RC_SVCNAME over a hard-coded PID file (j-licht)
+
+**FIXES**
+* Checks for '!' now only occur inside the command buffer (Joni Eskelinen)
+* NRPE daemon is more resilient to DOS attacks (Leonid Vasiliev)
+* allowed_hosts will no longer test getaddrinfo records against the wrong protocol (dombenson)
+* nasty_metachars will now handle C escape sequences properly when specified in the config file (Sebastian Wolf)
+* Calculated packet sizes now struct padding/alignment when sending and receiving messages (Sebastian Wolf)
+* Buffer sizes are now checked before use in packet size calculation (Sebastian Wolf)
+* When using `include_dir`, individual files' errors do not prevent the remaining files from being read (Sebastian Wolf)
+
+
 [3.2.1](https://github.com/NagiosEnterprises/nrpe/releases/tag/nrpe-3.2.1) - 2017-08-31
 ---------------------------------------------------------------------------------------
 **FIXES**


=====================================
CONTRIBUTING.md
=====================================
@@ -0,0 +1,164 @@
+# Contributing
+
+Thank you for considering contributing your time and effort to this Nagios project.
+This document serves as our guidelines for contribution. Keep in mind that these 
+are simply *guidelines* - nothing here is set in stone.
+
+## Questions
+
+If you have a question, you don't need to file an Issue. You can simply connect
+with the Nagios Support Team via the 
+[Nagios Support Forum](https://support.nagios.com/forum/).
+
+Not to say that you **can't** open an Issue - but you'll likely get a much faster
+response by posting it on the forum.
+
+## Ideas
+
+If you have an idea your best bet is to open an Issue. This gets it on the radar much
+quicker than any other method.
+
+First, let's define what an "Idea" really is. An Idea is simply an 
+[Enhancement](#enhancements) request in its infancy. 
+There's really nothing to it!
+
+Something as simple as "I think that this project should somehow connect with a 
+widget" is a valid Idea.
+
+These are unrefined and raw. That's why you open an issue - so everyone gets a chance
+to chime in and come up with a plan!
+
+## Feedback
+
+Feedback can be given via several methods. The *easiest* method is by opening an Issue.
+You're more than welcome to leave feedback on the 
+[Nagios Support Forum](https://support.nagios.com/forum/) as well.
+
+By opening an Issue, however, you're insuring that the maintainers and reviewers are
+the first ones to see the feedback. In most cases, this is likely ideal.
+
+## Bugs
+
+Here's where it starts to get serious. 
+
+Following the guidelines outlined in this section allows the maintainers, developers, and
+community to understand and reproduce your bug report.
+
+Make sure to search existing open and closed [Issues](https://guides.github.com/features/issues/)
+before opening a bug report. If you find a closed Issue that seems like it's the same 
+thing that you're experiencing, open a new Issue and include a link to the original Issue 
+in the body of the new one.
+
+**If you have a bug, you *NEED* to open an Issue.**
+
+Not only that, but when you open the Issue, this is what we ***absolutely require***:
+
+* Use a clear and concise title for the Issue to identify the problem accurately
+
+* Describe the bug with as much detail as you can
+
+* Include the version of the project containing the bug you're reporting
+
+* Include your operating system information (`uname -a`)
+
+* Include a list of third party modules that are installed and/or loaded
+
+* Explain the behavior you expected to see (and why) vs. what actually happened
+
+Once you've got that covered - there's still more to include if you want to
+make a ***killer*** report:
+
+* Describe the ***exact steps*** that reproduce the problem
+
+* Provide **specific** examples to demonstrate those steps
+ 
+* If your bug is from an older version, make sure test against the latest (and/or the `maint` branch)
+
+* Include any screenshots that can help explain the issue
+
+* Include a file containing `strace` and/or `valgrind` output
+
+* Explain when the problem started happening: was it after an upgrade? or was it always present?
+
+* Define how reliably you can reproduce the bug
+
+* Any other information that you decide is relevant is also welcome
+
+## Enhancements
+
+An enhancement is either a completely new feature or an improvement to existing 
+functionality. We consider it to be a bit different than idea - based solely
+on the fact that it's more detailed than an idea would be.
+
+So you've got an idea for an ehancement? Great!
+
+Following the guidelines outlined in this section allows maintainers, developers, and
+the community to understand your enhancement and determine whether or not it's worth 
+doing and/or what's involved in carrying it out.
+
+Make sure to search open and closed Issues and Pull Requests to determine if
+someone has either submitted the enhancement. If you feel like your enhancement
+is similar to one found, make sure to link the original in your request.
+
+Enhancements are submitted by opening an Issue.
+
+Unlike an [Idea](#idea), when you decide to submit your enhancement and open 
+the Issue, we require at least the following information:
+
+* Use a clear and descriptive title to illustrate the enhancement you're requesting
+
+* Describe the current behavior (if it exists) and what changes you think should be made
+
+* Explain the enhancement in detail - make sure it makes sense and is easily understandable
+
+* Specify why the enhancement would be useful and who it would be useful to
+
+* If there is some other project or program where this enhancement already exists, make sure
+to link to it
+
+Beyond that, there are a few more things you can do to make sure you **really** get your
+point across:
+
+* Create a mockup of the enhancement (if applicable) and attach whatever files you can
+
+* Provide a step-by-step description of the suggested enhancement
+
+* Generate a fully dressed use-case for the enhancement request
+
+* Create a specification for the preferred implementation of the enhancement
+
+* Include a timeline regarding development expectations towards the request
+
+## Submitting Code
+
+Everything else in this document has lead up to this moment - how can ***you*** submit 
+code to the **project**.
+
+We allow code submissions via [Pull Requests](https://help.github.com/articles/about-pull-requests/).
+These let you (and us) discuss and review any changes to code in any repository you've made.
+
+How to create and manage Pull Requests is outside of the scope of this document, but make
+sure to check out GitHub's official documentation ([link here](https://help.github.com/))
+to get a handle on it.
+
+While you're forking the repository to create a patch or an enhancement, create a *new 
+branch* to make the change - it will be easier to submit a pull request using a new
+branch in your forked repository!
+
+When you submit a Pull Request, make sure you follow the guidelines:
+
+* Make sure you're submitting to the proper branch. Branch `maint` is used for the 
+**next** bugfix release. The next enhancement release branch will vary.
+
+* ***NEVER*** submit a Pull Request to `master` branch.
+
+* Keep commit messages as concise as possible.
+* Update the appropriate files in regards to your changes:
+
+  * `CHANGES`
+
+  * `THANKS`
+
+* End all committed files with a newline.
+
+* Test your changes and include the results as a comment.
\ No newline at end of file


=====================================
configure
=====================================
@@ -2487,9 +2487,9 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
 PKG_NAME=nrpe
-PKG_VERSION="3.2.1"
+PKG_VERSION="4.0.0"
 PKG_HOME_URL="http://www.nagios.org/"
-PKG_REL_DATE="2017-09-01"
+PKG_REL_DATE="2020-01-15"
 RPM_RELEASE=1
 
 LANG=C


=====================================
configure.ac
=====================================
@@ -11,9 +11,9 @@ AC_CONFIG_AUX_DIR([build-aux])
 AC_PREFIX_DEFAULT(/usr/local/nagios)
 
 PKG_NAME=nrpe
-PKG_VERSION="3.2.1"
+PKG_VERSION="4.0.0"
 PKG_HOME_URL="http://www.nagios.org/"
-PKG_REL_DATE="2017-09-01"
+PKG_REL_DATE="2020-01-15"
 RPM_RELEASE=1
 
 LANG=C


=====================================
docs/NRPE.odt
=====================================
Binary files a/docs/NRPE.odt and b/docs/NRPE.odt differ


=====================================
docs/NRPE.pdf
=====================================
Binary files a/docs/NRPE.pdf and b/docs/NRPE.pdf differ


=====================================
include/common.h.in
=====================================
@@ -37,8 +37,8 @@
 # endif
 #endif
 
-#define PROGRAM_VERSION "3.2.1"
-#define MODIFICATION_DATE "2017-09-01"
+#define PROGRAM_VERSION "4.0.0"
+#define MODIFICATION_DATE "2020-01-15"
 
 #define OK							0
 #define ERROR						-1
@@ -66,12 +66,23 @@
 
 #define QUERY_PACKET				1		/* id code for a packet containing a query */
 #define	RESPONSE_PACKET				2		/* id code for a packet containing a response */
-#define NRPE_PACKET_VERSION_3		3		/* packet version identifier */
+
+/* v4 takes struct padding into account, so the buffer "takes" 4 bytes
+ * v3 removes the 1 byte that "should" be allocated to buffer.
+ */
+#define NRPE_V4_PACKET_SIZE_OFFSET  4
+#define NRPE_V3_PACKET_SIZE_OFFSET  1
+
+/* packet version identifiers */
+#define NRPE_PACKET_VERSION_4		4       /* Same as version 3, but accounts for struct padding in network code */
+#define NRPE_PACKET_VERSION_3		3		/* Allows for variable-length buffer */
 #define NRPE_PACKET_VERSION_2		2
 #define NRPE_PACKET_VERSION_1		1		/* older packet version identifiers (no longer supported) */
 
 #define MAX_PACKETBUFFER_LENGTH		1024	/* amount of data to send in one query/response vor version 2 */
 
+#define NRPE_DEFAULT_PACKET_VERSION NRPE_PACKET_VERSION_4
+
 typedef struct _v2_packet {
 	int16_t		packet_version;
 	int16_t		packet_type;
@@ -89,6 +100,8 @@ typedef struct _v3_packet {
 	char		buffer[1];
 } v3_packet;
 
+typedef v3_packet v4_packet;
+
 /**************** OPERATING SYSTEM SPECIFIC DEFINITIONS **********/
 #if defined(__sun) || defined(__hpux)
 


=====================================
include/nrpe.h
=====================================
@@ -24,6 +24,8 @@
  *
  ****************************************************************************/
 
+#include <limits.h>
+
 typedef struct command_struct {
 	char					*command_name;
 	char					*command_line;


=====================================
include/utils.h
=====================================
@@ -49,5 +49,6 @@ void open_log_file();
 void logit(int priority, const char *format, ...);
 void close_log_file();
 void display_license(void);
+extern int disable_syslog;
 
 #endif


=====================================
nrpe.spec.in
=====================================
@@ -22,7 +22,7 @@
 %define _sysconfdir /etc/nagios
 
 %define name @PACKAGE_NAME@
-%define version 3.2.1
+%define version 4.0.0
 %define release @RPM_RELEASE@
 %define nsusr @nrpe_user@
 %define nsgrp @nrpe_group@


=====================================
sample-config/nrpe.cfg.in
=====================================
@@ -270,7 +270,9 @@ connection_timeout=300
 
 # nasty_metachars="|`&><'\\[]{};\r\n"
 
-
+# This option allows you to enable or disable logging error messages to the syslog facilities.
+# If this option is not set, the error messages will be logged.
+disable_syslog=0
 
 # COMMAND DEFINITIONS
 # Command definitions that this daemon will run.  Definitions


=====================================
src/acl.c
=====================================
@@ -544,31 +544,45 @@ int is_an_allowed_host(int family, void *host)
 		if (!getaddrinfo(dns_acl_curr->domain, NULL, NULL, &res)) {
 
 			for (ai = res; ai; ai = ai->ai_next) {
-
-				switch(ai->ai_family) {
-
-				case AF_INET:
-					if(debug == TRUE) {
-						tmp.s_addr=((struct in_addr *)host)->s_addr;
-						logit(LOG_INFO, "is_an_allowed_host (AF_INET): is host >%s< "
-								"an allowed host >%s<\n",
-							 inet_ntoa(tmp), dns_acl_curr->domain);
+				if (ai->ai_family == family) {
+					switch (ai->ai_family) {
+
+						case AF_INET:
+							if (debug == TRUE) {
+								tmp.s_addr = ((struct in_addr *) host)->s_addr;
+								logit(LOG_INFO, "is_an_allowed_host (AF_INET): test match host >%s< "
+											  "for allowed host >%s<\n",
+									  inet_ntoa(tmp), dns_acl_curr->domain);
+							}
+
+							addr = (struct sockaddr_in *) (ai->ai_addr);
+							if (addr->sin_addr.s_addr == ((struct in_addr *) host)->s_addr) {
+								if (debug == TRUE)
+									logit(LOG_INFO, "is_an_allowed_host (AF_INET): "
+											"host is in allowed host list!");
+								return 1;
+							}
+							break;
+
+						case AF_INET6:
+							if (debug == TRUE) {
+								char formattedStr[INET6_ADDRSTRLEN];
+								inet_ntop(ai->ai_family, (void *) &(((struct sockaddr_in6 *) (ai->ai_addr))->sin6_addr),
+										  formattedStr, INET6_ADDRSTRLEN);
+								logit(LOG_INFO, "is_an_allowed_host (AF_INET6): test match host against >%s< "
+											  "for allowed host >%s<\n",
+									  formattedStr, dns_acl_curr->domain);
+							}
+							struct in6_addr *resolved = &(((struct sockaddr_in6 *) (ai->ai_addr))->sin6_addr);
+							memcpy((char *) &addr6, ai->ai_addr, sizeof(addr6));
+							if (!memcmp(&addr6.sin6_addr, host, sizeof(addr6.sin6_addr))) {
+								if (debug == TRUE)
+									logit(LOG_INFO, "is_an_allowed_host (AF_INET6): "
+											"host is in allowed host list!");
+								return 1;
+							}
+							break;
 					}
-
-					addr = (struct sockaddr_in*)(ai->ai_addr);
-					if (addr->sin_addr.s_addr == ((struct in_addr*)host)->s_addr) {
-						if (debug == TRUE)
-							logit(LOG_INFO, "is_an_allowed_host (AF_INET): "
-									"host is in allowed host list!");
-						return 1;
-					}
-					break;
-
-				case AF_INET6:
-					memcpy((char*)&addr6, ai->ai_addr, sizeof(addr6));
-					if (!memcmp(&addr6.sin6_addr, &host, sizeof(addr6.sin6_addr)))
-						return 1;
-					break;
 				}
 			}
 		}


=====================================
src/check_nrpe.c
=====================================
@@ -65,8 +65,9 @@ char query[MAX_INPUT_BUFFER] = "";
 int show_help = FALSE;
 int show_license = FALSE;
 int show_version = FALSE;
-int packet_ver = NRPE_PACKET_VERSION_3;
+int packet_ver = NRPE_DEFAULT_PACKET_VERSION;
 int force_v2_packet = 0;
+int force_v3_packet = 0;
 int payload_size = 0;
 extern char *log_file;
 
@@ -87,7 +88,7 @@ int use_ssl = FALSE;
 /* SSL/TLS parameters */
 typedef enum _SSL_VER {
 	SSL_Ver_Invalid = 0, SSLv2 = 1, SSLv2_plus, SSLv3, SSLv3_plus,
-	TLSv1, TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus
+	TLSv1, TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus, TLSv1_3, TLSv1_3_plus
 } SslVer;
 
 typedef enum _CLNT_CERTS { Ask_For_Cert = 1, Require_Cert = 2 } ClntCerts;
@@ -129,6 +130,8 @@ static int verify_callback(int ok, X509_STORE_CTX * ctx);
 #endif
 void alarm_handler(int);
 int graceful_close(int, int);
+int disable_syslog = FALSE;
+
 
 int main(int argc, char **argv)
 {
@@ -175,7 +178,7 @@ int main(int argc, char **argv)
 
 	if (result == -1) {
 		/* Failure reading from remote, so try version 2 packet */
-		logit(LOG_INFO, "Remote %s does not support Version 3 Packets", rem_host);
+		logit(LOG_INFO, "Remote %s does not support version 3/4 packets", rem_host);
 		packet_ver = NRPE_PACKET_VERSION_2;
 
 		/* Rerun the setup */
@@ -198,7 +201,7 @@ int main(int argc, char **argv)
 	}
 
 	if (result != -1 && force_v2_packet == 0 && packet_ver == NRPE_PACKET_VERSION_2)
-		logit(LOG_DEBUG, "Remote %s accepted a Version %d Packet", rem_host, packet_ver);
+		logit(LOG_DEBUG, "Remote %s accepted a version %d packet", rem_host, packet_ver);
 
 	close_log_file();			/* close the log file */
 	return result;
@@ -224,6 +227,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
 		{"no-ssl", no_argument, 0, 'n'},
 		{"unknown-timeout", no_argument, 0, 'u'},
 		{"v2-packets-only", no_argument, 0, '2'},
+		{"v3-packets-only", no_argument, 0, '3'},
 		{"ipv4", no_argument, 0, '4'},
 		{"ipv6", no_argument, 0, '6'},
 		{"use-adh", required_argument, 0, 'd'},
@@ -241,6 +245,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
 		{"license", no_argument, 0, 'l'},
 		{"version", no_argument, 0, 'V'},
 		{"stderr-to-stdout", no_argument, 0, 'E'},
+		{"disable-syslog", no_argument, 0, 'D'},
 		{0, 0, 0, 0}
 	};
 #endif
@@ -250,7 +255,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
 		return ERROR;
 
 	optind = 0;
-	snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:246hlnuVE");
+	snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:2346hlnuVED");
 
 	while (1) {
 		if (argindex > 0)
@@ -366,14 +371,21 @@ int process_arguments(int argc, char **argv, int from_config_file)
 			break;
 
 		case '2':
-			if (from_config_file && packet_ver != NRPE_PACKET_VERSION_3) {
+			if (from_config_file && packet_ver != NRPE_DEFAULT_PACKET_VERSION) {
 				logit(LOG_WARNING, "WARNING: Command-line v2-packets-only (-2) overrides the config file option.");
 				break;
 			}
 			packet_ver = NRPE_PACKET_VERSION_2;
 			force_v2_packet = 1;
 			break;
-
+		case '3':
+			if (from_config_file && packet_ver != NRPE_DEFAULT_PACKET_VERSION) {
+				logit(LOG_WARNING, "Warning: Command-line v3-packets-only (-3) overrides the config file option.");
+				break;
+			}
+			packet_ver = NRPE_PACKET_VERSION_3;
+			force_v3_packet = 1;
+			break;
 		case '4':
 			if (from_config_file && address_family != AF_UNSPEC) {
 				logit(LOG_WARNING, "WARNING: Command-line ipv4 (-4) or ipv6 (-6) overrides the config file option.");
@@ -432,7 +444,11 @@ int process_arguments(int argc, char **argv, int from_config_file)
 				break;
 			}
 
-			if (!strcmp(optarg, "TLSv1.2"))
+			if (!strcmp(optarg, "TLSv1.3"))
+				sslprm.ssl_proto_ver = TLSv1_3;
+			else if (!strcmp(optarg, "TLSv1.3+"))
+				sslprm.ssl_proto_ver = TLSv1_3_plus;
+			else if (!strcmp(optarg, "TLSv1.2"))
 				sslprm.ssl_proto_ver = TLSv1_2;
 			else if (!strcmp(optarg, "TLSv1.2+"))
 				sslprm.ssl_proto_ver = TLSv1_2_plus;
@@ -485,6 +501,11 @@ int process_arguments(int argc, char **argv, int from_config_file)
 			open_log_file();
 			break;
 
+		case 'D':
+			disable_syslog = TRUE;
+			break;
+
+
 		default:
 			return ERROR;
 		}
@@ -526,6 +547,11 @@ int process_arguments(int argc, char **argv, int from_config_file)
 		return ERROR;
 	}
 
+	if (force_v2_packet && force_v3_packet) {
+		printf("Error: Only one of force_v2_packet (-2) and force_v3_packet (-3) can be specified.\n");
+		return ERROR;
+	}
+
 	/* make sure required args were supplied */
 	if (server_name == NULL && show_help == FALSE && show_version == FALSE
 		&& show_license == FALSE)
@@ -687,15 +713,16 @@ void usage(int result)
 		printf("SSL/TLS Available: OpenSSL 0.9.6 or higher required\n");
 		printf("\n");
 #endif
-		printf("Usage: check_nrpe -H <host> [-2] [-4] [-6] [-n] [-u] [-V] [-l] [-d <dhopt>]\n");
+		printf("Usage: check_nrpe -H <host> [-2] [-3] [-4] [-6] [-n] [-u] [-V] [-l] [-d <dhopt>]\n");
 		printf("       [-P <size>] [-S <ssl version>]  [-L <cipherlist>] [-C <clientcert>]\n");
 		printf("       [-K <key>] [-A <ca-certificate>] [-s <logopts>] [-b <bindaddr>]\n");
 		printf("       [-f <cfg-file>] [-p <port>] [-t <interval>:<state>] [-g <log-file>]\n");
-		printf("       [-c <command>] [-E] [-a <arglist...>]\n");
+		printf("       [-c <command>] [-E] [-D] [-a <arglist...>]\n");
 		printf("\n");
 		printf("Options:\n");
 		printf(" -H, --host=HOST              The address of the host running the NRPE daemon\n");
-		printf(" -2, --v2-packets-only        Only use version 2 packets, not version 3\n");
+		printf(" -2, --v2-packets-only        Only use version 2 packets, not version 3/4\n");
+		printf(" -3, --v3-packets-only        Only use version 3 packets, not version 4\n");
 		printf(" -4, --ipv4                   Bind to ipv4 only\n");
 		printf(" -6, --ipv6                   Bind to ipv6 only\n");
 		printf(" -n, --no-ssl                 Do no use SSL\n");
@@ -708,6 +735,7 @@ void usage(int result)
 		printf("                                        (This will be the default in a future release.)\n");
 		printf("                              1         Allow Anonymous Diffie Hellman (default)\n");
 		printf("                              2         Force Anonymous Diffie Hellman\n");
+		printf(" -D, --disable-syslog         Disable logging to syslog facilities\n");
 		printf(" -P, --payload-size=SIZE      Specify non-default payload size for NSClient++\n");
 		printf(" -S, --ssl-version=VERSION    The SSL/TLS version to use. Can be any one of:\n");
 #if OPENSSL_VERSION_NUMBER < 0x10100000
@@ -740,6 +768,7 @@ void usage(int result)
 		printf(" -a, --args=LIST              Optional arguments that should be passed to the command,\n");
 		printf("                              separated by a space. If provided, this must be the last\n");
 		printf("                              option supplied on the command line.\n");
+		printf(" -e 	                      Enable syslog debug messages.\n");
 		printf("\n");
 		printf(" NEW TIMEOUT SYNTAX\n");
 		printf(" -t, --timeout=INTERVAL:STATE\n");
@@ -811,6 +840,12 @@ void setup_ssl()
 		case TLSv1_2_plus:
 			val = "TLSv1_2_plus And Above";
 			break;
+		case TLSv1_3:
+			val = "TLSv1_3";
+			break;
+		case TLSv1_3_plus:
+			val = "TLSv1_3_plus And Above";
+			break;
 		default:
 			val = "INVALID VALUE!";
 			break;
@@ -850,6 +885,10 @@ void setup_ssl()
 #  ifdef SSL_TXT_TLSV1_2
 		if (sslprm.ssl_proto_ver == TLSv1_2)
 			meth = TLSv1_2_client_method();
+#  ifdef SSL_TXT_TLSV1_3
+		if (sslprm.ssl_proto_ver == TLSv1_3)
+			meth = TLSv1_3_client_method();
+#  endif	/* ifdef SSL_TXT_TLSV1_3 */
 #  endif	/* ifdef SSL_TXT_TLSV1_2 */
 # endif	/* ifdef SSL_TXT_TLSV1_1 */
 
@@ -865,6 +904,15 @@ void setup_ssl()
 	SSL_CTX_set_max_proto_version(ctx, 0);
 
 	switch(sslprm.ssl_proto_ver) {
+		case TLSv1_3:
+#if OPENSSL_VERSION_NUMBER >= 0x10101000
+			SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
+#endif
+		case TLSv1_3_plus:
+#if OPENSSL_VERSION_NUMBER >= 0x10101000
+			SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
+			break;
+#endif
 
 		case TLSv1_2:
 			SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
@@ -897,11 +945,14 @@ void setup_ssl()
 			case SSLv2:
 			case SSLv2_plus:
 				break;
+			case TLSv1_3:
+			case TLSv1_3_plus:
+#ifdef SSL_OP_NO_TLSv1_2
+				ssl_opts |= SSL_OP_NO_TLSv1_2;
+#endif
 			case TLSv1_2:
 			case TLSv1_2_plus:
-#ifdef SSL_OP_NO_TLSv1_1
 				ssl_opts |= SSL_OP_NO_TLSv1_1;
-#endif
 			case TLSv1_1:
 			case TLSv1_1_plus:
 				ssl_opts |= SSL_OP_NO_TLSv1;
@@ -1165,9 +1216,13 @@ int send_request()
 
 	} else {
 
-		pkt_size = (sizeof(v3_packet) - 1) + strlen(query) + 1;
-		if (pkt_size < sizeof(v2_packet))
+		pkt_size = (sizeof(v3_packet) - NRPE_V4_PACKET_SIZE_OFFSET) + strlen(query) + 1;
+		if (packet_ver == NRPE_PACKET_VERSION_3) {
+			pkt_size = (sizeof(v3_packet) - NRPE_V3_PACKET_SIZE_OFFSET) + strlen(query) + 1;
+		}
+		if (pkt_size < sizeof(v2_packet)) {
 			pkt_size = sizeof(v2_packet);
+		}
 
 		v3_send_packet = calloc(1, pkt_size);
 		send_pkt = (char *)v3_send_packet;
@@ -1197,10 +1252,12 @@ int send_request()
 	}
 #endif
 
-	if (v3_send_packet)
+	if (v3_send_packet) {
 		free(v3_send_packet);
-	if (v2_send_packet)
+	}
+	if (v2_send_packet) {
 		free(v2_send_packet);
+	}
 
 	if (rc == -1) {
 		printf("CHECK_NRPE: Error sending query to host.\n");
@@ -1214,10 +1271,11 @@ int send_request()
 int read_response()
 {
 	v2_packet *v2_receive_packet = NULL;
+	/* Note: v4 packets will use the v3_packet structure */
 	v3_packet *v3_receive_packet = NULL;
 	u_int32_t packet_crc32;
 	u_int32_t calculated_crc32;
-	int32_t pkt_size;
+	int32_t pkt_size, buffer_size;
 	int rc, result;
 
 	alarm(0);
@@ -1243,32 +1301,50 @@ int read_response()
 
 	/* recv() error */
 	if (rc < 0) {
-		if (packet_ver == NRPE_PACKET_VERSION_3) {
-			if (v3_receive_packet)
-				free(v3_receive_packet);
+		if (v2_receive_packet) {
+			free(v2_receive_packet);
+		}
+		if (v3_receive_packet) {
+			free(v3_receive_packet);
+		}
+		if (packet_ver >= NRPE_PACKET_VERSION_3) {
 			return -1;
 		}
-		if (v2_receive_packet)
-			free(v2_receive_packet);
 		return STATE_UNKNOWN;
 
 	} else if (rc == 0) {
 
 		/* server disconnected */
 		printf("CHECK_NRPE: Received 0 bytes from daemon.  Check the remote server logs for error messages.\n");
-		if (packet_ver == NRPE_PACKET_VERSION_3) {
-			if (v3_receive_packet) {
-				free(v3_receive_packet);
-			}
-		} else if (v2_receive_packet) {
+		if (v3_receive_packet) {
+			free(v3_receive_packet);
+		}
+		if (v2_receive_packet) {
 			free(v2_receive_packet);
 		}
 		return STATE_UNKNOWN;
 	}
 
 	/* check the crc 32 value */
-	if (packet_ver == NRPE_PACKET_VERSION_3) {
-		pkt_size = (sizeof(v3_packet) - 1) + ntohl(v3_receive_packet->buffer_length);
+	if (packet_ver >= NRPE_PACKET_VERSION_3) {
+
+		buffer_size = ntohl(v3_receive_packet->buffer_length);
+		if (buffer_size < 0 || buffer_size > 65536) {
+			printf("CHECK_NRPE: Response packet had invalid buffer size.\n");
+			close(sd);
+			if (v3_receive_packet) {
+				free(v3_receive_packet);
+			}
+			if (v2_receive_packet) {
+				free(v2_receive_packet);
+			}
+			return STATE_UNKNOWN;
+		}
+
+		pkt_size = sizeof(v3_packet);
+		pkt_size -= (packet_ver == NRPE_PACKET_VERSION_3 ? NRPE_V3_PACKET_SIZE_OFFSET : NRPE_V4_PACKET_SIZE_OFFSET);
+		pkt_size += buffer_size;
+
 		packet_crc32 = ntohl(v3_receive_packet->crc32_value);
 		v3_receive_packet->crc32_value = 0L;
 		v3_receive_packet->alignment = 0;
@@ -1286,11 +1362,10 @@ int read_response()
 	if (packet_crc32 != calculated_crc32) {
 		printf("CHECK_NRPE: Response packet had invalid CRC32.\n");
 		close(sd);
-		if (packet_ver == NRPE_PACKET_VERSION_3) {
-			if (v3_receive_packet) {
-				free(v3_receive_packet);
-			}
-		} else if (v2_receive_packet) {
+		if (v3_receive_packet) {
+			free(v3_receive_packet);
+		}
+		if (v2_receive_packet) {
 			free(v2_receive_packet);
 		}
 		return STATE_UNKNOWN;
@@ -1322,11 +1397,10 @@ int read_response()
 		}
 	}
 
-	if (packet_ver == NRPE_PACKET_VERSION_3) {
-		if (v3_receive_packet) {
-			free(v3_receive_packet);
-		}
-	} else if (v2_receive_packet) {
+	if (v3_receive_packet) {
+		free(v3_receive_packet);
+	}
+	if (v2_receive_packet) {
 		free(v2_receive_packet);
 	}
 
@@ -1348,14 +1422,13 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
 
 		if (rc <= 0 || rc != bytes_to_recv) {
 			if (rc < bytes_to_recv) {
-				if (packet_ver != NRPE_PACKET_VERSION_3)
+				if (packet_ver <= NRPE_PACKET_VERSION_3)
 					printf("CHECK_NRPE: Receive header underflow - only %d bytes received (%ld expected).\n", rc, sizeof(bytes_to_recv));
 			}
 			return -1;
 		}
 
-		packet_ver = ntohs(packet.packet_version);
-		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+		if (packet_ver != ntohs(packet.packet_version)) {
 			printf("CHECK_NRPE: Invalid packet version received from server.\n");
 			return -1;
 		}
@@ -1398,6 +1471,10 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
 			tot_bytes += rc;
 
 			buffer_size = ntohl(buffer_size);
+			if (buffer_size < 0 || buffer_size > 65536) {
+				logit(LOG_ERR, "Error: Received packet with invalid buffer size");
+				return -1;
+			}
 			pkt_size += buffer_size;
 			if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
 				logit(LOG_ERR, "Error: Could not allocate memory for packet");
@@ -1413,7 +1490,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
 		rc = recvall(sock, buff_ptr, &bytes_to_recv, socket_timeout);
 
 		if (rc <= 0 || rc != buffer_size) {
-			if (packet_ver == NRPE_PACKET_VERSION_3) {
+			if (packet_ver >= NRPE_PACKET_VERSION_3) {
 				free(*v3_pkt);
 				*v3_pkt = NULL;
 			} else {
@@ -1436,14 +1513,13 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
 
 		if (rc <= 0 || rc != bytes_to_recv) {
 			if (rc < bytes_to_recv) {
-				if (packet_ver != NRPE_PACKET_VERSION_3)
+				if (packet_ver < NRPE_PACKET_VERSION_3 || packet_ver > NRPE_PACKET_VERSION_4)
 					printf("CHECK_NRPE: Receive header underflow - only %d bytes received (%ld expected).\n", rc, sizeof(bytes_to_recv));
 			}
 			return -1;
 		}
 
-		packet_ver = ntohs(packet.packet_version);
-		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+		if (packet_ver != ntohs(packet.packet_version)) {
 			printf("CHECK_NRPE: Invalid packet version received from server.\n");
 			return -1;
 		}
@@ -1491,6 +1567,10 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
 			tot_bytes += rc;
 
 			buffer_size = ntohl(buffer_size);
+			if (buffer_size < 0 || buffer_size > 65536) {
+				logit(LOG_ERR, "Error: Received packet with invalid buffer size");
+				return -1;
+			}
 			pkt_size += buffer_size;
 			if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
 				logit(LOG_ERR, "Error: Could not allocate memory for packet");
@@ -1517,7 +1597,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
 		buff_ptr[bytes_read] = 0;
 
 		if (rc < 0 || bytes_read != buffer_size) {
-			if (packet_ver == NRPE_PACKET_VERSION_3) {
+			if (packet_ver >= NRPE_PACKET_VERSION_3) {
 				free(*v3_pkt);
 				*v3_pkt = NULL;
 			} else {
@@ -1525,7 +1605,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
 				*v2_pkt = NULL;
 			}
 			if (bytes_read != buffer_size) {
-				if (packet_ver == NRPE_PACKET_VERSION_3) {
+				if (packet_ver >= NRPE_PACKET_VERSION_3) {
 					printf("CHECK_NRPE: Receive buffer size - %ld bytes received (%ld expected).\n", (long)bytes_read, sizeof(buffer_size));
 				} else {
 					printf("CHECK_NRPE: Receive underflow - only %ld bytes received (%ld expected).\n", (long)bytes_read, sizeof(buffer_size));


=====================================
src/nrpe.c
=====================================
@@ -124,7 +124,7 @@ extern char *log_file;
 /* SSL/TLS parameters */
 typedef enum _SSL_VER {
 	SSLv2 = 1, SSLv2_plus, SSLv3, SSLv3_plus, TLSv1,
-	TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus
+	TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus, TLSv1_3, TLSv1_3_plus
 } SslVer;
 
 typedef enum _CLNT_CERTS {
@@ -148,11 +148,11 @@ struct _SSL_PARMS {
 	SslLogging log_opts;
 } sslprm = {
 #if OPENSSL_VERSION_NUMBER >= 0x10100000
-NULL, NULL, NULL, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", TLSv1_plus, TRUE, 0, SSL_NoLogging};
+NULL, NULL, NULL, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", TLSv1_plus, TRUE, 0, SSL_NoLogging
 #else
-NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging};
+NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging
 #endif
-
+};
 
 #ifdef HAVE_SSL
 static int verify_callback(int ok, X509_STORE_CTX * ctx);
@@ -160,6 +160,8 @@ static void my_disconnect_sighandler(int sig);
 static void complete_SSL_shutdown(SSL *);
 #endif
 
+int disable_syslog = FALSE;
+
 int main(int argc, char **argv)
 {
 	int       result = OK;
@@ -329,6 +331,10 @@ void init_ssl(void)
 #  ifdef SSL_TXT_TLSV1_2
 	if (sslprm.ssl_proto_ver == TLSv1_2)
 		meth = TLSv1_2_server_method();
+#  ifdef SSL_TXT_TLSV1_3
+	if (sslprm.ssl_proto_ver == TLSv1_3)
+		meth = TLSv1_3_server_method();
+#  endif	/* ifdef SSL_TXT_TLSV1_3 */
 #  endif	/* ifdef SSL_TXT_TLSV1_2 */
 # endif		/* SSL_TXT_TLSV1_1 */
 
@@ -349,6 +355,15 @@ void init_ssl(void)
 	SSL_CTX_set_max_proto_version(ctx, 0);
 
 	switch(sslprm.ssl_proto_ver) {
+		case TLSv1_3:
+#if OPENSSL_VERSION_NUMBER >= 0x10101000
+			SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
+#endif
+		case TLSv1_3_plus:
+#if OPENSSL_VERSION_NUMBER >= 0x10101000
+			SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
+			break;
+#endif
 
 		case TLSv1_2:
 			SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
@@ -381,11 +396,14 @@ void init_ssl(void)
 		case SSLv2:
 		case SSLv2_plus:
 			break;
+		case TLSv1_3:
+		case TLSv1_3_plus:
+#ifdef SSL_OP_NO_TLSv1_2
+			ssl_opts |= SSL_OP_NO_TLSv1_2;
+#endif
 		case TLSv1_2:
 		case TLSv1_2_plus:
-#ifdef SSL_OP_NO_TLSv1_1
 			ssl_opts |= SSL_OP_NO_TLSv1_1;
-#endif
 		case TLSv1_1:
 		case TLSv1_1_plus:
 			ssl_opts |= SSL_OP_NO_TLSv1;
@@ -517,6 +535,12 @@ void log_ssl_startup(void)
 	case TLSv1_2_plus:
 		vers = "TLSv1_2 And Above";
 		break;
+	case TLSv1_3:
+		vers = "TLSv1_3";
+		break;
+	case TLSv1_3_plus:
+		vers = "TLSv1_3 And Above";
+		break;
 	default:
 		vers = "INVALID VALUE!";
 		break;
@@ -745,6 +769,62 @@ int verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
 }
 #endif
 
+/*
+ * Given a string, convert any byte pairs representing an escape sequence (e.g. "\\r" into 
+ * the single-byte metacharacter (e.g. '\r')
+ * Currently, this doesn't support octal/hex numbers or unicode code points (\n, \x, \u, \U)
+ */
+char* process_metachars(const char* input)
+{
+	char* copy = strdup(input);
+	int i,j;
+	int length = strlen(input);
+	for (i = 0, j = 0; i < length, j < length; i++, j++) {
+		if (copy[j] != '\\') {
+			copy[i] = copy[j];
+			continue;
+		}
+
+		j += 1;
+		switch (copy[j]) {
+			case 'a':
+				copy[i] = '\a';
+				break;
+			case 'b':
+				copy[i] = '\b';
+				break;
+			case 'f':
+				copy[i] = '\f';
+				break;
+			case 'n':
+				copy[i] = '\n';
+				break;
+			case 'r':
+				copy[i] = '\r';
+				break;
+			case 't':
+				copy[i] = '\t';
+				break;
+			case 'v':
+				copy[i] = '\v';
+				break;
+			case '\\':
+				copy[i] = '\\';
+				break;
+			case '\'':
+				copy[i] = '\'';
+				break;
+			case '"':
+				copy[i] = '\"';
+				break;
+			case '?':
+				copy[i] = '\?';
+				break;
+		}
+	}
+	copy[j] = '\0';
+}
+
 /* read in the configuration file */
 int read_config_file(char *filename)
 {
@@ -881,6 +961,9 @@ int read_config_file(char *filename)
 		else if (!strcmp(varname, "dont_blame_nrpe"))
 			allow_arguments = (atoi(varvalue) == 1) ? TRUE : FALSE;
 
+		else if (!strcmp(varname, "disable_syslog"))
+			disable_syslog = (atoi(varvalue) == 1) ? TRUE : FALSE;
+
 		else if (!strcmp(varname, "allow_bash_command_substitution"))
 			allow_bash_cmd_subst = (atoi(varvalue) == 1) ? TRUE : FALSE;
 
@@ -926,7 +1009,11 @@ int read_config_file(char *filename)
 			}
 
 		} else if (!strcmp(varname, "ssl_version")) {
-			if (!strcmp(varvalue, "TLSv1.2"))
+			if (!strcmp(varvalue, "TLSv1.3"))
+				sslprm.ssl_proto_ver = TLSv1_3;
+			else if (!strcmp(varvalue, "TLSv1.3+"))
+				sslprm.ssl_proto_ver = TLSv1_3_plus;
+			else if (!strcmp(varvalue, "TLSv1.2"))
 				sslprm.ssl_proto_ver = TLSv1_2;
 			else if (!strcmp(varvalue, "TLSv1.2+"))
 				sslprm.ssl_proto_ver = TLSv1_2_plus;
@@ -1005,7 +1092,7 @@ int read_config_file(char *filename)
 			keep_env_vars = strdup(varvalue);
 
 		else if (!strcmp(varname, "nasty_metachars"))
-			nasty_metachars = strdup(varvalue);
+			nasty_metachars = process_metachars(varvalue);
 
 		else if (!strcmp(varname, "log_file")) {
 			log_file = strdup(varvalue);
@@ -1074,11 +1161,7 @@ int read_config_dir(char *dirname)
 				continue;
 
 			/* process the config file */
-			result = read_config_file(config_file);
-
-			/* break out if we encountered an error */
-			if (result == ERROR)
-				break;
+			result |= read_config_file(config_file);
 		}
 
 		/* recurse into subdirectories... */
@@ -1089,12 +1172,7 @@ int read_config_dir(char *dirname)
 				continue;
 
 			/* process the config directory */
-			result = read_config_dir(config_file);
-
-			/* break out if we encountered an error */
-			if (result == ERROR)
-				break;
-
+			result |= read_config_dir(config_file);
 		}
 	}
 
@@ -1834,7 +1912,10 @@ void handle_connection(int sock)
 
 	} else {
 
-		pkt_size = (sizeof(v3_packet) - 1) + strlen(send_buff);
+		pkt_size = (sizeof(v3_packet) - NRPE_V4_PACKET_SIZE_OFFSET) + strlen(send_buff);
+		if (packet_ver == NRPE_PACKET_VERSION_3) {
+			pkt_size = (sizeof(v3_packet) - NRPE_V3_PACKET_SIZE_OFFSET) + strlen(send_buff);
+		}
 		v3_send_packet = calloc(1, pkt_size);
 		send_pkt = (char *)v3_send_packet;
 		/* initialize response packet data */
@@ -1914,13 +1995,31 @@ int handle_conn_ssl(int sock, void *ssl_ptr)
 	char      buffer[MAX_INPUT_BUFFER];
 	SSL      *ssl = (SSL*)ssl_ptr;
 	X509     *peer;
-	int       rc, x;
+	int       rc, x, sockfd, retval;
+	fd_set    rfds;
+	struct timeval timeout;
 
 	SSL_set_fd(ssl, sock);
+	sockfd = SSL_get_fd(ssl);
+
+	FD_ZERO(&rfds);
+	FD_SET(sockfd, &rfds);
+
+	timeout.tv_sec = connection_timeout;
+	timeout.tv_usec = 0;
+
 
 	/* keep attempting the request if needed */
-	while (((rc = SSL_accept(ssl)) != 1)
-			&& (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ));
+	do {
+		retval = select(sockfd + 1, &rfds, NULL, NULL, &timeout);
+
+		if (retval > 0) {
+			rc = SSL_accept(ssl);
+		} else {
+			logit(LOG_ERR, "Error: (!log_opts) Could not complete SSL handshake with %s: timeout %d seconds", remote_host, connection_timeout);
+			return ERROR;
+		}
+	} while (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ);
 
 	if (rc != 1) {
 		/* oops, got an unrecoverable error -- get out */
@@ -2010,7 +2109,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
 			return -1;
 
 		packet_ver = ntohs(v2_pkt->packet_version);
-		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_4) {
 			logit(LOG_ERR, "Error: (use_ssl == false): Request packet version was invalid!");
 			return -1;
 		}
@@ -2037,6 +2136,10 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
 			tot_bytes += rc;
 
 			buffer_size = ntohl(buffer_size);
+			if (buffer_size < 0 || buffer_size > 65536) {
+				logit(LOG_ERR, "Error: (use_ssl == false): Received packet with invalid buffer size");
+				return -1;
+			}
 			pkt_size += buffer_size;
 			if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
 				logit(LOG_ERR, "Error: (use_ssl == false): Could not allocate memory for packet");
@@ -2063,16 +2166,34 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
 #ifdef HAVE_SSL
 	else {
 		SSL      *ssl = (SSL *) ssl_ptr;
+		int       sockfd, retval;
+		fd_set    rfds;
+		struct timeval timeout;
 
-		while (((rc = SSL_read(ssl, v2_pkt, bytes_to_recv)) <= 0)
-			   && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
-		}
+		sockfd = SSL_get_fd(ssl);
+
+		FD_ZERO(&rfds);
+		FD_SET(sockfd, &rfds);
+
+		timeout.tv_sec = connection_timeout;
+		timeout.tv_usec = 0;
+
+		do {
+			retval = select(sockfd + 1, &rfds, NULL, NULL, &timeout);
+
+			if (retval > 0) {
+				rc = SSL_read(ssl, v2_pkt, bytes_to_recv);
+			} else {
+				logit(LOG_ERR, "Error (!log_opts): Could not complete SSL_read with %s: timeout %d seconds", remote_host, connection_timeout);
+				return -1;
+			}
+		} while (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ);
 
 		if (rc <= 0 || rc != bytes_to_recv)
 			return -1;
 
 		packet_ver = ntohs(v2_pkt->packet_version);
-		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
+		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_4) {
 			logit(LOG_ERR, "Error: (use_ssl == true): Request packet version was invalid!");
 			return -1;
 		}
@@ -2081,7 +2202,13 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
 			buffer_size = sizeof(v2_packet) - common_size;
 			buff_ptr = (char *)v2_pkt + common_size;
 		} else {
-			int32_t   pkt_size = sizeof(v3_packet) - 1;
+			int32_t   pkt_size = sizeof(v3_packet);
+			if (packet_ver == NRPE_PACKET_VERSION_3) {
+				pkt_size -= NRPE_V3_PACKET_SIZE_OFFSET;
+			}
+			else if (packet_ver == NRPE_PACKET_VERSION_4) {
+				pkt_size -= NRPE_V4_PACKET_SIZE_OFFSET;
+			}
 
 			/* Read the alignment filler */
 			bytes_to_recv = sizeof(int16_t);
@@ -2104,6 +2231,10 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
 			tot_bytes += rc;
 
 			buffer_size = ntohl(buffer_size);
+			if (buffer_size < 0 || buffer_size > 65536) {
+				logit(LOG_ERR, "Error: (use_ssl == true): Received packet with invalid buffer size");
+				return -1;
+			}
 			pkt_size += buffer_size;
 			if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
 				logit(LOG_ERR, "Error: (use_ssl == true): Could not allocate memory for packet");
@@ -2606,6 +2737,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
 {
 	u_int32_t	packet_crc32;
 	u_int32_t	calculated_crc32;
+	int32_t		pkt_size, buffer_size;
 	char		*buff, *ptr;
 	int			rc;
 #ifdef ENABLE_COMMAND_ARGUMENTS
@@ -2613,8 +2745,18 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
 #endif
 
 	/* check the crc 32 value */
-	if (packet_ver == NRPE_PACKET_VERSION_3) {
-		int32_t   pkt_size = (sizeof(v3_packet) - 1) + ntohl(v3pkt->buffer_length);
+	if (packet_ver >= NRPE_PACKET_VERSION_3) {
+
+		buffer_size = ntohl(v3pkt->buffer_length);
+		if (buffer_size < 0 || buffer_size > INT_MAX - pkt_size) {
+			logit(LOG_ERR, "Error: Request packet had invalid buffer size.");
+			return ERROR;
+		}
+
+		pkt_size = sizeof(v3_packet);
+		pkt_size -= (packet_ver == NRPE_PACKET_VERSION_3 ? NRPE_V3_PACKET_SIZE_OFFSET : NRPE_V4_PACKET_SIZE_OFFSET);
+		pkt_size += buffer_size;
+
 		packet_crc32 = ntohl(v3pkt->crc32_value);
 		v3pkt->crc32_value = 0L;
 		v3pkt->alignment = 0;
@@ -2637,7 +2779,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
 	}
 
 	/* make sure buffer is terminated */
-	if (packet_ver == NRPE_PACKET_VERSION_3) {
+	if (packet_ver >= NRPE_PACKET_VERSION_3) {
 		int32_t   l = ntohs(v3pkt->buffer_length);
 		v3pkt->buffer[l - 1] = '\x0';
 		buff = v3pkt->buffer;
@@ -2653,7 +2795,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
 	}
 
 	/* make sure request doesn't contain nasties */
-	if (packet_ver == NRPE_PACKET_VERSION_3)
+	if (packet_ver >= NRPE_PACKET_VERSION_3)
 		rc = contains_nasty_metachars(v3pkt->buffer);
 	else
 		rc = contains_nasty_metachars(v2pkt->buffer);
@@ -2663,7 +2805,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
 	}
 
 	/* make sure the request doesn't contain arguments */
-	if (strchr(v2pkt->buffer, '!')) {
+	if (strchr(buff, '!')) {
 #ifdef ENABLE_COMMAND_ARGUMENTS
 		if (allow_arguments == FALSE) {
 			logit(LOG_ERR, "Error: Request contained command arguments, but argument option is not enabled!");


=====================================
src/utils.c
=====================================
@@ -537,7 +537,6 @@ void logit(int priority, const char *format, ...)
 
 	if (!format || !*format)
 		return;
-
 	va_start(ap, format);
 	if(vasprintf(&buffer, format, ap) > 0) {
 		if (log_fp) {
@@ -549,8 +548,9 @@ void logit(int priority, const char *format, ...)
 			fprintf(log_fp, "[%llu] %s\n", (unsigned long long)log_time, buffer);
 			fflush(log_fp);
 
-		} else
+		} else if (!disable_syslog) {
 			syslog(priority, "%s", buffer);
+		}
 
 		free(buffer);
 	}


=====================================
startup/default-xinetd.in
=====================================
@@ -10,6 +10,6 @@ service nrpe
     group           = @nrpe_group@
     server          = @sbindir@/nrpe
     server_args     = -c @pkgsysconfdir@/nrpe.cfg --inetd
-    only_from       = 127.0.0.1
+    only_from       = 127.0.0.1 ::1
     log_on_success  = 
 }


=====================================
startup/openrc-init.in
=====================================
@@ -3,15 +3,19 @@
 # Copyright (c) 2017 Nagios(R) Core(TM) Development Team
 #
 
+# Supply a default value for NRPE_CFG in case the corresponding
+# conf.d file is not installed.
+: ${NRPE_CFG:="@sysconfdir@/nrpe.cfg"}
+
 command="@sbindir@/nrpe"
 command_args="--config=${NRPE_CFG} ${NRPE_OPTS}"
 command_args_background="--daemon"
 description="Nagios Remote Plugin Executor (NRPE) daemon"
 extra_started_commands="reload"
-pidfile="@piddir@/nrpe.pid"
+pidfile="@piddir@/${RC_SVCNAME}.pid"
 
 reload() {
-    ebegin "Reloading ${SVCNAME}"
+    ebegin "Reloading ${RC_SVCNAME}"
     start-stop-daemon --signal HUP --pidfile "${pidfile}"
     eend $?
 }


=====================================
update-version
=====================================
@@ -28,10 +28,10 @@ else
 fi
 
 # Current version number
-CURRENTVERSION=3.2.1
+CURRENTVERSION=4.0.0
 
 # Last date
-LASTDATE=2017-09-01
+LASTDATE=2020-01-15
 
 if [ "x$1" = "x" ]
 then



View it on GitLab: https://salsa.debian.org/nagios-team/pkg-nrpe/commit/c80db299b19d5b683516b3db7396ce27e6e9052d

-- 
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-nrpe/commit/c80db299b19d5b683516b3db7396ce27e6e9052d
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20200116/76bca915/attachment-0001.html>


More information about the pkg-nagios-changes mailing list