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