1# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 2# 3# Copyright (C) 2006 Red Hat 4# see file 'COPYING' for use and warranty information 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as 8# published by the Free Software Foundation; version 2 only 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18# 19 20import unittest 21import sepolgen.refpolicy as refpolicy 22import sepolgen.refparser as refparser 23import sepolgen.policygen as policygen 24import sepolgen.access as access 25 26class TestAccessVector(unittest.TestCase): 27 def test_init(self): 28 # Default construction 29 a = access.AccessVector() 30 self.assertEqual(a.src_type, None) 31 self.assertEqual(a.tgt_type, None) 32 self.assertEqual(a.obj_class, None) 33 self.assertTrue(isinstance(a.perms, refpolicy.IdSet)) 34 self.assertTrue(isinstance(a.audit_msgs, type([]))) 35 self.assertTrue(isinstance(a.xperms, type({}))) 36 self.assertEqual(len(a.audit_msgs), 0) 37 38 # Construction from a list 39 a = access.AccessVector() 40 a.src_type = "foo" 41 a.tgt_type = "bar" 42 a.obj_class = "file" 43 a.perms.update(["read", "write"]) 44 45 l = access.AccessVector(['foo', 'bar', 'file', 'read', 'write']) 46 self.assertEqual(a.src_type, l.src_type) 47 self.assertEqual(a.tgt_type, l.tgt_type) 48 self.assertEqual(a.obj_class, l.obj_class) 49 self.assertEqual(a.perms, l.perms) 50 51 def test_from_list(self): 52 a = access.AccessVector() 53 a.src_type = "foo" 54 a.tgt_type = "bar" 55 a.obj_class = "file" 56 a.perms.update(["read", "write"]) 57 58 l = access.AccessVector() 59 l.from_list(['foo', 'bar', 'file', 'read', 'write']) 60 self.assertEqual(a.src_type, l.src_type) 61 self.assertEqual(a.tgt_type, l.tgt_type) 62 self.assertEqual(a.obj_class, l.obj_class) 63 self.assertEqual(a.perms, l.perms) 64 65 l2 = access.AccessVector() 66 with self.assertRaises(ValueError): 67 l2.from_list(['foo', 'bar', 'file']) 68 69 def test_to_list(self): 70 a = access.AccessVector() 71 a.src_type = "foo" 72 a.tgt_type = "bar" 73 a.obj_class = "file" 74 a.perms.update(["read", "write"]) 75 76 l = a.to_list() 77 self.assertEqual(l[0], "foo") 78 self.assertEqual(l[1], "bar") 79 self.assertEqual(l[2], "file") 80 perms = l[3:] 81 perms.sort() 82 self.assertEqual(perms[0], "read") 83 self.assertEqual(perms[1], "write") 84 85 def test_to_string(self): 86 a = access.AccessVector() 87 a.src_type = "foo" 88 a.tgt_type = "bar" 89 a.obj_class = "file" 90 a.perms.update(["read", "write"]) 91 92 first, second = str(a).split(':') 93 self.assertEqual(first, "allow foo bar") 94 second = second.split(' ') 95 second.sort() 96 expected = "file { read write };".split(' ') 97 expected.sort() 98 self.assertEqual(second, expected) 99 100 first, second = a.to_string().split(':') 101 self.assertEqual(first, "allow foo bar") 102 second = second.split(' ') 103 second.sort() 104 expected = "file { read write };".split(' ') 105 expected.sort() 106 self.assertEqual(second, expected) 107 108 def test_cmp(self): 109 a = access.AccessVector() 110 a.src_type = "foo" 111 a.tgt_type = "bar" 112 a.obj_class = "file" 113 a.perms.update(["read", "write"]) 114 115 b = access.AccessVector() 116 b.src_type = "foo" 117 b.tgt_type = "bar" 118 b.obj_class = "file" 119 b.perms.update(["read", "write"]) 120 121 self.assertEqual(a, b) 122 123 # Source Type 124 b.src_type = "baz" 125 self.assertNotEqual(a, b) 126 self.assertTrue(a > b) 127 128 b.src_type = "gaz" 129 self.assertNotEqual(a, b) 130 self.assertTrue(a < b) 131 132 # Target Type 133 b.src_type = "foo" 134 b.tgt_type = "aar" 135 self.assertNotEqual(a, b) 136 self.assertTrue(a > b) 137 138 b.tgt_type = "gaz" 139 self.assertNotEqual(a, b) 140 self.assertTrue(a < b) 141 142 # Perms 143 b.tgt_type = "bar" 144 b.perms = refpolicy.IdSet(["read"]) 145 self.assertNotEqual(a, b) 146 self.assertTrue(a > b) 147 148 b.perms = refpolicy.IdSet(["read", "write", "append"]) 149 self.assertNotEqual(a, b) 150 151 b.perms = refpolicy.IdSet(["read", "append"]) 152 self.assertNotEqual(a, b) 153 154 def test_merge_noxperm(self): 155 """Test merging two AVs without xperms""" 156 a = access.AccessVector(["foo", "bar", "file", "read", "write"]) 157 b = access.AccessVector(["foo", "bar", "file", "append"]) 158 159 a.merge(b) 160 self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) 161 162 def text_merge_xperm1(self): 163 """Test merging AV that contains xperms with AV that does not""" 164 a = access.AccessVector(["foo", "bar", "file", "read"]) 165 b = access.AccessVector(["foo", "bar", "file", "read"]) 166 xp = refpolicy.XpermSet() 167 xp.add(42) 168 xp.add(12345) 169 b.xperms = {"ioctl": xp} 170 171 a.merge(b) 172 self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) 173 self.assertEqual(list(a.xperms.keys()), ["ioctl"]) 174 self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") 175 176 def text_merge_xperm2(self): 177 """Test merging AV that does not contain xperms with AV that does""" 178 a = access.AccessVector(["foo", "bar", "file", "read"]) 179 xp = refpolicy.XpermSet() 180 xp.add(42) 181 xp.add(12345) 182 a.xperms = {"ioctl": xp} 183 b = access.AccessVector(["foo", "bar", "file", "read"]) 184 185 a.merge(b) 186 self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) 187 self.assertEqual(list(a.xperms.keys()), ["ioctl"]) 188 self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") 189 190 def test_merge_xperm_diff_op(self): 191 """Test merging two AVs that contain xperms with different operation""" 192 a = access.AccessVector(["foo", "bar", "file", "read"]) 193 xp1 = refpolicy.XpermSet() 194 xp1.add(23) 195 a.xperms = {"asdf": xp1} 196 197 b = access.AccessVector(["foo", "bar", "file", "read"]) 198 xp2 = refpolicy.XpermSet() 199 xp2.add(42) 200 xp2.add(12345) 201 b.xperms = {"ioctl": xp2} 202 203 a.merge(b) 204 self.assertEqual(list(a.perms), ["read"]) 205 self.assertEqual(sorted(list(a.xperms.keys())), ["asdf", "ioctl"]) 206 self.assertEqual(a.xperms["asdf"].to_string(), "23") 207 self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") 208 209 def test_merge_xperm_same_op(self): 210 """Test merging two AVs that contain xperms with same operation""" 211 a = access.AccessVector(["foo", "bar", "file", "read"]) 212 xp1 = refpolicy.XpermSet() 213 xp1.add(23) 214 a.xperms = {"ioctl": xp1} 215 216 b = access.AccessVector(["foo", "bar", "file", "read"]) 217 xp2 = refpolicy.XpermSet() 218 xp2.add(42) 219 xp2.add(12345) 220 b.xperms = {"ioctl": xp2} 221 222 a.merge(b) 223 self.assertEqual(list(a.perms), ["read"]) 224 self.assertEqual(list(a.xperms.keys()), ["ioctl"]) 225 self.assertEqual(a.xperms["ioctl"].to_string(), "{ 23 42 12345 }") 226 227class TestUtilFunctions(unittest.TestCase): 228 def test_is_idparam(self): 229 self.assertTrue(access.is_idparam("$1")) 230 self.assertTrue(access.is_idparam("$2")) 231 self.assertTrue(access.is_idparam("$123")) 232 self.assertFalse(access.is_idparam("$123.23")) 233 self.assertFalse(access.is_idparam("$A")) 234 235 def test_avrule_to_access_vectors(self): 236 rule = refpolicy.AVRule() 237 rule.src_types.add("foo") 238 rule.src_types.add("baz") 239 rule.tgt_types.add("bar") 240 rule.tgt_types.add("what") 241 rule.obj_classes.add("file") 242 rule.obj_classes.add("dir") 243 rule.perms.add("read") 244 rule.perms.add("write") 245 246 avs = access.avrule_to_access_vectors(rule) 247 self.assertEqual(len(avs), 8) 248 comps = [("foo", "what", "dir"), 249 ("foo", "what", "file"), 250 ("foo", "bar", "dir"), 251 ("foo", "bar", "file"), 252 ("baz", "what", "dir"), 253 ("baz", "what", "file"), 254 ("baz", "bar", "dir"), 255 ("baz", "bar", "file")] 256 status = [False] * 8 257 for av in access.avrule_to_access_vectors(rule): 258 self.assertEqual(av.perms, refpolicy.IdSet(["read", "write"])) 259 for i in range(len(comps)): 260 if comps[i][0] == av.src_type and \ 261 comps[i][1] == av.tgt_type and \ 262 comps[i][2] == av.obj_class: 263 status[i] = True 264 265 for s in status: 266 self.assertEqual(s, True) 267 268 269class TestAccessVectorSet(unittest.TestCase): 270 def setUp(self): 271 rule = refpolicy.AVRule() 272 rule.src_types.add("foo") 273 rule.src_types.add("baz") 274 rule.tgt_types.add("bar") 275 rule.tgt_types.add("what") 276 rule.obj_classes.add("file") 277 rule.obj_classes.add("dir") 278 rule.perms.add("read") 279 rule.perms.add("write") 280 281 s = access.AccessVectorSet() 282 avs = access.avrule_to_access_vectors(rule) 283 for av in avs: 284 s.add_av(av) 285 self.s = s 286 287 def test_init(self): 288 a = access.AccessVectorSet() 289 290 def test_iter(self): 291 comps = [("foo", "what", "dir"), 292 ("foo", "what", "file"), 293 ("foo", "bar", "dir"), 294 ("foo", "bar", "file"), 295 ("baz", "what", "dir"), 296 ("baz", "what", "file"), 297 ("baz", "bar", "dir"), 298 ("baz", "bar", "file")] 299 status = [False] * 8 300 for av in self.s: 301 self.assertEqual(av.perms, refpolicy.IdSet(["read", "write"])) 302 for i in range(len(comps)): 303 if comps[i][0] == av.src_type and \ 304 comps[i][1] == av.tgt_type and \ 305 comps[i][2] == av.obj_class: 306 status[i] = True 307 308 for s in status: 309 self.assertEqual(s, True) 310 311 def test_len(self): 312 self.assertEqual(len(self.s), 8) 313 314 def test_list(self): 315 a = access.AccessVectorSet() 316 a.add("$1", "foo", "file", refpolicy.IdSet(["read", "write"])) 317 a.add("$1", "bar", "file", refpolicy.IdSet(["read", "write"])) 318 a.add("what", "bar", "file", refpolicy.IdSet(["read", "write"])) 319 320 avl = a.to_list() 321 avl.sort() 322 323 test_l = [['what','bar','file','read','write'], 324 ['$1','foo','file','read','write'], 325 ['$1','bar','file','read','write']] 326 test_l.sort() 327 328 for a,b in zip(test_l, avl): 329 self.assertEqual(len(a), len(b)) 330 for x,y in list(zip(a,b))[:3]: 331 self.assertEqual(x, y) 332 perms1 = a[3:] 333 perms2 = b[3:] 334 perms1.sort() 335 perms2.sort() 336 self.assertEqual(perms1, perms2) 337 338 b = access.AccessVectorSet() 339 b.from_list(avl) 340 self.assertEqual(len(b), 3) 341 342 def test_add_av_first(self): 343 """Test adding first AV to the AV set""" 344 avs = access.AccessVectorSet() 345 av = access.AccessVector(['foo', 'bar', 'file', 'read']) 346 347 avs.add_av(av) 348 349 self.assertEqual(avs.to_list(), [['foo', 'bar', 'file', 'read']]) 350 351 def test_add_av_second(self): 352 """Test adding second AV to the AV set with same source and target 353 context and class""" 354 avs = access.AccessVectorSet() 355 av1 = access.AccessVector(['foo', 'bar', 'file', 'read']) 356 av2 = access.AccessVector(['foo', 'bar', 'file', 'write']) 357 358 avs.add_av(av1) 359 avs.add_av(av2) 360 361 self.assertEqual(avs.to_list(), [['foo', 'bar', 'file', 'read', 362 'write']]) 363 364 def test_add_av_with_msg(self): 365 """Test adding audit message""" 366 avs = access.AccessVectorSet() 367 av = access.AccessVector(['foo', 'bar', 'file', 'read']) 368 369 avs.add_av(av, 'test message') 370 371 self.assertEqual(avs.src['foo']['bar']['file', av.type].audit_msgs, 372 ['test message']) 373 374 def test_add(self): 375 """Test adding AV to the set""" 376 s = access.AccessVectorSet() 377 378 def test_add_av(av, audit_msg=None): 379 self.assertEqual(av.src_type, 'foo') 380 self.assertEqual(av.tgt_type, 'bar') 381 self.assertEqual(av.obj_class, 'file') 382 self.assertEqual(list(av.perms), ['read']) 383 self.assertEqual(av.data, 'test data') 384 self.assertEqual(av.type, 42) 385 self.assertEqual(audit_msg, 'test message') 386 387 s.add_av = test_add_av 388 389 s.add("foo", "bar", "file", refpolicy.IdSet(["read"]), 390 audit_msg='test message', avc_type=42, data='test data') 391