[PATCH] NRPE: regular expression checks for command arguments
Bjoern Beutel
bjoern-beutel at arcor.de
Fri Mar 21 19:04:31 CET 2008
Hi everybody!
The following patch for the NRPE agent adds a regular expression check facility
for command arguments, using POSIX' extended regular expressions via regcomp()/regexec().
This makes NRPE a little bit safer for uses where command arguments are needed.
Example:
I have the following command definitions in "nrpe.cfg":
command[check_echo1]=/bin/echo $ARG1=start|stop$
command[check_echo2]=/bin/echo $ARG1=[A-Za-z]+$
So the format of a macro is "$ARG<x>=<re>$", where "=<re>" is optional.
NRPE will match the command line arguments against "^(<re>)$",
and reject the arguments that don't match:
bjoern at james:~$ check_nrpe -H localhost -c check_echo1 -a start
start
bjoern at james:~$ check_nrpe -H localhost -c check_echo1 -a stop
stop
bjoern at james:~$ check_nrpe -H localhost -c check_echo1 -a reload
NRPE: Malformed macro in command 'check_echo1'
bjoern at james:~$ check_nrpe -H localhost -c check_echo2 -a something
something
bjoern at james:~$ check_nrpe -H localhost -c check_echo2 -a "something dangerous"
NRPE: Malformed macro in command 'check_echo2'
Regards,
Bjoern Beutel
------------------------------ snip ------------------------------------------
diff -rU 3 nrpe-2.12/configure.in nrpe-regexp/configure.in
--- nrpe-2.12/configure.in 2008-03-10 22:04:41.000000000 +0100
+++ nrpe-regexp/configure.in 2008-03-21 18:52:24.000000000 +0100
@@ -28,7 +28,7 @@
AC_HEADER_STDC
AC_HEADER_TIME
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(ctype.h dirent.h errno.h fcntl.h getopt.h grp.h inttypes.h netdb.h pwd.h signal.h stdint.h strings.h string.h syslog.h tcpd.h unistd.h arpa/inet.h netinet/in.h socket.h sys/types.h sys/time.h sys/resource.h sys/wait.h sys/socket.h sys/stat.h)
+AC_CHECK_HEADERS(ctype.h dirent.h errno.h fcntl.h getopt.h grp.h inttypes.h netdb.h pwd.h signal.h stdint.h strings.h string.h syslog.h tcpd.h unistd.h arpa/inet.h netinet/in.h socket.h sys/types.h sys/time.h sys/resource.h sys/wait.h sys/socket.h sys/stat.h regex.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
diff -rU 3 nrpe-2.12/include/config.h.in nrpe-regexp/include/config.h.in
--- nrpe-2.12/include/config.h.in 2007-11-23 18:31:23.000000000 +0100
+++ nrpe-regexp/include/config.h.in 2008-03-21 18:50:26.000000000 +0100
@@ -243,6 +243,11 @@
#include <rand.h>
#endif
+#undef HAVE_REGEX_H
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
#undef HAVE_KRB5_H
#ifdef HAVE_KRB5_H
#include <krb5.h>
diff -rU 3 nrpe-2.12/src/nrpe.c nrpe-regexp/src/nrpe.c
--- nrpe-2.12/src/nrpe.c 2008-03-10 22:04:43.000000000 +0100
+++ nrpe-regexp/src/nrpe.c 2008-03-21 18:27:38.000000000 +0100
@@ -1199,38 +1199,44 @@
else
snprintf(raw_command,sizeof(raw_command)-1,"%s %s",command_prefix,temp_command->command_line);
raw_command[sizeof(raw_command)-1]='\x0';
- process_macros(raw_command,processed_command,sizeof(processed_command));
-
- /* log info to syslog facility */
- if(debug==TRUE)
- syslog(LOG_DEBUG,"Running command: %s",processed_command);
-
- /* run the command */
- strcpy(buffer,"");
- result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer));
-
- /* log debug info */
- if(debug==TRUE)
- syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer);
-
- /* see if the command timed out */
- if(early_timeout==TRUE)
- snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout);
- else if(!strcmp(buffer,""))
- snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n");
-
- buffer[sizeof(buffer)-1]='\x0';
-
- /* check return code bounds */
- if((result<0) || (result>3)){
+ if (process_macros(raw_command,processed_command,sizeof(processed_command) == ERROR)){
+ snprintf(buffer,sizeof(buffer), "NRPE: Malformed macro in command '%s'",command_name);
/* log error to syslog facility */
- syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result);
-
- result=STATE_UNKNOWN;
- }
+ if (debug==TRUE)
+ syslog(LOG_DEBUG,"%s",buffer);
+ result=STATE_CRITICAL;
+ } else {
+ /* log info to syslog facility */
+ if(debug==TRUE)
+ syslog(LOG_DEBUG,"Running command: %s",processed_command);
+
+ /* run the command */
+ strcpy(buffer,"");
+ result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer));
+
+ /* log debug info */
+ if(debug==TRUE)
+ syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer);
+
+ /* see if the command timed out */
+ if(early_timeout==TRUE)
+ snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout);
+ else if(!strcmp(buffer,""))
+ snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n");
+
+ buffer[sizeof(buffer)-1]='\x0';
+
+ /* check return code bounds */
+ if((result<0) || (result>3)){
+ /* log error to syslog facility */
+ syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result);
+
+ result=STATE_UNKNOWN;
+ }
}
- }
+ }
+ }
/* free memory */
free(command_name);
@@ -1856,9 +1862,31 @@
/* argument macro */
if(strstr(temp_buffer,"ARG")==temp_buffer){
arg_index=atoi(temp_buffer+3);
- if(arg_index>=1 && arg_index<=MAX_COMMAND_ARGUMENTS)
+ if(arg_index>=1 && arg_index<=MAX_COMMAND_ARGUMENTS){
+ char re_buffer[MAX_INPUT_BUFFER];
+ regex_t regexp;
+ char *s;
+
selected_macro=macro_argv[arg_index-1];
- }
+
+ /* For an $ARGx=<regexp>$ macro, check whether argument matches. */
+ for (s=temp_buffer+3;isdigit(*s);s++);
+ if (*s=='='){
+
+ snprintf(re_buffer, MAX_INPUT_BUFFER, "^(%s)$", ++s);
+ if (regcomp(®exp,re_buffer,REG_EXTENDED|REG_NOSUB|REG_NEWLINE)){
+ regfree(®exp);
+ return ERROR;
+ }
+ if (regexec(®exp,selected_macro,0,NULL,0)){
+ regfree(®exp);
+ return ERROR;
+ }
+ regfree(®exp);
+ } else if (*s!='\0')
+ return ERROR;
+ }
+ }
/* an escaped $ is done by specifying two $$ next to each other */
else if(!strcmp(temp_buffer,"")){
--------------------------- snip -------------------------------------
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
More information about the Developers
mailing list