def execute(self, parameters, message_uuid): """ execute an action :param parameters: list of parameters :param message_uuid: unique message id :return: """ # send-out syslog message if self.message is not None: log_message = '[%s] ' % message_uuid if self.message.count('%s') > 0 and parameters is not None and len(parameters) > 0: log_message = log_message + self.message % tuple(parameters[0:self.message.count('%s')]) else: log_message = log_message + self.message.replace("%s", "") syslog.syslog(syslog.LOG_NOTICE, log_message) # validate input if self.type is None: # no action type, nothing to do here return 'No action type' elif self.type.lower() in ('script', 'script_output'): # script type commands, basic script type only uses exit statuses, script_output sends back stdout data. if self.command is None: # no command supplied, exit syslog.syslog(syslog.LOG_ERR, '[%s] returned "No command"' % message_uuid) return 'No command' # build script command to execute, shared for both types script_command = self.command if self.parameters is not None and type(self.parameters) == str and len(parameters) > 0: script_command = '%s %s' % (script_command, self.parameters) if script_command.find('%s') > -1: # use command execution parameters in action parameter template # use quotes on parameters to prevent code injection script_command = script_command % tuple(map(lambda x: '"'+x.replace('"', '\\"')+'"', parameters[0:script_command.count('%s')])) if self.type.lower() == 'script': # execute script type command try: exit_status = subprocess.call(script_command, env=self.config_environment, shell=True) # send response if exit_status == 0: return 'OK' else: syslog.syslog(syslog.LOG_ERR, '[%s] returned exit status %d' % (message_uuid, exit_status)) return 'Error (%d)' % exit_status except: syslog.syslog(syslog.LOG_ERR, '[%s] Script action failed at %s' % (message_uuid, traceback.format_exc())) return 'Execute error' elif self.type.lower() == 'script_output': try: script_output = subprocess.check_output(script_command, env=self.config_environment, shell=True) return script_output except: syslog.syslog(syslog.LOG_ERR, '[%s] Script action failed at %s' % (message_uuid, traceback.format_exc())) return 'Execute error' # fallback should never get here return "type error" elif self.type.lower() == 'inline': # Handle inline service actions try: # match parameters, serialize to parameter string defined by action template if len(parameters) > 0: inline_act_parameters = self.parameters % tuple(parameters) else: inline_act_parameters = '' return ph_inline_actions.execute(self, inline_act_parameters) except: syslog.syslog(syslog.LOG_ERR, '[%s] Inline action failed at %s' % (message_uuid, traceback.format_exc())) return 'Execute error' return 'Unknown action type'
def execute(self, parameters, message_uuid): """ execute an action :param parameters: list of parameters :param message_uuid: unique message id :return: """ # send-out syslog message if self.message is not None: log_message = "[%s] " % message_uuid if self.message.count("%s") > 0 and parameters is not None and len(parameters) > 0: log_message = log_message + self.message % tuple(parameters[0 : self.message.count("%s")]) else: log_message = log_message + self.message.replace("%s", "") syslog.syslog(syslog.LOG_NOTICE, log_message) # validate input if self.type is None: # no action type, nothing to do here return "No action type" elif self.type.lower() in ("script", "script_output"): # script type commands, basic script type only uses exit statuses, script_output sends back stdout data. if self.command is None: # no command supplied, exit syslog.syslog(syslog.LOG_ERR, '[%s] returned "No command"' % message_uuid) return "No command" # build script command to execute, shared for both types script_command = self.command if self.parameters is not None and type(self.parameters) == str and len(parameters) > 0: script_command = "%s %s" % (script_command, self.parameters) if script_command.find("%s") > -1: # use command execution parameters in action parameter template # use quotes on parameters to prevent code injection if script_command.count("%s") > len(parameters): # script command accepts more parameters then given, fill with empty parameters for i in range(script_command.count("%s") - len(parameters)): parameters.append("") elif len(parameters) > script_command.count("%s"): # parameters then expected, fail execution return "Parameter mismatch" # force escape of shell exploitable characters for all user parameters for escape_char in ["`", "$", "!", "(", ")", "|"]: for i in range(len(parameters[0 : script_command.count("%s")])): parameters[i] = parameters[i].replace(escape_char, "\\%s" % escape_char) script_command = script_command % tuple( map(lambda x: '"' + x.replace('"', '\\"') + '"', parameters[0 : script_command.count("%s")]) ) if self.type.lower() == "script": # execute script type command try: exit_status = subprocess.call(script_command, env=self.config_environment, shell=True) # send response if exit_status == 0: return "OK" else: syslog.syslog(syslog.LOG_ERR, "[%s] returned exit status %d" % (message_uuid, exit_status)) return "Error (%d)" % exit_status except: syslog.syslog( syslog.LOG_ERR, "[%s] Script action failed at %s" % (message_uuid, traceback.format_exc()) ) return "Execute error" elif self.type.lower() == "script_output": try: with tempfile.NamedTemporaryFile() as error_stream: with tempfile.NamedTemporaryFile() as output_stream: subprocess.check_call( script_command, env=self.config_environment, shell=True, stdout=output_stream, stderr=error_stream, ) output_stream.seek(0) error_stream.seek(0) script_output = output_stream.read() script_error_output = error_stream.read() if len(script_error_output) > 0: syslog.syslog( syslog.LOG_ERR, '[%s] Script action stderr returned "%s"' % (message_uuid, script_error_output.strip()[:255]), ) return script_output except: syslog.syslog( syslog.LOG_ERR, "[%s] Script action failed at %s" % (message_uuid, traceback.format_exc()) ) return "Execute error" # fallback should never get here return "type error" elif self.type.lower() == "inline": # Handle inline service actions try: # match parameters, serialize to parameter string defined by action template if len(parameters) > 0: inline_act_parameters = self.parameters % tuple(parameters) else: inline_act_parameters = "" return ph_inline_actions.execute(self, inline_act_parameters) except: syslog.syslog( syslog.LOG_ERR, "[%s] Inline action failed at %s" % (message_uuid, traceback.format_exc()) ) return "Execute error" return "Unknown action type"
def execute(self, parameters, message_uuid): """ execute an action :param parameters: list of parameters :param message_uuid: unique message id :return: """ # send-out syslog message if self.message is not None: log_message = '[%s] ' % message_uuid if self.message.count('%s') > 0 and parameters is not None and len( parameters) > 0: log_message = log_message + self.message % tuple( parameters[0:self.message.count('%s')]) else: log_message = log_message + self.message.replace("%s", "") syslog.syslog(syslog.LOG_NOTICE, log_message) # validate input if self.type is None: # no action type, nothing to do here return 'No action type' elif self.type.lower() in ('script', 'script_output'): # script type commands, basic script type only uses exit statuses, script_output sends back stdout data. if self.command is None: # no command supplied, exit syslog.syslog(syslog.LOG_ERR, '[%s] returned "No command"' % message_uuid) return 'No command' # build script command to execute, shared for both types script_command = self.command if self.parameters is not None and type( self.parameters) == str and len(parameters) > 0: script_command = '%s %s' % (script_command, self.parameters) if script_command.find('%s') > -1: # use command execution parameters in action parameter template # use quotes on parameters to prevent code injection script_command = script_command % tuple( map(lambda x: '"' + x.replace('"', '\\"') + '"', parameters[0:script_command.count('%s')])) if self.type.lower() == 'script': # execute script type command try: exit_status = subprocess.call(script_command, shell=True) # send response if exit_status == 0: return 'OK' else: syslog.syslog( syslog.LOG_ERR, '[%s] returned exit status %d' % (message_uuid, exit_status)) return 'Error (%d)' % exit_status except: syslog.syslog( syslog.LOG_ERR, '[%s] Script action failed at %s' % (message_uuid, traceback.format_exc())) return 'Execute error' elif self.type.lower() == 'script_output': try: script_output = subprocess.check_output(script_command, shell=True) return script_output except: syslog.syslog( syslog.LOG_ERR, '[%s] Script action failed at %s' % (message_uuid, traceback.format_exc())) return 'Execute error' # fallback should never get here return "type error" elif self.type.lower() == 'inline': # Handle inline service actions try: # match parameters, serialize to parameter string defined by action template if len(parameters) > 0: inline_act_parameters = self.parameters % tuple(parameters) else: inline_act_parameters = '' return ph_inline_actions.execute(self, inline_act_parameters) except: syslog.syslog( syslog.LOG_ERR, '[%s] Inline action failed at %s' % (message_uuid, traceback.format_exc())) return 'Execute error' return 'Unknown action type'
def execute(self, parameters, message_uuid): """ execute an action :param parameters: list of parameters :param message_uuid: unique message id :return: """ # send-out syslog message if self.message is not None: log_message = '[%s] ' % message_uuid if self.message.count('%s') > 0 and parameters is not None and len(parameters) > 0: log_message = log_message + self.message % tuple(parameters[0:self.message.count('%s')]) else: log_message = log_message + self.message.replace("%s", "") syslog.syslog(syslog.LOG_NOTICE, log_message) # validate input if self.type is None: # no action type, nothing to do here return 'No action type' elif self.type.lower() in ('script', 'script_output'): # script type commands, basic script type only uses exit statuses, script_output sends back stdout data. if self.command is None: # no command supplied, exit syslog.syslog(syslog.LOG_ERR, '[%s] returned "No command"' % message_uuid) return 'No command' # build script command to execute, shared for both types script_command = self.command if self.parameters is not None and type(self.parameters) == str and len(parameters) > 0: script_command = '%s %s' % (script_command, self.parameters) if script_command.find('%s') > -1: # use command execution parameters in action parameter template # use quotes on parameters to prevent code injection if script_command.count('%s') > len(parameters): # script command accepts more parameters then given, fill with empty parameters for i in range(script_command.count('%s') - len(parameters)): parameters.append("") elif len(parameters) > script_command.count('%s'): # parameters then expected, fail execution return 'Parameter mismatch' # force escape of shell exploitable characters for all user parameters for escape_char in ['`', '$', '!', '(', ')', '|']: for i in range(len(parameters[0:script_command.count('%s')])): parameters[i] = parameters[i].replace(escape_char, '\\%s' % escape_char) script_command = script_command % tuple(map(lambda x: '"' + x.replace('"', '\\"') + '"', parameters[0:script_command.count('%s')])) if self.type.lower() == 'script': # execute script type command try: exit_status = subprocess.call(script_command, env=self.config_environment, shell=True) # send response if exit_status == 0: return 'OK' else: syslog.syslog(syslog.LOG_ERR, '[%s] returned exit status %d' % (message_uuid, exit_status)) return 'Error (%d)' % exit_status except Exception as script_exception: syslog.syslog(syslog.LOG_ERR, '[%s] Script action failed with %s at %s' % (message_uuid, script_exception, traceback.format_exc())) return 'Execute error' elif self.type.lower() == 'script_output': try: with tempfile.NamedTemporaryFile() as error_stream: with tempfile.NamedTemporaryFile() as output_stream: subprocess.check_call(script_command, env=self.config_environment, shell=True, stdout=output_stream, stderr=error_stream) output_stream.seek(0) error_stream.seek(0) script_output = output_stream.read() script_error_output = error_stream.read() if len(script_error_output) > 0: syslog.syslog(syslog.LOG_ERR, '[%s] Script action stderr returned "%s"' % (message_uuid, script_error_output.strip()[:255]) ) return script_output except Exception as script_exception: syslog.syslog(syslog.LOG_ERR, '[%s] Script action failed with %s at %s' % (message_uuid, script_exception, traceback.format_exc())) return 'Execute error' # fallback should never get here return "type error" elif self.type.lower() == 'inline': # Handle inline service actions try: # match parameters, serialize to parameter string defined by action template if len(parameters) > 0: inline_act_parameters = self.parameters % tuple(parameters) else: inline_act_parameters = '' return ph_inline_actions.execute(self, inline_act_parameters) except Exception as inline_exception: syslog.syslog(syslog.LOG_ERR, '[%s] Inline action failed with %s at %s' % (message_uuid, inline_exception, traceback.format_exc())) return 'Execute error' return 'Unknown action type'
def execute(self, parameters, message_uuid): """ execute an action :param parameters: list of parameters :param message_uuid: unique message id :return: """ # send-out syslog message if self.message is not None: log_message = '[%s] ' % message_uuid if self.message.count('%s') > 0 and parameters is not None and len(parameters) > 0: log_message = log_message + self.message % tuple(parameters[0:self.message.count('%s')]) else: log_message = log_message + self.message.replace("%s", "") syslog.syslog(syslog.LOG_NOTICE, log_message) # validate input if self.type is None: # no action type, nothing to do here return 'No action type' elif self.type.lower() in ('script', 'script_output'): # script type commands, basic script type only uses exit statuses, script_output sends back stdout data. if self.command is None: # no command supplied, exit syslog.syslog(syslog.LOG_ERR, '[%s] returned "No command"' % message_uuid) return 'No command' # build script command to execute, shared for both types script_command = self.command if self.parameters is not None and type(self.parameters) == str and len(parameters) > 0: script_arguments = self.parameters if script_arguments.find('%s') > -1: # use command execution parameters in action parameter template # use quotes on parameters to prevent code injection if script_arguments.count('%s') > len(parameters): # script command accepts more parameters than given, fill with empty parameters for i in range(script_arguments.count('%s') - len(parameters)): parameters.append("") elif len(parameters) > script_arguments.count('%s'): # more parameters than expected, fail execution return 'Parameter mismatch' # use single quotes to prevent command injection for i in range(len(parameters)): parameters[i] = "'" + parameters[i].replace("'", "'\"'\"'") + "'" # safely print the argument list now script_arguments = script_arguments % tuple(parameters) script_command = script_command + " " + script_arguments if self.type.lower() == 'script': # execute script type command try: exit_status = subprocess.call(script_command, env=self.config_environment, shell=True) # send response if exit_status == 0: return 'OK' else: syslog.syslog(syslog.LOG_ERR, '[%s] returned exit status %d' % (message_uuid, exit_status)) return 'Error (%d)' % exit_status except Exception as script_exception: syslog.syslog(syslog.LOG_ERR, '[%s] Script action failed with %s at %s' % (message_uuid, script_exception, traceback.format_exc())) return 'Execute error' elif self.type.lower() == 'script_output': try: with tempfile.NamedTemporaryFile() as error_stream: with tempfile.NamedTemporaryFile() as output_stream: subprocess.check_call(script_command, env=self.config_environment, shell=True, stdout=output_stream, stderr=error_stream) output_stream.seek(0) error_stream.seek(0) script_output = output_stream.read() script_error_output = error_stream.read() if len(script_error_output) > 0: syslog.syslog(syslog.LOG_ERR, '[%s] Script action stderr returned "%s"' % (message_uuid, script_error_output.strip()[:255]) ) return script_output except Exception as script_exception: syslog.syslog(syslog.LOG_ERR, '[%s] Script action failed with %s at %s' % (message_uuid, script_exception, traceback.format_exc())) return 'Execute error' # fallback should never get here return "type error" elif self.type.lower() == 'inline': # Handle inline service actions try: # match parameters, serialize to parameter string defined by action template if len(parameters) > 0: inline_act_parameters = self.parameters % tuple(parameters) else: inline_act_parameters = '' return ph_inline_actions.execute(self, inline_act_parameters) except Exception as inline_exception: syslog.syslog(syslog.LOG_ERR, '[%s] Inline action failed with %s at %s' % (message_uuid, inline_exception, traceback.format_exc())) return 'Execute error' return 'Unknown action type'