args_test.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. """
  2. This program tests the boss process to make sure that it runs while
  3. dropping permissions. It must be run as a user that can set permission.
  4. """
  5. import unittest
  6. import os
  7. import sys
  8. import subprocess
  9. import select
  10. import time
  11. import pwd
  12. # Set to a valid user name on the system to run setuid() test
  13. #SUID_USER=None
  14. SUID_USER="shane"
  15. BIND10_EXE="../run_bind10.sh"
  16. TIMEOUT=3
  17. class TestBossArgs(unittest.TestCase):
  18. def _waitForString(self, bob, s):
  19. found_string = False
  20. start_time = time.time()
  21. while time.time() < start_time + TIMEOUT:
  22. (r,w,x) = select.select((bob.stdout,), (), (), TIMEOUT)
  23. if bob.stdout in r:
  24. s = bob.stdout.readline()
  25. if s == '':
  26. break
  27. if s.startswith(s):
  28. found_string = True
  29. break
  30. return found_string
  31. def testNoArgs(self):
  32. """Run bind10 without any arguments"""
  33. bob = subprocess.Popen(args=(BIND10_EXE,),
  34. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  35. started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
  36. time.sleep(0.1)
  37. bob.terminate()
  38. bob.wait()
  39. self.assertTrue(started_ok)
  40. def testBadOption(self):
  41. """Run bind10 with a bogus option"""
  42. bob = subprocess.Popen(args=(BIND10_EXE, "--badoption"),
  43. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  44. failed = self._waitForString(bob, 'bind10: error: no such option: --badoption')
  45. time.sleep(0.1)
  46. bob.terminate()
  47. self.assertTrue(bob.wait() == 2)
  48. self.assertTrue(failed)
  49. def testArgument(self):
  50. """Run bind10 with an argument (this is not allowed)"""
  51. bob = subprocess.Popen(args=(BIND10_EXE, "argument"),
  52. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  53. failed = self._waitForString(bob, 'Usage: bind10 [options]')
  54. time.sleep(0.1)
  55. bob.terminate()
  56. self.assertTrue(bob.wait() == 1)
  57. self.assertTrue(failed)
  58. def testBadUser(self):
  59. """Run bind10 with a bogus user"""
  60. bob = subprocess.Popen(args=(BIND10_EXE, "-u", "bogus_user"),
  61. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  62. failed = self._waitForString(bob, "bind10: invalid user: 'bogus_user'")
  63. time.sleep(0.1)
  64. bob.terminate()
  65. self.assertTrue(bob.wait() == 1)
  66. self.assertTrue(failed)
  67. def testBadUid(self):
  68. """Run bind10 with a bogus user ID"""
  69. bob = subprocess.Popen(args=(BIND10_EXE, "-u", "999999999"),
  70. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  71. failed = self._waitForString(bob, "bind10: invalid user: '999999999'")
  72. time.sleep(0.1)
  73. bob.terminate()
  74. self.assertTrue(bob.wait() == 1)
  75. self.assertTrue(failed)
  76. def testFailSetUser(self):
  77. """Try the -u option when we don't run as root"""
  78. global SUID_USER
  79. if SUID_USER is None:
  80. self.skipTest("test needs a valid user (set when run)")
  81. if os.getuid() == 0:
  82. self.skipTest("test must not be run as root (uid is 0)")
  83. # XXX: we depend on the "nobody" user
  84. bob = subprocess.Popen(args=(BIND10_EXE, "-u", "nobody"),
  85. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  86. failed = self._waitForString(bob, "[bind10] Error on startup: Unable to start b10-msgq; Unable to change to user nobody")
  87. time.sleep(0.1)
  88. bob.terminate()
  89. self.assertTrue(bob.wait() == 1)
  90. self.assertTrue(failed)
  91. def testSetUser(self):
  92. """Try the -u option"""
  93. global SUID_USER
  94. if SUID_USER is None:
  95. self.skipTest("test needs a valid user (set when run)")
  96. if os.getuid() != 0:
  97. self.skipTest("test must run as root (uid is not 0)")
  98. if os.geteuid() != 0:
  99. self.skipTest("test must run as root (euid is not 0)")
  100. bob = subprocess.Popen(args=(BIND10_EXE, "-u", SUID_USER),
  101. stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  102. started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
  103. self.assertTrue(started_ok)
  104. ps = subprocess.Popen(args=("ps", "axo", "user,pid"),
  105. stdout=subprocess.PIPE)
  106. s = ps.stdout.readline()
  107. ps_user = None
  108. while True:
  109. s = ps.stdout.readline()
  110. if s == '': break
  111. (user, pid) = s.split()
  112. if int(pid) == bob.pid:
  113. ps_user = user.decode()
  114. break
  115. self.assertTrue(ps_user is not None)
  116. self.assertTrue(ps_user == SUID_USER)
  117. time.sleep(0.1)
  118. bob.terminate()
  119. x = bob.wait()
  120. self.assertTrue(bob.wait() == 0)
  121. def testPrettyName(self):
  122. """Try the --pretty-name option."""
  123. CMD_PRETTY_NAME = b'bob-name-test'
  124. bob = subprocess.Popen(args=(BIND10_EXE, '--pretty-name',
  125. CMD_PRETTY_NAME), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  126. started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
  127. self.assertTrue(started_ok)
  128. ps = subprocess.Popen(args=("ps", "axo", "pid,comm"),
  129. stdout=subprocess.PIPE)
  130. s = ps.stdout.readline()
  131. command = None
  132. while True:
  133. s = ps.stdout.readline()
  134. if s == '': break
  135. (pid,comm) = s.split(None, 1)
  136. if int(pid) == bob.pid:
  137. command = comm
  138. break
  139. self.assertEqual(command, CMD_PRETTY_NAME + b'\n')
  140. time.sleep(0.1)
  141. bob.terminate()
  142. bob.wait()
  143. if __name__ == '__main__':
  144. unittest.main()