Blob Blame History Raw
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policycoreutils-2.0.81/sepolgen-1.0.20/src/sepolgen/access.py
--- nsasepolgen/src/sepolgen/access.py	2009-05-18 13:53:14.000000000 -0400
+++ policycoreutils-2.0.81/sepolgen-1.0.20/src/sepolgen/access.py	2010-03-12 09:57:04.000000000 -0500
@@ -32,6 +32,7 @@
 """
 
 import refpolicy
+from selinux import audit2why
 
 def is_idparam(id):
     """Determine if an id is a paramater in the form $N, where N is
@@ -85,6 +86,8 @@
             self.obj_class = None
             self.perms = refpolicy.IdSet()
             self.audit_msgs = []
+            self.type = audit2why.TERULE
+            self.bools = []
 
         # The direction of the information flow represented by this
         # access vector - used for matching
@@ -127,7 +130,7 @@
         return self.to_string()
 
     def to_string(self):
-        return "allow %s %s : %s %s;" % (self.src_type, self.tgt_type,
+        return "allow %s %s:%s %s;" % (self.src_type, self.tgt_type,
                                         self.obj_class, self.perms.to_space_str())
 
     def __cmp__(self, other):
@@ -253,20 +256,22 @@
         for av in l:
             self.add_av(AccessVector(av))
 
-    def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None):
+    def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, bools=[]):
         """Add an access vector to the set.
         """
         tgt = self.src.setdefault(src_type, { })
         cls = tgt.setdefault(tgt_type, { })
         
-        if cls.has_key(obj_class):
-            access = cls[obj_class]
+        if cls.has_key((obj_class, avc_type)):
+            access = cls[obj_class, avc_type]
         else:
             access = AccessVector()
             access.src_type = src_type
             access.tgt_type = tgt_type
             access.obj_class = obj_class
-            cls[obj_class] = access
+            access.bools = bools
+            access.type = avc_type
+            cls[obj_class, avc_type] = access
 
         access.perms.update(perms)
         if audit_msg:
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycoreutils-2.0.81/sepolgen-1.0.20/src/sepolgen/audit.py
--- nsasepolgen/src/sepolgen/audit.py	2009-12-01 15:46:50.000000000 -0500
+++ policycoreutils-2.0.81/sepolgen-1.0.20/src/sepolgen/audit.py	2010-03-12 09:59:05.000000000 -0500
@@ -23,6 +23,27 @@
 
 # Convenience functions
 
+def get_audit_boot_msgs():
+    """Obtain all of the avc and policy load messages from the audit
+    log. This function uses ausearch and requires that the current
+    process have sufficient rights to run ausearch.
+
+    Returns:
+       string contain all of the audit messages returned by ausearch.
+    """
+    import subprocess
+    import time
+    fd=open("/proc/uptime", "r")
+    off=float(fd.read().split()[0])
+    fd.close
+    s = time.localtime(time.time() - off)
+    date = time.strftime("%D/%Y", s).split("/")
+    bootdate="%s/%s/%s" % (date[0], date[1], date[3])
+    boottime = time.strftime("%X", s)
+    output = subprocess.Popen(["/sbin/ausearch", "-m", "AVC,USER_AVC,MAC_POLICY_LOAD,DAEMON_START,SELINUX_ERR", "-ts", bootdate, boottime],
+                              stdout=subprocess.PIPE).communicate()[0]
+    return output
+
 def get_audit_msgs():
     """Obtain all of the avc and policy load messages from the audit
     log. This function uses ausearch and requires that the current
@@ -47,6 +68,17 @@
                               stdout=subprocess.PIPE).communicate()[0]
     return output
 
+def get_log_msgs():
+    """Obtain all of the avc and policy load messages from /var/log/messages.
+
+    Returns:
+       string contain all of the audit messages returned by /var/log/messages.
+    """
+    import subprocess
+    output = subprocess.Popen(["/bin/grep", "avc",  "/var/log/messages"],
+                              stdout=subprocess.PIPE).communicate()[0]
+    return output
+
 # Classes representing audit messages
 
 class AuditMessage:
@@ -106,6 +138,9 @@
             if fields[0] == "path":
                 self.path = fields[1][1:-1]
                 return
+import selinux.audit2why as audit2why
+
+avcdict = {}
 
 class AVCMessage(AuditMessage):
     """AVC message representing an access denial or granted message.
@@ -146,6 +181,8 @@
         self.path = ""
         self.accesses = []
         self.denial = True
+        self.type = audit2why.TERULE
+        self.bools = []
 
     def __parse_access(self, recs, start):
         # This is kind of sucky - the access that is in a space separated
@@ -205,7 +242,31 @@
 
         if not found_src or not found_tgt or not found_class or not found_access:
             raise ValueError("AVC message in invalid format [%s]\n" % self.message)
-                
+        self.analyze()
+
+    def analyze(self):
+        tcontext = self.tcontext.to_string()
+        scontext = self.scontext.to_string()
+        access_tuple = tuple( self.accesses)
+        if (scontext, tcontext, self.tclass, access_tuple) in avcdict.keys():
+            self.type, self.bools = avcdict[(scontext, tcontext, self.tclass, access_tuple)]
+        else:
+            self.type, self.bools = audit2why.analyze(scontext, tcontext, self.tclass, self.accesses);
+            if self.type == audit2why.NOPOLICY:
+                raise ValueError("Must call policy_init first")
+            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")
+
+            avcdict[(scontext, tcontext, self.tclass, access_tuple)] = (self.type, self.bools)
+
 class PolicyLoadMessage(AuditMessage):
     """Audit message indicating that the policy was reloaded."""
     def __init__(self, message):
@@ -448,10 +509,10 @@
             if avc_filter:
                 if avc_filter.filter(avc):
                     av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
-                               avc.accesses, avc)
+                               avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
             else:
                 av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
-                           avc.accesses, avc)
+                           avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
         return av_set
 
 class AVCTypeFilter:
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py policycoreutils-2.0.81/sepolgen-1.0.20/src/sepolgen/policygen.py
--- nsasepolgen/src/sepolgen/policygen.py	2010-03-12 09:34:56.000000000 -0500
+++ policycoreutils-2.0.81/sepolgen-1.0.20/src/sepolgen/policygen.py	2010-03-12 09:53:30.000000000 -0500
@@ -29,6 +29,8 @@
 import access
 import interfaces
 import matching
+import selinux.audit2why as audit2why
+from setools import *
 
 # Constants for the level of explanation from the generation
 # routines
@@ -77,6 +79,7 @@
 
         self.dontaudit = False
 
+        self.domains = None
     def set_gen_refpol(self, if_set=None, perm_maps=None):
         """Set whether reference policy interfaces are generated.
 
@@ -151,8 +154,35 @@
             rule = refpolicy.AVRule(av)
             if self.dontaudit:
                 rule.rule_type = rule.DONTAUDIT
+            rule.comment = ""
             if self.explain:
                 rule.comment = refpolicy.Comment(explain_access(av, verbosity=self.explain))
+            if av.type == audit2why.ALLOW:
+                rule.comment += "#!!!! This avc is allowed in the current policy\n" 
+            if av.type == audit2why.DONTAUDIT:
+                rule.comment += "#!!!! This avc has a dontaudit rule in the current policy\n" 
+            if av.type == audit2why.BOOLEAN:
+                if len(av.bools) > 1:
+                    rule.comment += "#!!!! This avc can be allowed using one of the these booleans:\n#     %s\n" % ", ".join(map(lambda x: av.bools[0][0], av.bools))
+                else:
+                    rule.comment += "#!!!! This avc can be allowed using the boolean '%s'\n" % av.bools[0][0]
+
+            if av.type == audit2why.CONSTRAINT:
+                rule.comment += "#!!!! This avc is a constraint violation.  You will need to add an attribute to either the source or target type to make it work.\n" 
+            if av.type == audit2why.TERULE:
+                if "write" in av.perms:
+                    if "dir" in av.obj_class or "open" in av.perms:
+                        if not self.domains:
+                            self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"]
+                        types=[]
+                        for i in map(lambda x: x[TCONTEXT], sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})):
+                            if i not in self.domains:
+                                types.append(i)
+                        if len(types) == 1:
+                            rule.comment += "#!!!! The source type '%s' can write to a '%s' of the following type:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types))
+                        elif len(types) >= 1:
+                            rule.comment += "#!!!! The source type '%s' can write to a '%s' of the following types:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types))
+                            
             self.module.children.append(rule)