Esempio n. 1
0
    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'
Esempio n. 2
0
    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"
Esempio n. 3
0
    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'
Esempio n. 4
0
    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'
Esempio n. 5
0
    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'