diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/access.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/access.py --- nsasepolgen/src/sepolgen/access.py 2009-05-18 13:53:14.000000000 -0400 +++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/access.py 2009-12-08 17:05:49.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.78/sepolgen-1.0.19/src/sepolgen/audit.py --- nsasepolgen/src/sepolgen/audit.py 2009-12-01 15:46:50.000000000 -0500 +++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/audit.py 2010-01-06 09:52:35.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): @@ -285,6 +346,9 @@ def __initialize(self): self.avc_msgs = [] + self.constraint_msgs = [] + self.dontaudit_msgs = [] + self.rbac_msgs = [] self.compute_sid_msgs = [] self.invalid_msgs = [] self.policy_load_msgs = [] @@ -314,7 +378,7 @@ elif i == "security_compute_sid:": msg = ComputeSidMessage(line) found = True - elif i == "type=MAC_POLICY_LOAD" or i == "type=1403": + elif i == "type=MAC_POLICY_LOAD": msg = PolicyLoadMessage(line) found = True elif i == "type=AVC_PATH": @@ -442,16 +506,17 @@ audit logs parsed by this object. """ av_set = access.AccessVectorSet() + for avc in self.avc_msgs: if avc.denial != True and only_denials: continue 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: @@ -477,5 +542,3 @@ if self.regex.match(avc.tcontext.type): return True return False - - diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/policygen.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/policygen.py --- nsasepolgen/src/sepolgen/policygen.py 2008-09-12 11:48:15.000000000 -0400 +++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/policygen.py 2010-01-08 09:33:54.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 @@ -74,7 +76,7 @@ self.moduel = module else: self.module = refpolicy.Module() - + self.domains = None def set_gen_refpol(self, if_set=None, perm_maps=None): """Set whether reference policy interfaces are generated. @@ -141,15 +143,42 @@ """Return the generated module""" return self.module - def __add_allow_rules(self, avs): + def __add_allow_rules(self, avs, dontaudit): for av in avs: - rule = refpolicy.AVRule(av) + rule = refpolicy.AVRule(av, dontaudit=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) - def add_access(self, av_set): + def add_access(self, av_set, dontaudit=False): """Add the access from the access vector set to this module. """ @@ -165,7 +194,7 @@ raw_allow = av_set # Generate the raw allow rules from the filtered list - self.__add_allow_rules(raw_allow) + self.__add_allow_rules(raw_allow, dontaudit) def add_role_types(self, role_type_set): for role_type in role_type_set: diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refparser.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refparser.py --- nsasepolgen/src/sepolgen/refparser.py 2009-10-29 15:21:39.000000000 -0400 +++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refparser.py 2009-12-08 17:05:49.000000000 -0500 @@ -973,7 +973,7 @@ def list_headers(root): modules = [] support_macros = None - blacklist = ["init.if", "inetd.if", "uml.if", "thunderbird.if"] + blacklist = ["uml.if", "thunderbird.if", "unconfined.if"] for dirpath, dirnames, filenames in os.walk(root): for name in filenames: diff --exclude-from=exclude -N -u -r nsasepolgen/src/sepolgen/refpolicy.py policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refpolicy.py --- nsasepolgen/src/sepolgen/refpolicy.py 2009-10-29 15:21:39.000000000 -0400 +++ policycoreutils-2.0.78/sepolgen-1.0.19/src/sepolgen/refpolicy.py 2010-01-08 09:33:37.000000000 -0500 @@ -398,6 +398,7 @@ return "attribute %s;" % self.name # Classes representing rules +import selinux.audit2why as audit2why class AVRule(Leaf): """SELinux access vector (AV) rule. @@ -420,21 +421,26 @@ AUDITALLOW = 2 NEVERALLOW = 3 - def __init__(self, av=None, parent=None): + def __init__(self, av=None, parent=None, dontaudit=False): Leaf.__init__(self, parent) self.src_types = IdSet() self.tgt_types = IdSet() self.obj_classes = IdSet() self.perms = IdSet() - self.rule_type = self.ALLOW + if dontaudit: + self.rule_type = audit2why.DONTAUDIT + else: + self.rule_type = audit2why.TERULE if av: self.from_av(av) def __rule_type_str(self): - if self.rule_type == self.ALLOW: + if self.rule_type == audit2why.TERULE: return "allow" - elif self.rule_type == self.DONTAUDIT: + elif self.rule_type == audit2why.DONTAUDIT: return "dontaudit" + elif self.rule_type == audit2why.CONSTRAINT: + return "#constraint allow" else: return "auditallow"