• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(), "{ 0x2a 0x3039 }")
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(), "{ 0x2a 0x3039 }")
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(), "0x17")
207        self.assertEqual(a.xperms["ioctl"].to_string(), "{ 0x2a 0x3039 }")
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(), "{ 0x17 0x2a 0x3039 }")
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