• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import unittest
2import sys
3from subprocess import Popen, PIPE
4
5import argparse
6
7object_list = ['login', 'user', 'port', 'module', 'interface', 'node', 'fcontext', 'boolean', 'permissive', "dontaudit"]
8
9
10class SemanageTests(unittest.TestCase):
11
12    def assertDenied(self, err):
13        self.assertTrue('Permission denied' in err,
14                        '"Permission denied" not found in %r' % err)
15
16    def assertNotFound(self, err):
17        self.assertTrue('not found' in err,
18                        '"not found" not found in %r' % err)
19
20    def assertFailure(self, status):
21        self.assertTrue(status != 0,
22                        '"semanage succeeded when it should have failed')
23
24    def assertSuccess(self, status, err):
25        self.assertTrue(status == 0,
26                        '"semanage should have succeeded for this test %r' % err)
27
28    def test_extract(self):
29        for object in object_list:
30            if object in ["dontaudit", "module", "permissive"]:
31                continue
32            "Verify semanage %s -E" % object
33            p = Popen(['semanage', object, '-E'], stdout=PIPE)
34            out, err = p.communicate()
35            self.assertSuccess(p.returncode, err)
36
37    def test_input_output(self):
38        print("Verify semanage export -f /tmp/out")
39        p = Popen(['semanage', "export", '-f', '/tmp/out'], stdout=PIPE)
40        out, err = p.communicate()
41        self.assertSuccess(p.returncode, err)
42        print("Verify semanage export -S targeted -f -")
43        p = Popen(["semanage", "export", "-S", "targeted", "-f", "-"], stdout=PIPE)
44        out, err = p.communicate()
45        self.assertSuccess(p.returncode, err)
46        print("Verify semanage -S targeted -o -")
47        p = Popen(["semanage", "-S", "targeted", "-o", "-"], stdout=PIPE)
48        out, err = p.communicate()
49        self.assertSuccess(p.returncode, err)
50        print("Verify semanage import -f /tmp/out")
51        p = Popen(['semanage', "import", '-f', '/tmp/out'], stdout=PIPE)
52        out, err = p.communicate()
53        self.assertSuccess(p.returncode, err)
54        print("Verify semanage import -S targeted -f /tmp/out")
55        p = Popen(["semanage", "import", "-S", "targeted", "-f", "/tmp/out"], stdout=PIPE)
56        out, err = p.communicate()
57        self.assertSuccess(p.returncode, err)
58        print("Verify semanage -S targeted -i /tmp/out")
59        p = Popen(["semanage", "-S", "targeted", "-i", "/tmp/out"], stdout=PIPE)
60        out, err = p.communicate()
61        self.assertSuccess(p.returncode, err)
62
63    def test_list(self):
64        for object in object_list:
65            if object in ["dontaudit"]:
66                continue
67            "Verify semanage %s -l" % object
68            p = Popen(['semanage', object, '-l'], stdout=PIPE)
69            out, err = p.communicate()
70            self.assertSuccess(p.returncode, err)
71
72    def test_list_c(self):
73        for object in object_list:
74            if object in ["module", "permissive", "dontaudit"]:
75                continue
76            print("Verify semanage %s -l" % object)
77            p = Popen(['semanage', object, '-lC'], stdout=PIPE)
78            out, err = p.communicate()
79            self.assertSuccess(p.returncode, err)
80
81    def test_fcontext(self):
82        p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?"], stderr=PIPE)
83        out, err = p.communicate()
84
85        print("Verify semanage fcontext -a")
86        p = Popen(["semanage", "fcontext", "-a", "-t", "httpd_sys_content_t", "/ha-web(/.*)?"], stdout=PIPE)
87        out, err = p.communicate()
88        self.assertSuccess(p.returncode, err)
89        print("Verify semanage fcontext -m")
90        p = Popen(["semanage", "fcontext", "-m", "-t", "default_t", "/ha-web(/.*)?"], stdout=PIPE)
91        out, err = p.communicate()
92        self.assertSuccess(p.returncode, err)
93        print("Verify semanage fcontext -d")
94        p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?"], stdout=PIPE)
95        out, err = p.communicate()
96        self.assertSuccess(p.returncode, err)
97
98    def test_fcontext_e(self):
99        p = Popen(["semanage", "fcontext", "-d", "/myhome"], stderr=PIPE)
100        out, err = p.communicate()
101        p = Popen(["semanage", "fcontext", "-d", "/myhome1"], stderr=PIPE)
102        out, err = p.communicate()
103
104        print("Verify semanage fcontext -a -e")
105        p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome"], stdout=PIPE)
106        out, err = p.communicate()
107        self.assertSuccess(p.returncode, err)
108        print("Verify semanage fcontext -m -e")
109        p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome1"], stdout=PIPE)
110        out, err = p.communicate()
111        self.assertSuccess(p.returncode, err)
112        print("Verify semanage fcontext -d -e")
113        p = Popen(["semanage", "fcontext", "-d", "/myhome1"], stdout=PIPE)
114        out, err = p.communicate()
115        self.assertSuccess(p.returncode, err)
116
117    def test_port(self):
118        # Cleanup
119        p = Popen(["semanage", "port", "-d", "-p", "tcp", "55"], stdout=PIPE, stderr=PIPE)
120        out, err = p.communicate()
121
122        # test
123        print("Verify semanage port -a")
124        p = Popen(["semanage", "port", "-a", "-t", "ssh_port_t", "-p", "tcp", "55"], stdout=PIPE)
125        out, err = p.communicate()
126        self.assertSuccess(p.returncode, err)
127        print("Verify semanage port -m")
128        p = Popen(["semanage", "port", "-m", "-t", "http_port_t", "-p", "tcp", "55"], stdout=PIPE)
129        out, err = p.communicate()
130        self.assertSuccess(p.returncode, err)
131        print("Verify semanage port -d")
132        p = Popen(["semanage", "port", "-d", "-p", "tcp", "55"], stdout=PIPE)
133        out, err = p.communicate()
134        self.assertSuccess(p.returncode, err)
135
136    def test_login(self):
137        # Cleanup
138        p = Popen(["userdel", "-f", "-r", "testlogin"], stderr=PIPE, stdout=PIPE)
139        out, err = p.communicate()
140        p = Popen(["semanage", "user", "-d", "testuser_u"], stderr=PIPE, stdout=PIPE)
141        out, err = p.communicate()
142        p = Popen(["semanage", "login", "-d", "testlogin"], stderr=PIPE, stdout=PIPE)
143        out, err = p.communicate()
144
145        #test
146        print("Verify semanage user -a")
147        p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u"], stdout=PIPE)
148        out, err = p.communicate()
149        self.assertSuccess(p.returncode, err)
150        print("Verify useradd ")
151        p = Popen(["useradd", "testlogin"], stdout=PIPE)
152        out, err = p.communicate()
153        self.assertSuccess(p.returncode, err)
154        print("Verify semanage login -a")
155        p = Popen(["semanage", "login", "-a", "-s", "testuser_u", "testlogin"], stdout=PIPE)
156        out, err = p.communicate()
157        self.assertSuccess(p.returncode, err)
158        print("Verify semanage login -m -r")
159        p = Popen(["semanage", "login", "-m", "-r", "s0-s0:c1", "testlogin"], stdout=PIPE)
160        out, err = p.communicate()
161        self.assertSuccess(p.returncode, err)
162        print("Verify semanage login -m -s")
163        p = Popen(["semanage", "login", "-m", "-s", "staff_u", "testlogin"], stdout=PIPE)
164        out, err = p.communicate()
165        self.assertSuccess(p.returncode, err)
166        print("Verify semanage login -m -s -r")
167        p = Popen(["semanage", "login", "-m", "-s", "testuser_u", "-r", "s0", "testlogin"], stdout=PIPE)
168        out, err = p.communicate()
169        self.assertSuccess(p.returncode, err)
170        print("Verify semanage login -d")
171        p = Popen(["semanage", "login", "-d", "testlogin"], stdout=PIPE)
172        out, err = p.communicate()
173        print("Verify userdel ")
174        p = Popen(["userdel", "-f", "-r", "testlogin"], stderr=PIPE, stdout=PIPE)
175        out, err = p.communicate()
176        self.assertSuccess(p.returncode, err)
177        print("Verify semanage user -d")
178        p = Popen(["semanage", "user", "-d", "testuser_u"], stdout=PIPE)
179        out, err = p.communicate()
180        self.assertSuccess(p.returncode, err)
181
182    def test_user(self):
183        # Cleanup
184        p = Popen(["semanage", "user", "-d", "testuser_u"], stderr=PIPE, stdout=PIPE)
185        out, err = p.communicate()
186
187        # test
188        print("Verify semanage user -a")
189        p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u"], stdout=PIPE)
190        out, err = p.communicate()
191        self.assertSuccess(p.returncode, err)
192        print("Verify semanage user -m -R")
193        p = Popen(["semanage", "user", "-m", "-R", "sysadm_r unconfined_r", "testuser_u"], stdout=PIPE)
194        out, err = p.communicate()
195        self.assertSuccess(p.returncode, err)
196        print("Verify semanage user -m -r")
197        p = Popen(["semanage", "user", "-m", "-r", "s0-s0:c1", "testuser_u"], stdout=PIPE)
198        out, err = p.communicate()
199        self.assertSuccess(p.returncode, err)
200        print("Verify semanage user -d")
201        p = Popen(["semanage", "user", "-d", "testuser_u"], stdout=PIPE)
202        out, err = p.communicate()
203        self.assertSuccess(p.returncode, err)
204
205    def test_boolean(self):
206        import selinux
207        boolean_status = {0: "--off", 1: "--on"}
208        boolean_state = selinux.security_get_boolean_active("httpd_anon_write")
209        # Test
210        print("Verify semanage boolean -m %s httpd_anon_write" % boolean_status[not boolean_state])
211        p = Popen(["semanage", "boolean", "-m", boolean_status[(not boolean_state)], "httpd_anon_write"], stdout=PIPE)
212        out, err = p.communicate()
213        self.assertSuccess(p.returncode, err)
214        print("Verify semanage boolean -m %s httpd_anon_write" % boolean_status[boolean_state])
215        p = Popen(["semanage", "boolean", "-m", boolean_status[boolean_state], "httpd_anon_write"], stdout=PIPE)
216        out, err = p.communicate()
217        self.assertSuccess(p.returncode, err)
218
219
220def semanage_suite():
221    semanage_suite = unittest.TestSuite()
222    semanage_suite.addTest(unittest.makeSuite(SemanageTests))
223
224    return semanage_suite
225
226
227def semanage_custom_suite(test_list):
228    suiteSemanage = unittest.TestSuite()
229    for t in test_list:
230        suiteSemanage.addTest(SemanageTests(t))
231
232    return suiteSemanage
233
234
235def semanage_run_test(suite):
236    return unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
237
238
239class CheckTest(argparse.Action):
240
241    def __call__(self, parser, namespace, values, option_string=None):
242        newval = getattr(namespace, self.dest)
243        if not newval:
244            newval = []
245        for v in values:
246            if v not in semanage_test_list:
247                raise ValueError("%s must be an unit test.\nValid tests: %s" % (v, ", ".join(semanage_test_list)))
248            newval.append(v)
249        setattr(namespace, self.dest, newval)
250
251
252def semanage_args(args):
253    if args.list:
254        print("You can run the following tests:")
255        for i in semanage_test_list:
256            print(i)
257    if args.all:
258        return semanage_run_test(semanage_suite())
259    if args.test:
260        return semanage_run_test(semanage_custom_suite(args.test))
261
262
263def gen_semanage_test_args(parser):
264    group = parser.add_mutually_exclusive_group(required=True)
265    group.add_argument('-a', "--all", dest="all", default=False,
266                       action="store_true",
267                       help=("Run all semanage unit tests"))
268    group.add_argument('-l', "--list", dest="list", default=False,
269                       action="store_true",
270                       help=("List all semanage unit tests"))
271    group.add_argument('-t', "--test", dest="test", default=[],
272                       action=CheckTest, nargs="*",
273                       help=("Run selected semanage unit test(s)"))
274    group.set_defaults(func=semanage_args)
275
276if __name__ == "__main__":
277    import selinux
278    semanage_test_list = [x for x in dir(SemanageTests) if x.startswith("test_")]
279    if selinux.is_selinux_enabled() and selinux.security_getenforce() == 1:
280        parser = argparse.ArgumentParser(description='Semanage unit test script')
281        gen_semanage_test_args(parser)
282        try:
283            args = parser.parse_args()
284            if args.func(args):
285                sys.exit(0)
286            else:
287                sys.exit(1)
288        except ValueError as e:
289            sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
290            sys.exit(1)
291        except IOError as e:
292            sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
293            sys.exit(1)
294        except KeyboardInterrupt:
295            sys.exit(0)
296    else:
297        print("SELinux must be in enforcing mode for this test")
298