def test_dont_log_methods_without_system_id(self):
        # we need a method that doesn't have a system_id parameter
        def api_method(not_system_id):
            pass

        auditlog_xmlrpc(api_method, "method_name", "args", "request")
        self.assertFalse(self.auditlog_server.log.called)
    def test_successful_logging_with_proxy(self):
        request = Mock()
        request.headers_in = {"SERVER_NAME": "server_name",
                              "REMOTE_ADDR": "remote_addr",
                              "SERVER_PORT": "server_port",
                              "DOCUMENT_ROOT": "document_root",
                              "SCRIPT_FILENAME": "script_filename",
                              "SCRIPT_URI": "script_uri",
                              "HTTP_X_RHN_PROXY_AUTH": "proxy_auth",
                              "HTTP_X_RHN_PROXY_VERSION": "proxy_version",
                              "HTTP_X_RHN_IP_PATH": "original_addr"}
        auditlog._get_server_id = Mock(return_value=("system_id", ("arg1", "arg2")))

        def api_method(system_id):
            pass

        auditlog_xmlrpc(api_method, "api_method_name", ["args"], request)

        self.assertEqual(self.auditlog_server.audit.log.call_args,
                         (('42(geeko)', "api_method_name('arg1', 'arg2')",
                           'server_name',
                           {'EVT.SRC': 'BACKEND_API',
                            'REQ.SCRIPT_URI': 'script_uri',
                            'REQ.SCRIPT_FILENAME': 'script_filename',
                            'REQ.REMOTE_ADDR': 'remote_addr',
                            'REQ.DOCUMENT_ROOT': 'document_root',
                            'REQ.SERVER_PORT': 'server_port',
                            'REQ.PROXY': 'proxy_auth',
                            'REQ.PROXY_VERSION': 'proxy_version',
                            'REQ.ORIGINAL_ADDR': 'original_addr'}), {}))
    def test_missing_header_values_in_proxy_sent_as_null_strings(self):
        request = Mock()
        request.headers_in = {
            "SERVER_NAME": "server_name",
            "HTTP_X_RHN_PROXY_AUTH": "proxy"
        }
        auditlog._get_server_id = Mock(return_value=("system_id", ("args", )))

        def api_method(system_id):
            pass

        auditlog_xmlrpc(api_method, "method_name", ["args"], request)
        self.assertEqual(
            self.auditlog_server.audit.log.call_args,
            (('42(geeko)', "method_name('args',)", 'server_name', {
                'EVT.SRC': 'BACKEND_API',
                'REQ.SCRIPT_URI': '',
                'REQ.SCRIPT_FILENAME': '',
                'REQ.REMOTE_ADDR': '',
                'REQ.DOCUMENT_ROOT': '',
                'REQ.SERVER_PORT': '',
                'REQ.PROXY': 'proxy',
                'REQ.PROXY_VERSION': '',
                'REQ.ORIGINAL_ADDR': ''
            }), {}))
    def test_missing_header_values_sent_as_null_strings(self):
        request = Mock()
        request.headers_in = {"SERVER_NAME": "server_name"}
        auditlog._get_server_id = Mock(return_value=("system_id", ("args",)))
        def api_method(system_id): pass

        auditlog_xmlrpc(api_method, "method_name", ["args"], request)
        self.assertEqual(self.auditlog_server.audit.log.call_args,
                         (('42(geeko)', "method_name('args',)", 'server_name',
                           {'EVT.SRC': 'BACKEND_API',
                            'REQ.SCRIPT_URI': '',
                            'REQ.SCRIPT_FILENAME': '',
                            'REQ.REMOTE_ADDR': '',
                            'REQ.DOCUMENT_ROOT': '',
                            'REQ.SERVER_PORT': ''}), {}))
    def test_logging_is_disabled(self):
        auditlog._read_config = Mock(return_value=(False, ""))

        auditlog_xmlrpc("method", "method_name", "args", "request")
        self.assertFalse(self.auditlog_server.log.called)
Exemple #6
0
    def call_function(self, method, params):
        # short-circuit everything if sending a system-wide message.
        if CFG.SEND_MESSAGE_TO_ALL:
            # Make sure the applet doesn't see the message
            if method == 'applet.poll_status':
                return self.response({
                    'checkin_interval': 3600,
                    'server_status': 'normal'
                })
            if method == 'applet.poll_packages':
                return self.response({'use_cached_copy': 1})

            # Fetch global message being sent to clients if applicable.
            msg = open(CFG.MESSAGE_TO_ALL).read()
            log_debug(3, "Sending message to all clients: %s" % msg)
            # Send the message as a fault.
            response = xmlrpclib.Fault(
                -1, _("IMPORTANT MESSAGE FOLLOWS:\n%s") % msg)
            # and now send everything back
            ret = self.response(response)
            log_debug(4, "Leave with return value", ret)
            return ret

        # req: where the response is sent to
        log_debug(2, method)

        # Now we have the reference, call away
        force_rollback = 1
        func = None
        try:
            # now get the function reference and call it
            func = self.method_ref(method)
            response = func(*params)
        except (TypeError, ValueError, KeyError, IndexError, UnknownXML):
            # report exception back to server
            fault = 1

            if sys.version_info[0] == 3:
                exctype = sys.exc_info()[0]
            else:
                exctype = sys.exc_info()[0]

            if exctype == UnknownXML:
                fault = -1
            e_type, e_value = sys.exc_info()[:2]
            response = xmlrpclib.Fault(fault, _(
                "While running '%s': caught\n%s : %s\n") % (
                method, e_type, e_value))
            Traceback(method, self.req,
                      extra="Response sent back to the caller:\n%s\n" % (
                          response.faultString,),
                      severity="notification")
        except rhnNotFound:
            e = sys.exc_info()[1]
            return apache.HTTP_NOT_FOUND
        # pkilambi:catch exception if redirect
        except redirectException:
            re = sys.exc_info()[1]
            log_debug(3, "redirect exception caught", re.path)
            response = re.path

        except rhnFault:
            f = sys.exc_info()[1]
            response = f.getxml()
        except rhnSQL.SQLSchemaError:
            e = sys.exc_info()[1]
            f = None
            if e.errno == 20200:
                log_debug(2, "User Group Membership EXCEEDED")
                f = rhnFault(43, e.errmsg)
            if not f:
                log_error("rhnSQL.SQLSchemaError caught", e)
                rhnSQL.rollback()
                # generate the traceback report
                Traceback(method, self.req,
                          extra="SQL Error generated: %s" % e,
                          severity="schema")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            response = f.getxml()
        except rhnSQL.SQLError:
            e = sys.exc_info()[1]
            log_error("rhnSQL.SQLError caught", e)
            rhnSQL.rollback()
            Traceback(method, self.req,
                      extra="SQL Error generated: %s" % e,
                      severity="schema")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        except Exception:
            e = sys.exc_info()[1]
            log_error("Unhandled exception", e)
            rhnSQL.rollback()
            # otherwise we do a full stop
            Traceback(method, self.req, severity="unhandled")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        else:
            # if no exception, we don't need to rollback
            force_rollback = 0
        if force_rollback:
            rhnSQL.rollback()

        # we only want to log successful actions at this time, that's
        # why we do it here. Note: "func" might be None, in this case
        # it will cause AuditLogException below.
        try:
            auditlog_xmlrpc(func, method, params, self.req)
        except AuditLogException as e:
            # if logging didn't succeed, cancel the whole action
            rhnSQL.rollback()
            Traceback(method, self.req,
                      extra="AuditLogging error: %s" % e)
            return apache.HTTP_INTERNAL_SERVER_ERROR
        # and now send everything back
        ret = self.response(response)

        # we only want to log successful actions at this time, that's
        # why we do it here
        auditlog_xmlrpc(func, method, params, self.req)

        log_debug(4, "Leave with return value", ret)
        return ret
Exemple #7
0
class apacheRequest:
    def __init__(self, client_version, req):
        self.client = client_version
        self.req = req
        # grab an Input object
        self.input = transports.Input(req.headers_in)
        # make sure we have a parser and a decoder available
        self.parser, self.decoder = xmlrpclib.getparser()
        # Make sure the decoder doesn't assume UTF-8 data, that would break if
        # non-UTF-8 chars are sent (bug 139370)
        self.decoder._encoding = None

        # extract the server we're talking to and the root directory
        # from the request configuration options
        req_config = req.get_options()
        # XXX: attempt to catch these KeyErrors sometime when there is
        # time to play nicely
        self.server = req_config["SERVER"]
        # Load the server classes
        # XXX: some day we're going to trust the timestamp stuff...
        self.servers = None
        self._setup_servers()

    def _setup_servers(self):
        self.servers = rhnImport.load("server/handlers",
                                      interface_signature='rpcClasses')

    # return a reference to a method name. The method in the base
    def method_ref(self, method):
        raise UnknownXML("Could not find reference definition"
                         "for method '%s'" % method)

    # call a function with parameters
    def call_function(self, method, params):
        # short-circuit everything if sending a system-wide message.
        if CFG.SEND_MESSAGE_TO_ALL:
            # Make sure the applet doesn't see the message
            if method == 'applet.poll_status':
                return self.response({
                    'checkin_interval': 3600,
                    'server_status': 'normal'
                })
            if method == 'applet.poll_packages':
                return self.response({'use_cached_copy': 1})

            # Fetch global message being sent to clients if applicable.
            msg = open(CFG.MESSAGE_TO_ALL).read()
            log_debug(3, "Sending message to all clients: %s" % msg)
            # Send the message as a fault.
            response = xmlrpclib.Fault(
                -1,
                _("IMPORTANT MESSAGE FOLLOWS:\n%s") % msg)
            # and now send everything back
            ret = self.response(response)
            log_debug(4, "Leave with return value", ret)
            return ret

        # req: where the response is sent to
        log_debug(2, method)

        # Now we have the reference, call away
        force_rollback = 1
        func = None
        try:
            # now get the function reference and call it
            func = self.method_ref(method)
            response = func(*params)
        except (TypeError, ValueError, KeyError, IndexError, UnknownXML):
            # report exception back to server
            fault = 1

            if sys.version_info[0] == 3:
                exctype = sys.exc_info()[0]
            else:
                exctype = sys.exc_type

            if exctype == UnknownXML:
                fault = -1
            e_type, e_value = sys.exc_info()[:2]
            response = xmlrpclib.Fault(
                fault,
                _("While running '%s': caught\n%s : %s\n") %
                (method, e_type, e_value))
            Traceback(method,
                      self.req,
                      extra="Response sent back to the caller:\n%s\n" %
                      (response.faultString, ),
                      severity="notification")
        except rhnNotFound:
            e = sys.exc_info()[1]
            return apache.HTTP_NOT_FOUND
        # pkilambi:catch exception if redirect
        except redirectException:
            re = sys.exc_info()[1]
            log_debug(3, "redirect exception caught", re.path)
            response = re.path

        except rhnFault:
            f = sys.exc_info()[1]
            response = f.getxml()
        except rhnSQL.SQLSchemaError:
            e = sys.exc_info()[1]
            f = None
            if e.errno == 20200:
                log_debug(2, "User Group Membership EXCEEDED")
                f = rhnFault(43, e.errmsg)
            if not f:
                log_error("rhnSQL.SQLSchemaError caught", e)
                rhnSQL.rollback()
                # generate the traceback report
                Traceback(method,
                          self.req,
                          extra="SQL Error generated: %s" % e,
                          severity="schema")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            response = f.getxml()
        except rhnSQL.SQLError:
            e = sys.exc_info()[1]
            log_error("rhnSQL.SQLError caught", e)
            rhnSQL.rollback()
            Traceback(method,
                      self.req,
                      extra="SQL Error generated: %s" % e,
                      severity="schema")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        except Exception:
            e = sys.exc_info()[1]
            log_error("Unhandled exception", e)
            rhnSQL.rollback()
            # otherwise we do a full stop
            Traceback(method, self.req, severity="unhandled")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        else:
            # if no exception, we don't need to rollback
            force_rollback = 0
        if force_rollback:
            rhnSQL.rollback()

        # we only want to log successful actions at this time, that's
        # why we do it here. Note: "func" might be None, in this case
        # it will cause AuditLogException below.
        try:
            auditlog_xmlrpc(func, method, params, self.req)
        except AuditLogException, e:
            # if logging didn't succeed, cancel the whole action
            rhnSQL.rollback()
            Traceback(method, self.req, extra="AuditLogging error: %s" % e)
            return apache.HTTP_INTERNAL_SERVER_ERROR
        # and now send everything back
        ret = self.response(response)

        # we only want to log successful actions at this time, that's
        # why we do it here
        auditlog_xmlrpc(func, method, params, self.req)

        log_debug(4, "Leave with return value", ret)
        return ret
Exemple #8
0
    def call_function(self, method, params):
        # short-circuit everything if sending a system-wide message.
        if CFG.SEND_MESSAGE_TO_ALL:
            # Make sure the applet doesn't see the message
            if method == 'applet.poll_status':
                return self.response({
                    'checkin_interval': 3600,
                    'server_status': 'normal'
                })
            if method == 'applet.poll_packages':
                return self.response({'use_cached_copy': 1})

            # Fetch global message being sent to clients if applicable.
            msg = open(CFG.MESSAGE_TO_ALL).read()
            log_debug(3, "Sending message to all clients: %s" % msg)
            # Send the message as a fault.
            response = xmlrpclib.Fault(
                -1, _("IMPORTANT MESSAGE FOLLOWS:\n%s") % msg)
            # and now send everything back
            ret = self.response(response)
            log_debug(4, "Leave with return value", ret)
            return ret

        # req: where the response is sent to
        log_debug(2, method)

        # Now we have the reference, call away
        force_rollback = 1
        func = None
        try:
            # now get the function reference and call it
            func = self.method_ref(method)
            response = func(*params)
        except (TypeError, ValueError, KeyError, IndexError, UnknownXML):
            # report exception back to server
            fault = 1

            if sys.version_info[0] == 3:
                exctype = sys.exc_info()[0]
            else:
                exctype = sys.exc_type

            if exctype == UnknownXML:
                fault = -1
            e_type, e_value = sys.exc_info()[:2]
            response = xmlrpclib.Fault(fault, _(
                "While running '%s': caught\n%s : %s\n") % (
                method, e_type, e_value))
            Traceback(method, self.req,
                      extra="Response sent back to the caller:\n%s\n" % (
                          response.faultString,),
                      severity="notification")
        except rhnNotFound:
            e = sys.exc_info()[1]
            return apache.HTTP_NOT_FOUND
        # pkilambi:catch exception if redirect
        except redirectException:
            re = sys.exc_info()[1]
            log_debug(3, "redirect exception caught", re.path)
            response = re.path

        except rhnFault:
            f = sys.exc_info()[1]
            response = f.getxml()
        except rhnSQL.SQLSchemaError:
            e = sys.exc_info()[1]
            f = None
            if e.errno == 20200:
                log_debug(2, "User Group Membership EXCEEDED")
                f = rhnFault(43, e.errmsg)
            if not f:
                log_error("rhnSQL.SQLSchemaError caught", e)
                rhnSQL.rollback()
                # generate the traceback report
                Traceback(method, self.req,
                          extra="SQL Error generated: %s" % e,
                          severity="schema")
                return apache.HTTP_INTERNAL_SERVER_ERROR
            response = f.getxml()
        except rhnSQL.SQLError:
            e = sys.exc_info()[1]
            log_error("rhnSQL.SQLError caught", e)
            rhnSQL.rollback()
            Traceback(method, self.req,
                      extra="SQL Error generated: %s" % e,
                      severity="schema")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        except Exception:
            e = sys.exc_info()[1]
            log_error("Unhandled exception", e)
            rhnSQL.rollback()
            # otherwise we do a full stop
            Traceback(method, self.req, severity="unhandled")
            return apache.HTTP_INTERNAL_SERVER_ERROR
        else:
            # if no exception, we don't need to rollback
            force_rollback = 0
        if force_rollback:
            rhnSQL.rollback()

        # we only want to log successful actions at this time, that's
        # why we do it here. Note: "func" might be None, in this case
        # it will cause AuditLogException below.
        try:
            auditlog_xmlrpc(func, method, params, self.req)
        except AuditLogException, e:
            # if logging didn't succeed, cancel the whole action
            rhnSQL.rollback()
            Traceback(method, self.req,
                      extra="AuditLogging error: %s" % e)
            return apache.HTTP_INTERNAL_SERVER_ERROR