test_auth.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. # -*- coding: utf-8 -*-
  2. '''
  3. tests.integration.shell.auth
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. '''
  6. # Import Python libs
  7. from __future__ import absolute_import, print_function, unicode_literals
  8. import logging
  9. try:
  10. import pwd
  11. import grp
  12. except ImportError:
  13. pwd, grp = None, None
  14. import random
  15. # Import Salt Testing libs
  16. from tests.support.case import ShellCase
  17. from tests.support.unit import skipIf
  18. from tests.support.helpers import destructiveTest, skip_if_not_root
  19. # Import Salt libs
  20. import salt.utils.platform
  21. from salt.utils.pycrypto import gen_hash
  22. # Import 3rd-party libs
  23. from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
  24. log = logging.getLogger(__name__)
  25. def gen_password():
  26. '''
  27. generate a password and hash it
  28. '''
  29. alphabet = ('abcdefghijklmnopqrstuvwxyz'
  30. '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')
  31. password = ''
  32. # generate password
  33. for _ in range(20):
  34. next_index = random.randrange(len(alphabet))
  35. password += alphabet[next_index]
  36. # hash the password
  37. hashed_pwd = gen_hash('salt', password, 'sha512')
  38. return (password, hashed_pwd)
  39. @skip_if_not_root
  40. @skipIf(pwd is None, 'Skip if no pwd module exists')
  41. @destructiveTest
  42. class AuthTest(ShellCase):
  43. '''
  44. Test auth mechanisms
  45. '''
  46. _call_binary_ = 'salt'
  47. userA = 'saltdev'
  48. userB = 'saltadm'
  49. group = 'saltops'
  50. def setUp(self):
  51. for user in (self.userA, self.userB):
  52. try:
  53. if salt.utils.platform.is_darwin() and user not in str(self.run_call('user.list_users')):
  54. # workaround for https://github.com/saltstack/salt-jenkins/issues/504
  55. raise KeyError
  56. pwd.getpwnam(user)
  57. except KeyError:
  58. self.run_call('user.add {0} createhome=False'.format(user))
  59. # only put userB into the group for the group auth test
  60. try:
  61. if salt.utils.platform.is_darwin() and self.group not in str(self.run_call('group.info {0}'.format(self.group))):
  62. # workaround for https://github.com/saltstack/salt-jenkins/issues/504
  63. raise KeyError
  64. grp.getgrnam(self.group)
  65. except KeyError:
  66. self.run_call('group.add {0}'.format(self.group))
  67. self.run_call('user.chgroups {0} {1} True'.format(self.userB, self.group))
  68. def tearDown(self):
  69. for user in (self.userA, self.userB):
  70. try:
  71. pwd.getpwnam(user)
  72. except KeyError:
  73. pass
  74. else:
  75. self.run_call('user.delete {0}'.format(user))
  76. try:
  77. grp.getgrnam(self.group)
  78. except KeyError:
  79. pass
  80. else:
  81. self.run_call('group.delete {0}'.format(self.group))
  82. def test_pam_auth_valid_user(self):
  83. '''
  84. test that pam auth mechanism works with a valid user
  85. '''
  86. password, hashed_pwd = gen_password()
  87. # set user password
  88. set_pw_cmd = "shadow.set_password {0} '{1}'".format(
  89. self.userA,
  90. password if salt.utils.platform.is_darwin() else hashed_pwd
  91. )
  92. self.run_call(set_pw_cmd)
  93. # test user auth against pam
  94. cmd = ('-a pam "*" test.ping '
  95. '--username {0} --password {1}'.format(self.userA, password))
  96. resp = self.run_salt(cmd)
  97. log.debug('resp = %s', resp)
  98. self.assertTrue(
  99. 'minion:' in resp
  100. )
  101. def test_pam_auth_invalid_user(self):
  102. '''
  103. test pam auth mechanism errors for an invalid user
  104. '''
  105. cmd = ('-a pam "*" test.ping '
  106. '--username nouser --password {0}'.format('abcd1234'))
  107. resp = self.run_salt(cmd)
  108. self.assertTrue(
  109. 'Authentication error occurred.' in ''.join(resp)
  110. )
  111. def test_pam_auth_valid_group(self):
  112. '''
  113. test that pam auth mechanism works for a valid group
  114. '''
  115. password, hashed_pwd = gen_password()
  116. # set user password
  117. set_pw_cmd = "shadow.set_password {0} '{1}'".format(
  118. self.userB,
  119. password if salt.utils.platform.is_darwin() else hashed_pwd
  120. )
  121. self.run_call(set_pw_cmd)
  122. # test group auth against pam: saltadm is not configured in
  123. # external_auth, but saltops is and saldadm is a member of saltops
  124. cmd = ('-a pam "*" test.ping '
  125. '--username {0} --password {1}'.format(self.userB, password))
  126. resp = self.run_salt(cmd)
  127. self.assertTrue(
  128. 'minion:' in resp
  129. )