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