1import unittest
2import os
3import shutil
4import sys
5from tempfile import mkdtemp
6from subprocess import Popen, PIPE
7
8
9class SandboxTests(unittest.TestCase):
10
11    def assertDenied(self, err):
12        self.assertTrue(b'Permission denied' in err,
13                        '"Permission denied" not found in %r' % err)
14
15    def assertNotFound(self, err):
16        self.assertTrue(b'not found' in err,
17                        '"not found" not found in %r' % err)
18
19    def assertFailure(self, status):
20        self.assertTrue(status != 0,
21                        '"Succeeded when it should have failed')
22
23    def assertSuccess(self, status, err):
24        self.assertTrue(status == 0,
25                        '"Sandbox should have succeeded for this test %r' % err)
26
27    def test_simple_success(self):
28        "Verify that we can read file descriptors handed to sandbox"
29        p1 = Popen(['cat', '/etc/passwd'], stdout=PIPE)
30        p2 = Popen([sys.executable, 'sandbox', 'grep', 'root'], stdin=p1.stdout, stdout=PIPE)
31        p1.stdout.close()
32        out, err = p2.communicate()
33        self.assertTrue(b'root' in out)
34
35    def test_cant_kill(self):
36        "Verify that we cannot send kill signal in the sandbox"
37        pid = os.getpid()
38        p = Popen([sys.executable, 'sandbox', 'kill', '-HUP', str(pid)], stdout=PIPE, stderr=PIPE)
39        out, err = p.communicate()
40        self.assertDenied(err)
41
42    def test_cant_ping(self):
43        "Verify that we can't ping within the sandbox"
44        p = Popen([sys.executable, 'sandbox', 'ping', '-c 1 ', '127.0.0.1'], stdout=PIPE, stderr=PIPE)
45        out, err = p.communicate()
46        self.assertDenied(err)
47
48    def test_cant_mkdir(self):
49        "Verify that we can't mkdir within the sandbox"
50        p = Popen([sys.executable, 'sandbox', 'mkdir', '~/test'], stdout=PIPE, stderr=PIPE)
51        out, err = p.communicate()
52        self.assertFailure(p.returncode)
53
54    def test_cant_list_homedir(self):
55        "Verify that we can't list homedir within the sandbox"
56        p = Popen([sys.executable, 'sandbox', 'ls', '~'], stdout=PIPE, stderr=PIPE)
57        out, err = p.communicate()
58        self.assertFailure(p.returncode)
59
60    def test_cant_send_mail(self):
61        "Verify that we can't send mail within the sandbox"
62        p = Popen([sys.executable, 'sandbox', 'mail'], stdout=PIPE, stderr=PIPE)
63        out, err = p.communicate()
64        self.assertDenied(err)
65
66    def test_cant_sudo(self):
67        "Verify that we can't run sudo within the sandbox"
68        p = Popen([sys.executable, 'sandbox', 'sudo'], stdout=PIPE, stderr=PIPE)
69        out, err = p.communicate()
70        self.assertFailure(p.returncode)
71
72    def test_mount(self):
73        "Verify that we mount a file system"
74        p = Popen([sys.executable, 'sandbox', '-M', 'id'], stdout=PIPE, stderr=PIPE)
75        out, err = p.communicate()
76        self.assertSuccess(p.returncode, err)
77
78    def test_set_level(self):
79        "Verify that we set level a file system"
80        p = Popen([sys.executable, 'sandbox', '-l', 's0', 'id'], stdout=PIPE, stderr=PIPE)
81        out, err = p.communicate()
82        self.assertSuccess(p.returncode, err)
83
84    def test_homedir(self):
85        "Verify that we set homedir a file system"
86        homedir = mkdtemp(dir=".", prefix=".sandbox_test")
87        p = Popen([sys.executable, 'sandbox', '-H', homedir, '-M', 'id'], stdout=PIPE, stderr=PIPE)
88        out, err = p.communicate()
89        shutil.rmtree(homedir)
90        self.assertSuccess(p.returncode, err)
91
92    def test_tmpdir(self):
93        "Verify that we set tmpdir a file system"
94        tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_test")
95        p = Popen([sys.executable, 'sandbox', '-T', tmpdir, '-M', 'id'], stdout=PIPE, stderr=PIPE)
96        out, err = p.communicate()
97        shutil.rmtree(tmpdir)
98        self.assertSuccess(p.returncode, err)
99
100    def test_include_file(self):
101        "Verify that sandbox can copy a file in the sandbox home and use it"
102        p = Popen([sys.executable, 'sandbox', '-i' ,'test_sandbox.py' , '-M', '/bin/cat', 'test_sandbox.py'],
103                  stdout=PIPE, stderr=PIPE)
104        out, err = p.communicate()
105        self.assertSuccess(p.returncode, err)
106
107
108if __name__ == "__main__":
109    import selinux
110    if selinux.is_selinux_enabled() and selinux.security_getenforce() == 1:
111        unittest.main()
112    else:
113        print("SELinux must be in enforcing mode for this test")
114