Home | History | Annotate | Download | only in semanage
      1 import unittest
      2 import sys
      3 from subprocess import Popen, PIPE
      4 
      5 import argparse
      6 
      7 object_list = ['login', 'user', 'port', 'module', 'interface', 'node', 'fcontext', 'boolean', 'permissive', "dontaudit"]
      8 
      9 
     10 class 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 
    220 def semanage_suite():
    221     semanage_suite = unittest.TestSuite()
    222     semanage_suite.addTest(unittest.makeSuite(SemanageTests))
    223 
    224     return semanage_suite
    225 
    226 
    227 def 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 
    235 def semanage_run_test(suite):
    236     unittest.TextTestRunner(verbosity=2).run(suite)
    237 
    238 
    239 class 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 
    252 def 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         semanage_run_test(semanage_suite())
    259     if args.test:
    260         semanage_run_test(semanage_custom_suite(args.test))
    261 
    262 
    263 def 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 
    276 if __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             args.func(args)
    285             sys.exit(0)
    286         except ValueError as e:
    287             sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
    288             sys.exit(1)
    289         except IOError as e:
    290             sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
    291             sys.exit(1)
    292         except KeyboardInterrupt:
    293             sys.exit(0)
    294     else:
    295         print("SELinux must be in enforcing mode for this test")
    296