Ejemplo n.º 1
0
    def analyze(self):
        tcontext = self.tcontext.to_string()
        scontext = self.scontext.to_string()
        access_tuple = tuple( self.accesses)
        self.data = []

        if (scontext, tcontext, self.tclass, access_tuple) in avcdict.keys():
            self.type, self.data = avcdict[(scontext, tcontext, self.tclass, access_tuple)]
        else:
            self.type, self.data = audit2why.analyze(scontext, tcontext, self.tclass, self.accesses);
            if self.type == audit2why.NOPOLICY:
                self.type = audit2why.TERULE
            if self.type == audit2why.BADTCON:
                raise ValueError("Invalid Target Context %s\n" % tcontext)
            if self.type == audit2why.BADSCON:
                raise ValueError("Invalid Source Context %s\n" % scontext)
            if self.type == audit2why.BADSCON:
                raise ValueError("Invalid Type Class %s\n" % self.tclass)
            if self.type == audit2why.BADPERM:
                raise ValueError("Invalid permission %s\n" % " ".join(self.accesses))
            if self.type == audit2why.BADCOMPUTE:
                raise ValueError("Error during access vector computation")

            if self.type == audit2why.CONSTRAINT:
                self.data = [ self.data ]
                if self.scontext.user != self.tcontext.user:
                    self.data.append(("user (%s)" % self.scontext.user, 'user (%s)' % self.tcontext.user))
                if self.scontext.role != self.tcontext.role and self.tcontext.role != "object_r":
                    self.data.append(("role (%s)" % self.scontext.role, 'role (%s)' % self.tcontext.role))
                if self.scontext.level != self.tcontext.level:
                    self.data.append(("level (%s)" % self.scontext.level, 'level (%s)' % self.tcontext.level))

            avcdict[(scontext, tcontext, self.tclass, access_tuple)] = (self.type, self.data)
Ejemplo n.º 2
0
    def derive_avc_info_from_audit_event(self):
        self.tpath = None
        self.spath = None
        self.source = None
        self.a1 = None
        self.success = False
        self.syscall_paths = []
        exe = comm = arch = syscall = None

        self.avc_record = self.audit_event.get_avc_record()
        syscall_record = self.audit_event.get_record_of_type('SYSCALL')

        self.access = self.avc_record.get_field('seperms')
        if not isinstance(self.scontext, AvcContext):
            self.scontext = AvcContext(self.avc_record.get_field('scontext'))

        if not isinstance(self.tcontext, AvcContext):
            self.tcontext = AvcContext(self.avc_record.get_field('tcontext'))

        self.tclass = self.avc_record.get_field('tclass')

        if self.avc_record.get_field('dest') is None:
            self.port = self.avc_record.get_field('src')
        else:
            self.port = self.avc_record.get_field('dest')

        self._set_tpath()

        self.kmod = self.avc_record.get_field('kmod')

        self.pid = self.avc_record.get_field('pid')

        # exe, cwd, name, path, key, dir, comm, ocomm, key_desc

        if syscall_record:
            exe = syscall_record.get_field('exe')
            try:
                exe.decode("hex")
            except:
                pass
            comm = syscall_record.get_field('comm')
            self.syscall = syscall_record.get_field('syscall')
            self.success = (syscall_record.get_field('success') == "yes")
            self.a1 = syscall_record.get_field('a1')

        if comm is None:
            comm = self.avc_record.get_field('comm')
        if exe is None:
            exe = self.avc_record.get_field('exe')

        try:
            self.spath = exe.decode("hex")
        except:
            self.spath = exe

        if comm:
            self.source = comm
        elif exe:
            self.source = self.spath

        if not self.spath:
            self.spath = self.source

        if not self.spath:
            self.spath = self.scontext.type

        cwd_record = self.audit_event.get_record_of_type('CWD')
        if cwd_record:
            cwd = cwd_record.get_field('cwd')
        else:
            cwd = None

        path_records = self.audit_event.get_records_of_type('PATH')
        for path_record in path_records:
            path = path_record.get_field('name')
            if os.path.isabs(path) or not cwd:
                self.syscall_paths.append(path)
            else:
                self.syscall_paths.append(os.path.join(cwd, path))

        self.src_rpms = []
        self.tgt_rpms = []

        self.host = self.audit_event.event_id.host

        self.why, bools = audit2why.analyze(str(self.scontext),
                                            str(self.tcontext),
                                            str(self.tclass), self.access)
        if self.why == audit2why.ALLOW:
            raise ValueError(
                _("%s \n**** Invalid AVC allowed in current policy ***\n") %
                self.avc_record)
        if self.why == audit2why.DONTAUDIT:
            raise ValueError(
                _("%s \n**** Invalid AVC dontaudited in current policy.  'semodule -B' will turn on dontaudit rules. ***\n"
                  ) % self.avc_record)
        if self.why == audit2why.NOPOLICY:
            raise ValueError(_("Must call policy_init first"))
        if self.why == audit2why.BADTCON:
            raise ValueError(
                _("%s \n**** Invalid AVC bad target context. ***\n") %
                self.avc_record)
        if self.why == audit2why.BADSCON:
            raise ValueError(
                _("%s \n**** Invalid AVC bad source context. ***\n") %
                self.avc_record)
        if self.why == audit2why.BADSCON:
            raise ValueError(
                _("%s \n**** Invalid AVC bad type class ***\n") %
                self.avc_record)
        if self.why == audit2why.BADPERM:
            raise ValueError(
                _("%s \n**** Invalid AVC bad permission ***\n") %
                self.avc_record)
        if self.why == audit2why.BADCOMPUTE:
            raise ValueError(_("Error during access vector computation"))
        if self.why == audit2why.BOOLEAN:
            self.bools = bools
Ejemplo n.º 3
0
def RunFaultServer(timeout=10):
    # FIXME
    audit2why.init()
    global host_database, analysis_queue, email_recipients

    signal.signal(signal.SIGHUP, sighandler)
    signal.signal(signal.SIGQUIT, sighandler)
    signal.signal(signal.SIGTERM, sighandler)
    signal.signal(signal.SIGALRM, sighandler)

    #interface_registry.dump_interfaces()

    try:
        # FIXME: should this be using our logging objects in log.py?
        # currently syslog is only used for putting an alert into
        # the syslog with it's id

        pkg_name = get_config('general', 'pkg_name')
        syslog.openlog(pkg_name)

        # Create an object responsible for sending notifications to clients
        client_notifier = ClientNotifier(connection_pool)

        # Create a database local to this host

        database_filename = get_config('database', 'filename')
        database_filepath = make_database_filepath(database_filename)
        assure_file_ownership_permissions(database_filepath, 0600,
                                          'setroubleshoot')
        host_database = SETroubleshootDatabase(
            database_filepath,
            database_filename,
            friendly_name=_("Audit Listener"))
        host_database.set_notify(client_notifier)

        atexit.register(goodbye, host_database)

        deleted = False
        for i in host_database.sigs.signature_list:
            why, bools = audit2why.analyze(str(i.sig.scontext),
                                           str(i.sig.tcontext),
                                           str(i.sig.tclass), i.sig.access)
            if why == audit2why.ALLOW or why == audit2why.DONTAUDIT:
                if why == audit2why.ALLOW:
                    reason = "allowed"
                else:
                    reason = "dontaudit'd"
                syslog.syslog(
                    syslog.LOG_ERR,
                    "Deleting alert %s, it is %s in current policy" %
                    (i.local_id, reason))
                deleted = True
                host_database.delete_signature(i.sig)
        if deleted:
            host_database.save(prune=True)
        # Attach the local database to an object which will send alerts
        # specific to this host

        if not get_config('test', 'analyze', bool):
            alert_receiver = AlertPluginReportReceiver(host_database)
        else:
            alert_receiver = TestPluginReportReceiver(host_database)

        # Create a synchronized queue for analysis requests
        import Queue
        analysis_queue = Queue.Queue(0)

        # Create a thread to peform analysis, it takes AVC objects off
        # the analysis queue and runs the plugins against the
        # AVC. Analysis requests in the queue may arrive from a
        # variety of places; from the audit system, from a log file
        # scan, etc. The disposition of the analysis (e.g. where the
        # results of the analysis are to go) are included in the queued
        # object along with the data to analyze.

        analyze_thread = AnalyzeThread(analysis_queue)
        analyze_thread.setDaemon(True)
        analyze_thread.start()

        # Create a thread to receive messages from the audit system.
        # This is a time sensitive operation, the primary job of this
        # thread is to receive the audit message as quickly as
        # possible and return to listening on the audit socket. When
        # it receives a complete audit event it places it in the
        # analysis queue where another thread will process it
        # independently.

        #        audit_socket_thread = AuditSocketReceiverThread(analysis_queue, alert_receiver)
        #        audit_socket_thread.setDaemon(True)
        #        audit_socket_thread.start()

        # Initialize the email recipient list
        from setroubleshoot.signature import SEEmailRecipientSet
        email_recipients = SEEmailRecipientSet()
        assure_file_ownership_permissions(email_recipients_filepath, 0600,
                                          'setroubleshoot')
        try:
            email_recipients.parse_recipient_file(email_recipients_filepath)
        except ProgramError, e:
            if e.errno == ERR_FILE_OPEN:
                log_debug(e.strerror)
            else:
                raise e

        # Create a server to listen for alert clients and then run.
        listen_addresses = get_socket_list_from_config('listen_for_client')
        for listen_address in listen_addresses:
            listening_server = ListeningServer(
                listen_address, SetroubleshootdClientConnectionHandler)
            listening_server.open()

        dbus.glib.init_threads()
        setroubleshootd_dbus = SetroubleshootdDBus(analysis_queue,
                                                   alert_receiver, timeout)
        main_loop = gobject.MainLoop()
        main_loop.run()
Ejemplo n.º 4
0
def RunFaultServer(timeout=10):
    # FIXME
    audit2why.init()
    global host_database, analysis_queue, email_recipients

    signal.signal(signal.SIGHUP, sighandler)
    signal.signal(signal.SIGQUIT, sighandler)
    signal.signal(signal.SIGTERM, sighandler)
    signal.signal(signal.SIGALRM, sighandler)

    #interface_registry.dump_interfaces()

    try:
        # FIXME: should this be using our logging objects in log.py?
        # currently syslog is only used for putting an alert into
        # the syslog with it's id

        pkg_name = get_config('general','pkg_name')
        syslog.openlog(pkg_name)

        # Create an object responsible for sending notifications to clients
        client_notifier = ClientNotifier(connection_pool)

        # Create a database local to this host
        
        database_filename = get_config('database','filename')
        database_filepath = make_database_filepath(database_filename)
        assure_file_ownership_permissions(database_filepath, 0600, 'root', 'root')
        host_database = SETroubleshootDatabase(database_filepath, database_filename,
                                               friendly_name=_("Audit Listener"))
        host_database.set_notify(client_notifier)

        atexit.register(goodbye, host_database)

        deleted = False
        for i in host_database.sigs.signature_list:
            why, bools = audit2why.analyze(str(i.sig.scontext), str(i.sig.tcontext), str(i.sig.tclass), i.sig.access)
            if why == audit2why.ALLOW or why == audit2why.DONTAUDIT:
                if why == audit2why.ALLOW:
                    reason = "allowed"
                else:
                    reason = "dontaudit'd"
                syslog.syslog(syslog.LOG_ERR, "Deleting alert %s, it is %s in current policy" % (i.local_id, reason) )
                deleted = True
                host_database.delete_signature(i.sig)
        if deleted:
            host_database.save(prune=True)
        # Attach the local database to an object which will send alerts
        # specific to this host

        if not get_config('test', 'analyze', bool):
            alert_receiver = AlertPluginReportReceiver(host_database)
        else:
            alert_receiver = TestPluginReportReceiver(host_database)

        # Create a synchronized queue for analysis requests
        import Queue
        analysis_queue = Queue.Queue(0)

        # Create a thread to peform analysis, it takes AVC objects off
        # the analysis queue and runs the plugins against the
        # AVC. Analysis requests in the queue may arrive from a
        # variety of places; from the audit system, from a log file
        # scan, etc. The disposition of the analysis (e.g. where the
        # results of the analysis are to go) are included in the queued
        # object along with the data to analyze.

        analyze_thread = AnalyzeThread(analysis_queue)
        analyze_thread.setDaemon(True)
        analyze_thread.start()
    
        # Create a thread to receive messages from the audit system.
        # This is a time sensitive operation, the primary job of this
        # thread is to receive the audit message as quickly as
        # possible and return to listening on the audit socket. When
        # it receives a complete audit event it places it in the
        # analysis queue where another thread will process it
        # independently.

#        audit_socket_thread = AuditSocketReceiverThread(analysis_queue, alert_receiver)
#        audit_socket_thread.setDaemon(True)
#        audit_socket_thread.start()

        # Initialize the email recipient list
        from setroubleshoot.signature import SEEmailRecipientSet
        email_recipients = SEEmailRecipientSet()
        assure_file_ownership_permissions(email_recipients_filepath, 0600, 'root', 'root')
        try:
            email_recipients.parse_recipient_file(email_recipients_filepath)
        except ProgramError, e:
            if e.errno == ERR_FILE_OPEN:
                syslog.syslog(syslog.LOG_DEBUG, e.strerror)
            else:
                raise e

        # Create a server to listen for alert clients and then run.
        listen_addresses = get_socket_list_from_config('listen_for_client')
        for listen_address in listen_addresses:
            listening_server = ListeningServer(listen_address, SetroubleshootdClientConnectionHandler)
            listening_server.open()

        dbus.glib.init_threads()
        setroubleshootd_dbus = SetroubleshootdDBus(analysis_queue, alert_receiver, timeout)
        main_loop = gobject.MainLoop()
        main_loop.run()
Ejemplo n.º 5
0
    def derive_avc_info_from_audit_event(self):
        self.tpath = None
        self.spath = None
        self.source = None
        self.a1 = None
        self.success = False
        self.syscall_paths = []
        exe = comm = arch = syscall = None

        self.avc_record = self.audit_event.get_avc_record()
        syscall_record = self.audit_event.get_record_of_type('SYSCALL')

        self.access = self.avc_record.get_field('seperms')
        if not isinstance(self.scontext, AvcContext):
            self.scontext = AvcContext(self.avc_record.get_field('scontext'))

        if not isinstance(self.tcontext, AvcContext):
            self.tcontext = AvcContext(self.avc_record.get_field('tcontext'))

        self.tclass = self.avc_record.get_field('tclass')

        if self.avc_record.get_field('dest') is None:
            self.port = self.avc_record.get_field('src')
        else:
            self.port = self.avc_record.get_field('dest')

        self._set_tpath()

        self.kmod = self.avc_record.get_field('kmod')

        self.pid = self.avc_record.get_field('pid')

        # exe, cwd, name, path, key, dir, comm, ocomm, key_desc

        if syscall_record:
            exe = syscall_record.get_field('exe')
            try:
                exe.decode("hex")
            except:
                pass
            comm = syscall_record.get_field('comm')
            self.syscall = syscall_record.get_field('syscall')
            self.success = (syscall_record.get_field('success') == "yes")
            self.a1 = syscall_record.get_field('a1')

        if comm is None:
            comm = self.avc_record.get_field('comm')
        if exe is None:
            exe = self.avc_record.get_field('exe')

        try:
            self.spath = exe.decode("hex")
        except:
            self.spath = exe

        if comm:
            self.source = comm
        elif exe:
            self.source = self.spath

        if not self.spath:
            self.spath = self.source

        if not self.spath:
            self.spath = self.scontext.type

        cwd_record = self.audit_event.get_record_of_type('CWD')
        if cwd_record:
            cwd = cwd_record.get_field('cwd')
        else:
            cwd = None

        path_records = self.audit_event.get_records_of_type('PATH')
        for path_record in path_records:
            path = path_record.get_field('name')
            if os.path.isabs(path) or not cwd:
                self.syscall_paths.append(path)
            else:
                self.syscall_paths.append(os.path.join(cwd, path))

        self.src_rpms = []
        self.tgt_rpms = []

        self.host = self.audit_event.event_id.host

        self.why, bools = audit2why.analyze(str(self.scontext), str(self.tcontext), str(self.tclass), self.access)
        if self.why == audit2why.ALLOW:
            raise ValueError(_("%s \n**** Invalid AVC allowed in current policy ***\n") % self.avc_record)
        if self.why == audit2why.DONTAUDIT:
            raise ValueError(_("%s \n**** Invalid AVC dontaudited in current policy.  'semodule -B' will turn on dontaudit rules. ***\n") % self.avc_record)
        if self.why == audit2why.NOPOLICY:
            raise ValueError(_("Must call policy_init first"))
        if self.why == audit2why.BADTCON:
            raise ValueError(_("%s \n**** Invalid AVC bad target context. ***\n") % self.avc_record)
        if self.why == audit2why.BADSCON:
            raise ValueError(_("%s \n**** Invalid AVC bad source context. ***\n") % self.avc_record)
        if self.why == audit2why.BADSCON:
            raise ValueError(_("%s \n**** Invalid AVC bad type class ***\n") % self.avc_record)
        if self.why == audit2why.BADPERM:
            raise ValueError(_("%s \n**** Invalid AVC bad permission ***\n") % self.avc_record)
        if self.why == audit2why.BADCOMPUTE:
            raise ValueError(_("Error during access vector computation"))
        if self.why == audit2why.BOOLEAN:
            self.bools = bools
Ejemplo n.º 6
0
def RunFaultServer(timeout=10):
    signal.alarm(timeout)
    sigalrm_handler = signal.signal(signal.SIGALRM, polling_failed_handler)
    # polling for /sys/fs/selinux/policy file
    while True:
        try:
            audit2why.init()
            signal.alarm(0)
            break
        # retry if init() failed to open /sys/fs/selinux/policy
        except ValueError as e:
            # The value error contains the following error message,
            # followed by strerror string (which can differ with localization)
            if "unable to open /sys/fs/selinux/policy" in str(e):
                continue
            raise e
        except SystemError as e:
            # As a result of a bug in audit2why.c, SystemError is raised instead of ValueError.
            # Python reports: "SystemError occurs as a direct cause of ValueError"
            # Error message of the ValueError is stored in __context__
            # TODO: remove this except clause when the bug in audti2why is fixed
            if "unable to open /sys/fs/selinux/policy" in str(getattr(e, "__context__", "")):
                continue
            raise e

    global host_database, analysis_queue, email_recipients

    signal.signal(signal.SIGALRM, sigalrm_handler)
    signal.signal(signal.SIGHUP, sighandler)

    #interface_registry.dump_interfaces()

    try:
        # FIXME: should this be using our logging objects in log.py?
        # currently syslog is only used for putting an alert into
        # the syslog with it's id

        pkg_name = get_config('general', 'pkg_name')
        syslog.openlog(pkg_name)

        # Create an object responsible for sending notifications to clients
        client_notifier = ClientNotifier(connection_pool)

        # Create a database local to this host

        database_filename = get_config('database', 'filename')
        database_filepath = make_database_filepath(database_filename)
        assure_file_ownership_permissions(database_filepath, 0o600, 'setroubleshoot')
        host_database = SETroubleshootDatabase(database_filepath, database_filename,
                                               friendly_name=_("Audit Listener"))
        host_database.set_notify(client_notifier)

        atexit.register(goodbye, host_database)

        deleted = False
        for i in host_database.sigs.signature_list:
            why, bools = audit2why.analyze(str(i.sig.scontext), str(i.sig.tcontext), str(i.sig.tclass), i.sig.access)
            if why == audit2why.ALLOW or why == audit2why.DONTAUDIT:
                if why == audit2why.ALLOW:
                    reason = "allowed"
                else:
                    reason = "dontaudit'd"
                syslog.syslog(syslog.LOG_ERR, "Deleting alert %s, it is %s in current policy" % (i.local_id, reason))
                deleted = True
                host_database.delete_signature(i.sig)
        if deleted:
            host_database.save(prune=True)
        # Attach the local database to an object which will send alerts
        # specific to this host

        if not get_config('test', 'analyze', bool):
            alert_receiver = AlertPluginReportReceiver(host_database)
        else:
            alert_receiver = TestPluginReportReceiver(host_database)

        # Create a synchronized queue for analysis requests
        import six.moves.queue
        analysis_queue = six.moves.queue.Queue(0)

        # Create a thread to peform analysis, it takes AVC objects off
        # the analysis queue and runs the plugins against the
        # AVC. Analysis requests in the queue may arrive from a
        # variety of places; from the audit system, from a log file
        # scan, etc. The disposition of the analysis (e.g. where the
        # results of the analysis are to go) are included in the queued
        # object along with the data to analyze.

        analyze_thread = AnalyzeThread(analysis_queue)
        analyze_thread.setDaemon(True)
        analyze_thread.start()

        # Create a thread to receive messages from the audit system.
        # This is a time sensitive operation, the primary job of this
        # thread is to receive the audit message as quickly as
        # possible and return to listening on the audit socket. When
        # it receives a complete audit event it places it in the
        # analysis queue where another thread will process it
        # independently.

#        audit_socket_thread = AuditSocketReceiverThread(analysis_queue, alert_receiver)
#        audit_socket_thread.setDaemon(True)
#        audit_socket_thread.start()

        # Initialize the email recipient list
        from setroubleshoot.signature import SEEmailRecipientSet
        email_recipients = SEEmailRecipientSet()
        assure_file_ownership_permissions(email_recipients_filepath, 0o600, 'setroubleshoot')
        try:
            email_recipients.parse_recipient_file(email_recipients_filepath)
        except ProgramError as e:
            if e.errno == ERR_FILE_OPEN:
                log_debug(e.strerror)
            else:
                raise e

        # Create a server to listen for alert clients and then run.
        listen_addresses = get_socket_list_from_config('listen_for_client')
        for listen_address in listen_addresses:
            listening_server = ListeningServer(listen_address, SetroubleshootdClientConnectionHandler)
            listening_server.open()

        dbus.glib.init_threads()
        setroubleshootd_dbus = SetroubleshootdDBus(analysis_queue, alert_receiver, timeout)
        main_loop = GLib.MainLoop()
        main_loop.run()

    except KeyboardInterrupt as e:
        log_debug("KeyboardInterrupt in RunFaultServer")

    except SystemExit as e:
        log_debug("raising SystemExit in RunFaultServer")

    except Exception as e:
        import traceback
        syslog_trace(traceback.format_exc())
        syslog.syslog(syslog.LOG_ERR, "exception %s: %s" % (e.__class__.__name__, str(e)))