Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 1 | from ctypes import * |
| 2 | import re |
| 3 | import os |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 4 | import sys |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 5 | |
| 6 | class TERule: |
| 7 | def __init__(self, rule): |
| 8 | data = rule.split(',') |
| 9 | self.flavor = data[0] |
| 10 | self.sctx = data[1] |
| 11 | self.tctx = data[2] |
| 12 | self.tclass = data[3] |
| 13 | self.perms = set((data[4].strip()).split(' ')) |
| 14 | self.rule = rule |
| 15 | |
| 16 | class Policy: |
| 17 | __Rules = None |
| 18 | __FcDict = None |
| 19 | __libsepolwrap = None |
| 20 | __policydbP = None |
| 21 | |
| 22 | # Return all file_contexts entries that map to the input Type. |
| 23 | def QueryFc(self, Type): |
| 24 | if Type in self.__FcDict: |
| 25 | return self.__FcDict[Type] |
| 26 | else: |
| 27 | return None |
| 28 | |
| 29 | # Return all attributes associated with a type if IsAttr=False or |
| 30 | # all types associated with an attribute if IsAttr=True |
| 31 | def QueryTypeAttribute(self, Type, IsAttr): |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 32 | init_type_iter = self.__libsepolwrap.init_type_iter |
| 33 | init_type_iter.restype = c_void_p |
| 34 | TypeIterP = init_type_iter(c_void_p(self.__policydbP), |
| 35 | create_string_buffer(Type), c_bool(IsAttr)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 36 | if (TypeIterP == None): |
| 37 | sys.exit("Failed to initialize type iterator") |
| 38 | buf = create_string_buffer(2048) |
| 39 | |
| 40 | while True: |
| 41 | ret = self.__libsepolwrap.get_type(buf, c_int(2048), |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 42 | c_void_p(self.__policydbP), c_void_p(TypeIterP)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 43 | if ret == 0: |
| 44 | yield buf.value |
| 45 | continue |
| 46 | if ret == 1: |
| 47 | break; |
| 48 | # We should never get here. |
| 49 | sys.exit("Failed to import policy") |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 50 | self.__libsepolwrap.destroy_type_iter(c_void_p(TypeIterP)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 51 | |
| 52 | # Return all TERules that match: |
| 53 | # (any scontext) or (any tcontext) or (any tclass) or (any perms), |
| 54 | # perms. |
| 55 | # Any unspecified paramenter will match all. |
| 56 | # |
| 57 | # Example: QueryTERule(tcontext=["foo", "bar"], perms=["entrypoint"]) |
| 58 | # Will return any rule with: |
| 59 | # (tcontext="foo" or tcontext="bar") and ("entrypoint" in perms) |
| 60 | def QueryTERule(self, **kwargs): |
| 61 | if self.__Rules is None: |
| 62 | self.__InitTERules() |
| 63 | for Rule in self.__Rules: |
| 64 | # Match source type |
| 65 | if "scontext" in kwargs and Rule.sctx not in kwargs['scontext']: |
| 66 | continue |
| 67 | # Match target type |
| 68 | if "tcontext" in kwargs and Rule.tctx not in kwargs['tcontext']: |
| 69 | continue |
| 70 | # Match target class |
| 71 | if "tclass" in kwargs and Rule.tclass not in kwargs['tclass']: |
| 72 | continue |
| 73 | # Match any perms |
| 74 | if "perms" in kwargs and not bool(Rule.perms & set(kwargs['perms'])): |
| 75 | continue |
| 76 | yield Rule |
| 77 | |
| 78 | |
| 79 | def __GetTERules(self, policydbP, avtabIterP): |
| 80 | if self.__Rules is None: |
| 81 | self.__Rules = set() |
| 82 | buf = create_string_buffer(2048) |
| 83 | ret = 0 |
| 84 | while True: |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 85 | ret = self.__libsepolwrap.get_allow_rule(buf, c_int(2048), |
| 86 | c_void_p(policydbP), c_void_p(avtabIterP)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 87 | if ret == 0: |
| 88 | Rule = TERule(buf.value) |
| 89 | self.__Rules.add(Rule) |
| 90 | continue |
| 91 | if ret == 1: |
| 92 | break; |
| 93 | # We should never get here. |
| 94 | sys.exit("Failed to import policy") |
| 95 | |
| 96 | def __InitTERules(self): |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 97 | init_avtab = self.__libsepolwrap.init_avtab |
| 98 | init_avtab.restype = c_void_p |
| 99 | avtabIterP = init_avtab(c_void_p(self.__policydbP)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 100 | if (avtabIterP == None): |
| 101 | sys.exit("Failed to initialize avtab") |
| 102 | self.__GetTERules(self.__policydbP, avtabIterP) |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 103 | self.__libsepolwrap.destroy_avtab(c_void_p(avtabIterP)) |
| 104 | init_cond_avtab = self.__libsepolwrap.init_cond_avtab |
| 105 | init_cond_avtab.restype = c_void_p |
| 106 | avtabIterP = init_cond_avtab(c_void_p(self.__policydbP)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 107 | if (avtabIterP == None): |
| 108 | sys.exit("Failed to initialize conditional avtab") |
| 109 | self.__GetTERules(self.__policydbP, avtabIterP) |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 110 | self.__libsepolwrap.destroy_avtab(c_void_p(avtabIterP)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 111 | |
| 112 | # load ctypes-ified libsepol wrapper |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 113 | def __InitLibsepolwrap(self, LibPath): |
| 114 | if "linux" in sys.platform: |
| 115 | self.__libsepolwrap = CDLL(LibPath + "/libsepolwrap.so") |
| 116 | elif "darwin" in sys.platform: |
| 117 | self.__libsepolwrap = CDLL(LibPath + "/libsepolwrap.dylib") |
| 118 | else: |
| 119 | sys.exit("only Linux and Mac currrently supported") |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 120 | |
| 121 | # load file_contexts |
| 122 | def __InitFC(self, FcPaths): |
| 123 | fc = [] |
| 124 | for path in FcPaths: |
| 125 | if not os.path.exists(path): |
| 126 | sys.exit("file_contexts file " + path + " does not exist.") |
| 127 | fd = open(path, "r") |
| 128 | fc += fd.readlines() |
| 129 | fd.close() |
| 130 | self.__FcDict = {} |
| 131 | for i in fc: |
| 132 | rec = i.split() |
| 133 | try: |
| 134 | t = rec[-1].split(":")[2] |
| 135 | if t in self.__FcDict: |
| 136 | self.__FcDict[t].append(rec[0]) |
| 137 | else: |
| 138 | self.__FcDict[t] = [rec[0]] |
| 139 | except: |
| 140 | pass |
| 141 | |
| 142 | # load policy |
| 143 | def __InitPolicy(self, PolicyPath): |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 144 | load_policy = self.__libsepolwrap.load_policy |
| 145 | load_policy.restype = c_void_p |
| 146 | self.__policydbP = load_policy(create_string_buffer(PolicyPath)) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 147 | if (self.__policydbP is None): |
| 148 | sys.exit("Failed to load policy") |
| 149 | |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 150 | def __init__(self, PolicyPath, FcPaths, LibPath): |
| 151 | self.__InitLibsepolwrap(LibPath) |
Jeff Vander Stoep | bdfc030 | 2017-05-25 09:53:47 -0700 | [diff] [blame] | 152 | self.__InitFC(FcPaths) |
| 153 | self.__InitPolicy(PolicyPath) |
| 154 | |
| 155 | def __del__(self): |
| 156 | if self.__policydbP is not None: |
Jeff Vander Stoep | 1fc0682 | 2017-05-31 15:36:07 -0700 | [diff] [blame^] | 157 | self.__libsepolwrap.destroy_policy(c_void_p(self.__policydbP)) |