b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/access.py
829762e
--- nsasepolgen/src/sepolgen/access.py	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/access.py	2010-06-16 08:22:43.000000000 -0400
79944fd
@@ -32,6 +32,7 @@
79944fd
 """
79944fd
 
79944fd
 import refpolicy
79944fd
+from selinux import audit2why
79944fd
 
79944fd
 def is_idparam(id):
79944fd
     """Determine if an id is a paramater in the form $N, where N is
79944fd
@@ -85,6 +86,8 @@
79944fd
             self.obj_class = None
79944fd
             self.perms = refpolicy.IdSet()
79944fd
             self.audit_msgs = []
79944fd
+            self.type = audit2why.TERULE
79944fd
+            self.bools = []
79944fd
 
79944fd
         # The direction of the information flow represented by this
79944fd
         # access vector - used for matching
79944fd
@@ -253,20 +256,22 @@
79944fd
         for av in l:
79944fd
             self.add_av(AccessVector(av))
79944fd
 
79944fd
-    def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None):
79944fd
+    def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, bools=[]):
79944fd
         """Add an access vector to the set.
79944fd
         """
79944fd
         tgt = self.src.setdefault(src_type, { })
79944fd
         cls = tgt.setdefault(tgt_type, { })
79944fd
         
79944fd
-        if cls.has_key(obj_class):
79944fd
-            access = cls[obj_class]
79944fd
+        if cls.has_key((obj_class, avc_type)):
79944fd
+            access = cls[obj_class, avc_type]
79944fd
         else:
79944fd
             access = AccessVector()
79944fd
             access.src_type = src_type
79944fd
             access.tgt_type = tgt_type
79944fd
             access.obj_class = obj_class
79944fd
-            cls[obj_class] = access
79944fd
+            access.bools = bools
79944fd
+            access.type = avc_type
79944fd
+            cls[obj_class, avc_type] = access
79944fd
 
79944fd
         access.perms.update(perms)
79944fd
         if audit_msg:
b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/audit.py policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/audit.py
829762e
--- nsasepolgen/src/sepolgen/audit.py	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/audit.py	2010-06-16 08:22:43.000000000 -0400
829762e
@@ -68,6 +68,17 @@
b61040e
                               stdout=subprocess.PIPE).communicate()[0]
b61040e
     return output
b61040e
 
b61040e
+def get_log_msgs():
b61040e
+    """Obtain all of the avc and policy load messages from /var/log/messages.
b61040e
+
b61040e
+    Returns:
b61040e
+       string contain all of the audit messages returned by /var/log/messages.
b61040e
+    """
b61040e
+    import subprocess
b61040e
+    output = subprocess.Popen(["/bin/grep", "avc",  "/var/log/messages"],
b61040e
+                              stdout=subprocess.PIPE).communicate()[0]
b61040e
+    return output
b61040e
+
b61040e
 # Classes representing audit messages
b61040e
 
b61040e
 class AuditMessage:
829762e
@@ -127,6 +138,9 @@
79944fd
             if fields[0] == "path":
79944fd
                 self.path = fields[1][1:-1]
79944fd
                 return
79944fd
+import selinux.audit2why as audit2why
6ed2be8
+
6ed2be8
+avcdict = {}
79944fd
 
79944fd
 class AVCMessage(AuditMessage):
79944fd
     """AVC message representing an access denial or granted message.
829762e
@@ -167,6 +181,8 @@
79944fd
         self.path = ""
79944fd
         self.accesses = []
79944fd
         self.denial = True
79944fd
+        self.type = audit2why.TERULE
79944fd
+        self.bools = []
79944fd
 
79944fd
     def __parse_access(self, recs, start):
79944fd
         # This is kind of sucky - the access that is in a space separated
829762e
@@ -226,7 +242,31 @@
79944fd
 
79944fd
         if not found_src or not found_tgt or not found_class or not found_access:
79944fd
             raise ValueError("AVC message in invalid format [%s]\n" % self.message)
79944fd
-                
79944fd
+        self.analyze()
79944fd
+
79944fd
+    def analyze(self):
79944fd
+        tcontext = self.tcontext.to_string()
79944fd
+        scontext = self.scontext.to_string()
6ed2be8
+        access_tuple = tuple( self.accesses)
6ed2be8
+        if (scontext, tcontext, self.tclass, access_tuple) in avcdict.keys():
6ed2be8
+            self.type, self.bools = avcdict[(scontext, tcontext, self.tclass, access_tuple)]
6ed2be8
+        else:
6ed2be8
+            self.type, self.bools = audit2why.analyze(scontext, tcontext, self.tclass, self.accesses);
6ed2be8
+            if self.type == audit2why.NOPOLICY:
829762e
+                self.type = audit2why.TERULE
6ed2be8
+            if self.type == audit2why.BADTCON:
6ed2be8
+                raise ValueError("Invalid Target Context %s\n" % tcontext)
6ed2be8
+            if self.type == audit2why.BADSCON:
6ed2be8
+                raise ValueError("Invalid Source Context %s\n" % scontext)
6ed2be8
+            if self.type == audit2why.BADSCON:
6ed2be8
+                raise ValueError("Invalid Type Class %s\n" % self.tclass)
6ed2be8
+            if self.type == audit2why.BADPERM:
6ed2be8
+                raise ValueError("Invalid permission %s\n" % " ".join(self.accesses))
6ed2be8
+            if self.type == audit2why.BADCOMPUTE:
6ed2be8
+                raise ValueError("Error during access vector computation")
829762e
+            
6ed2be8
+            avcdict[(scontext, tcontext, self.tclass, access_tuple)] = (self.type, self.bools)
79944fd
+
79944fd
 class PolicyLoadMessage(AuditMessage):
79944fd
     """Audit message indicating that the policy was reloaded."""
79944fd
     def __init__(self, message):
829762e
@@ -469,10 +509,10 @@
79944fd
             if avc_filter:
79944fd
                 if avc_filter.filter(avc):
79944fd
                     av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
79944fd
-                               avc.accesses, avc)
79944fd
+                               avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
79944fd
             else:
79944fd
                 av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass,
79944fd
-                           avc.accesses, avc)
79944fd
+                           avc.accesses, avc, avc_type=avc.type, bools=avc.bools)
79944fd
         return av_set
79944fd
 
79944fd
 class AVCTypeFilter:
b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/defaults.py policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/defaults.py
829762e
--- nsasepolgen/src/sepolgen/defaults.py	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/defaults.py	2010-06-16 08:22:43.000000000 -0400
829762e
@@ -30,6 +30,9 @@
829762e
 def interface_info():
829762e
     return data_dir() + "/interface_info"
829762e
 
829762e
+def attribute_info():
829762e
+    return data_dir() + "/attribute_info"
829762e
+
829762e
 def refpolicy_devel():
829762e
     return "/usr/share/selinux/devel"
829762e
 
b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/interfaces.py policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/interfaces.py
829762e
--- nsasepolgen/src/sepolgen/interfaces.py	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/interfaces.py	2010-06-16 08:22:43.000000000 -0400
829762e
@@ -29,6 +29,8 @@
829762e
 
829762e
 from sepolgeni18n import _
829762e
 
829762e
+import copy
829762e
+
829762e
 class Param:
829762e
     """
829762e
     Object representing a paramater for an interface.
829762e
@@ -197,10 +199,48 @@
829762e
                 ret = 1
829762e
 
829762e
     return ret
829762e
-            
829762e
+
829762e
+class AttributeVector:
829762e
+    def __init__(self):
829762e
+        self.name = ""
829762e
+        self.access = access.AccessVectorSet()
829762e
+
829762e
+    def add_av(self, av):
829762e
+        self.access.add_av(av)
829762e
+
829762e
+class AttributeSet:
829762e
+    def __init__(self):
829762e
+        self.attributes = { }
829762e
+
829762e
+    def add_attr(self, attr):
829762e
+        self.attributes[attr.name] = attr
829762e
+
829762e
+    def from_file(self, fd):
829762e
+        def parse_attr(line):
829762e
+            fields = line[1:-1].split()
829762e
+            if len(fields) != 2 or fields[0] != "Attribute":
829762e
+                raise SyntaxError("Syntax error Attribute statement %s" % line)
829762e
+            a = AttributeVector()
829762e
+            a.name = fields[1]
829762e
+
829762e
+            return a
829762e
+
829762e
+        a = None
829762e
+        for line in fd:
829762e
+            line = line[:-1]
829762e
+            if line[0] == "[":
829762e
+                if a:
829762e
+                    self.add_attr(a)
829762e
+                a = parse_attr(line)
829762e
+            elif a:
829762e
+                l = line.split(",")
829762e
+                av = access.AccessVector(l)
829762e
+                a.add_av(av)
829762e
+        if a:
829762e
+            self.add_attr(a)
829762e
 
829762e
 class InterfaceVector:
829762e
-    def __init__(self, interface=None):
829762e
+    def __init__(self, interface=None, attributes={}):
829762e
         # Enabled is a loose concept currently - we are essentially
829762e
         # not enabling interfaces that we can't handle currently.
829762e
         # See InterfaceVector.add_ifv for more information.
829762e
@@ -214,10 +254,10 @@
829762e
         # value: Param object).
829762e
         self.params = { }
829762e
         if interface:
829762e
-            self.from_interface(interface)
829762e
+            self.from_interface(interface, attributes)
829762e
         self.expanded = False
829762e
 
829762e
-    def from_interface(self, interface):
829762e
+    def from_interface(self, interface, attributes={}):
829762e
         self.name = interface.name
829762e
 
829762e
         # Add allow rules
829762e
@@ -232,6 +272,23 @@
829762e
             for av in avs:
829762e
                 self.add_av(av)
829762e
 
829762e
+        # Add typeattribute access
829762e
+        if attributes != None:
829762e
+            for typeattribute in interface.typeattributes():
829762e
+                for attr in typeattribute.attributes:
829762e
+                    if not attributes.attributes.has_key(attr):
829762e
+                        # print "missing attribute " + attr
829762e
+                        continue
829762e
+                    attr_vec = attributes.attributes[attr]
829762e
+                    for a in attr_vec.access:
829762e
+                        av = copy.copy(a)
829762e
+                        if av.src_type == attr_vec.name:
829762e
+                            av.src_type = typeattribute.type
829762e
+                        if av.tgt_type == attr_vec.name:
829762e
+                            av.tgt_type = typeattribute.type
829762e
+                        self.add_av(av)
829762e
+
829762e
+
829762e
         # Extract paramaters from roles
829762e
         for role in interface.roles():
829762e
             if role_extract_params(role, self.params):
829762e
@@ -346,13 +403,13 @@
829762e
                 l = self.tgt_type_map.setdefault(type, [])
829762e
                 l.append(ifv)
829762e
 
829762e
-    def add(self, interface):
829762e
-        ifv = InterfaceVector(interface)
829762e
+    def add(self, interface, attributes={}):
829762e
+        ifv = InterfaceVector(interface, attributes)
829762e
         self.add_ifv(ifv)
829762e
 
829762e
-    def add_headers(self, headers, output=None):
829762e
+    def add_headers(self, headers, output=None, attributes={}):
829762e
         for i in itertools.chain(headers.interfaces(), headers.templates()):
829762e
-            self.add(i)
829762e
+            self.add(i, attributes)
829762e
 
829762e
         self.expand_ifcalls(headers)
829762e
         self.index()
b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/matching.py policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/matching.py
829762e
--- nsasepolgen/src/sepolgen/matching.py	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/matching.py	2010-06-16 08:22:43.000000000 -0400
829762e
@@ -50,7 +50,7 @@
829762e
                 return 1
829762e
 
829762e
 class MatchList:
829762e
-    DEFAULT_THRESHOLD = 120
829762e
+    DEFAULT_THRESHOLD = 150
829762e
     def __init__(self):
829762e
         # Match objects that pass the threshold
829762e
         self.children = []
829762e
@@ -63,14 +63,15 @@
829762e
     def best(self):
829762e
         if len(self.children):
829762e
             return self.children[0]
829762e
-        else:
829762e
-            return None
829762e
+        if len(self.bastards):
829762e
+            return self.bastards[0]
829762e
+        return None
829762e
 
829762e
     def __len__(self):
829762e
         # Only return the length of the matches so
829762e
         # that this can be used to test if there is
829762e
         # a match.
829762e
-        return len(self.children)
829762e
+        return len(self.children) + len(self.bastards)
829762e
 
829762e
     def __iter__(self):
829762e
         return iter(self.children)
b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/policygen.py
829762e
--- nsasepolgen/src/sepolgen/policygen.py	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/policygen.py	2010-06-21 10:10:01.000000000 -0400
79944fd
@@ -29,6 +29,8 @@
79944fd
 import access
79944fd
 import interfaces
79944fd
 import matching
79944fd
+import selinux.audit2why as audit2why
79944fd
+from setools import *
79944fd
 
79944fd
 # Constants for the level of explanation from the generation
79944fd
 # routines
829762e
@@ -77,6 +79,7 @@
829762e
 
829762e
         self.dontaudit = False
829762e
 
79944fd
+        self.domains = None
79944fd
     def set_gen_refpol(self, if_set=None, perm_maps=None):
79944fd
         """Set whether reference policy interfaces are generated.
79944fd
 
d98a897
@@ -151,8 +154,41 @@
829762e
             rule = refpolicy.AVRule(av)
829762e
             if self.dontaudit:
829762e
                 rule.rule_type = rule.DONTAUDIT
79944fd
+            rule.comment = ""
79944fd
             if self.explain:
d98a897
-                rule.comment = refpolicy.Comment(explain_access(av, verbosity=self.explain))
d98a897
+                rule.comment = str(refpolicy.Comment(explain_access(av, verbosity=self.explain)))
a1bf0da
+            if av.type == audit2why.ALLOW:
a1bf0da
+                rule.comment += "#!!!! This avc is allowed in the current policy\n" 
79944fd
+            if av.type == audit2why.DONTAUDIT:
79944fd
+                rule.comment += "#!!!! This avc has a dontaudit rule in the current policy\n" 
d98a897
+
79944fd
+            if av.type == audit2why.BOOLEAN:
79944fd
+                if len(av.bools) > 1:
d98a897
+                    rule.comment += "#!!!! This avc can be allowed using one of the these booleans:\n#     %s\n" % ", ".join(map(lambda x: x[0], av.bools))
79944fd
+                else:
79944fd
+                    rule.comment += "#!!!! This avc can be allowed using the boolean '%s'\n" % av.bools[0][0]
79944fd
+
79944fd
+            if av.type == audit2why.CONSTRAINT:
79944fd
+                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" 
829762e
+                rule.comment += "#Contraint rule: "
829762e
+
79944fd
+            if av.type == audit2why.TERULE:
a1bf0da
+                if "write" in av.perms:
a1bf0da
+                    if "dir" in av.obj_class or "open" in av.perms:
a1bf0da
+                        if not self.domains:
a1bf0da
+                            self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"]
a1bf0da
+                        types=[]
829762e
+                        
829762e
+                        try:
829762e
+                            for i in map(lambda x: x[TCONTEXT], sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})):
829762e
+                                if i not in self.domains:
829762e
+                                    types.append(i)
b467ef3
+                            if len(types) == 1:
b467ef3
+                                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))
b467ef3
+                            elif len(types) >= 1:
b467ef3
+                                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))
829762e
+                        except:
829762e
+                            pass
d98a897
             self.module.children.append(rule)
79944fd
 
79944fd
 
b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refparser.py policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/refparser.py
829762e
--- nsasepolgen/src/sepolgen/refparser.py	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/sepolgen/refparser.py	2010-06-16 08:22:43.000000000 -0400
829762e
@@ -1044,7 +1044,7 @@
829762e
         # of misc_macros. We are just going to pretend that this is an interface
829762e
         # to make the expansion work correctly.
829762e
         can_exec = refpolicy.Interface("can_exec")
829762e
-        av = access.AccessVector(["$1","$2","file","execute_no_trans","read",
829762e
+        av = access.AccessVector(["$1","$2","file","execute_no_trans","open", "read",
829762e
                                   "getattr","lock","execute","ioctl"])
829762e
 
829762e
         can_exec.children.append(refpolicy.AVRule(av))
b467ef3
diff --exclude-from=exclude -N -u -r nsasepolgen/src/share/perm_map policycoreutils-2.0.83/sepolgen-1.0.23/src/share/perm_map
829762e
--- nsasepolgen/src/share/perm_map	2010-05-19 14:45:51.000000000 -0400
b467ef3
+++ policycoreutils-2.0.83/sepolgen-1.0.23/src/share/perm_map	2010-06-16 08:22:43.000000000 -0400
829762e
@@ -124,7 +124,7 @@
829762e
           quotamod     w           1
829762e
           quotaget     r           1
829762e
 
829762e
-class file 20
829762e
+class file 21
829762e
   execute_no_trans     r           1
829762e
         entrypoint     r           1
829762e
            execmod     n           1
829762e
@@ -141,48 +141,50 @@
829762e
             unlink     w           1
829762e
               link     w           1
829762e
             rename     w           5
829762e
-           execute     r           100
829762e
+           execute     r           10
829762e
             swapon     b           1
829762e
            quotaon     b           1
829762e
            mounton     b           1
829762e
+	      open     r	   1
829762e
 
829762e
-class dir 22
829762e
-          add_name     w           5
829762e
+class dir 23
829762e
+          add_name     w           1
829762e
        remove_name     w           1
829762e
           reparent     w           1
829762e
             search     r           1
829762e
              rmdir     b           1
829762e
              ioctl     n           1
829762e
-              read     r          10
829762e
-             write     w          10
829762e
+              read     r           1
829762e
+             write     w           1
829762e
             create     w           1
829762e
-           getattr     r           7
829762e
-           setattr     w           7
829762e
+           getattr     r           1
829762e
+           setattr     w           1
829762e
               lock     n           1
829762e
-       relabelfrom     r           10
829762e
-         relabelto     w           10
829762e
+       relabelfrom     r           1
829762e
+         relabelto     w           1
829762e
             append     w           1
829762e
             unlink     w           1
829762e
               link     w           1
829762e
-            rename     w           5
829762e
+            rename     w           1
829762e
            execute     r           1
829762e
             swapon     b           1
829762e
            quotaon     b           1
829762e
            mounton     b           1
829762e
+	      open     r	   1
829762e
 
829762e
 class fd 1
829762e
                use     b           1
829762e
 
829762e
-class lnk_file 17
829762e
+class lnk_file 18
829762e
              ioctl     n           1
829762e
-              read     r          10
829762e
-             write     w          10
829762e
+              read     r           1
829762e
+             write     w           1
829762e
             create     w           1
829762e
-           getattr     r           7
829762e
-           setattr     w           7
829762e
+           getattr     r           1
829762e
+           setattr     w           1
829762e
               lock     n           1
829762e
-       relabelfrom     r           10
829762e
-         relabelto     w           10
829762e
+       relabelfrom     r           1
829762e
+         relabelto     w           1
829762e
             append     w           1
829762e
             unlink     w           1
829762e
               link     w           1
829762e
@@ -191,8 +193,9 @@
829762e
             swapon     b           1
829762e
            quotaon     b           1
829762e
            mounton     b           1
829762e
+	      open     r	   1
829762e
 
829762e
-class chr_file 20
829762e
+class chr_file 21
829762e
   execute_no_trans     r           1
829762e
         entrypoint     r           1
829762e
            execmod     n           1
829762e
@@ -213,8 +216,9 @@
829762e
             swapon     b           1
829762e
            quotaon     b           1
829762e
            mounton     b           1
829762e
+	      open     r	   1
829762e
 
829762e
-class blk_file 17
829762e
+class blk_file 18
829762e
              ioctl     n           1
829762e
               read     r          10
829762e
              write     w          10
829762e
@@ -232,8 +236,9 @@
829762e
             swapon     b           1
829762e
            quotaon     b           1
829762e
            mounton     b           1
829762e
+	      open     r	   1
829762e
 
829762e
-class sock_file 17
829762e
+class sock_file 18
829762e
              ioctl     n           1
829762e
               read     r          10
829762e
              write     w          10
829762e
@@ -251,8 +256,9 @@
829762e
             swapon     b           1
829762e
            quotaon     b           1
829762e
            mounton     b           1
829762e
+	      open     r	   1
829762e
 
829762e
-class fifo_file 17
829762e
+class fifo_file 18
829762e
              ioctl     n           1
829762e
               read     r          10
829762e
              write     w          10
829762e
@@ -270,6 +276,7 @@
829762e
             swapon     b           1
829762e
            quotaon     b           1
829762e
            mounton     b           1
829762e
+	      open     r	   1
829762e
 
829762e
 class socket 22
829762e
              ioctl     n           1