1
0

test_auth.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. # Import Salt libs
  19. import salt.utils.platform
  20. from salt.utils.pycrypto import gen_hash
  21. # Import 3rd-party libs
  22. import pytest
  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. @pytest.mark.skip_if_not_root
  40. @skipIf(pwd is None, 'Skip if no pwd module exists')
  41. @pytest.mark.destructive_test
  42. @pytest.mark.windows_whitelisted
  43. class AuthTest(ShellCase):
  44. '''
  45. Test auth mechanisms
  46. '''
  47. _call_binary_ = 'salt'
  48. userA = 'saltdev'
  49. userB = 'saltadm'
  50. group = 'saltops'
  51. def setUp(self):
  52. for user in (self.userA, self.userB):
  53. try:
  54. if salt.utils.platform.is_darwin() and user not in str(self.run_call('user.list_users')):
  55. # workaround for https://github.com/saltstack/salt-jenkins/issues/504
  56. raise KeyError
  57. pwd.getpwnam(user)
  58. except KeyError:
  59. self.run_call('user.add {0} createhome=False'.format(user))
  60. # only put userB into the group for the group auth test
  61. try:
  62. if salt.utils.platform.is_darwin() and self.group not in str(self.run_call('group.info {0}'.format(self.group))):
  63. # workaround for https://github.com/saltstack/salt-jenkins/issues/504
  64. raise KeyError
  65. grp.getgrnam(self.group)
  66. except KeyError:
  67. self.run_call('group.add {0}'.format(self.group))
  68. self.run_call('user.chgroups {0} {1} True'.format(self.userB, self.group))
  69. def tearDown(self):
  70. for user in (self.userA, self.userB):
  71. try:
  72. pwd.getpwnam(user)
  73. except KeyError:
  74. pass
  75. else:
  76. self.run_call('user.delete {0}'.format(user))
  77. try:
  78. grp.getgrnam(self.group)
  79. except KeyError:
  80. pass
  81. else:
  82. self.run_call('group.delete {0}'.format(self.group))
  83. def test_pam_auth_valid_user(self):
  84. '''
  85. test that pam auth mechanism works with a valid user
  86. '''
  87. password, hashed_pwd = gen_password()
  88. # set user password
  89. set_pw_cmd = "shadow.set_password {0} '{1}'".format(
  90. self.userA,
  91. password if salt.utils.platform.is_darwin() else hashed_pwd
  92. )
  93. self.run_call(set_pw_cmd)
  94. # test user auth against pam
  95. cmd = ('-a pam "*" test.ping '
  96. '--username {0} --password {1}'.format(self.userA, password))
  97. resp = self.run_salt(cmd)
  98. log.debug('resp = %s', resp)
  99. self.assertTrue(
  100. 'minion:' in resp
  101. )
  102. def test_pam_auth_invalid_user(self):
  103. '''
  104. test pam auth mechanism errors for an invalid user
  105. '''
  106. cmd = ('-a pam "*" test.ping '
  107. '--username nouser --password {0}'.format('abcd1234'))
  108. resp = self.run_salt(cmd)
  109. self.assertTrue(
  110. 'Authentication error occurred.' in ''.join(resp)
  111. )
  112. def test_pam_auth_valid_group(self):
  113. '''
  114. test that pam auth mechanism works for a valid group
  115. '''
  116. password, hashed_pwd = gen_password()
  117. # set user password
  118. set_pw_cmd = "shadow.set_password {0} '{1}'".format(
  119. self.userB,
  120. password if salt.utils.platform.is_darwin() else hashed_pwd
  121. )
  122. self.run_call(set_pw_cmd)
  123. # test group auth against pam: saltadm is not configured in
  124. # external_auth, but saltops is and saldadm is a member of saltops
  125. cmd = ('-a pam "*" test.ping '
  126. '--username {0} --password {1}'.format(self.userB, password))
  127. resp = self.run_salt(cmd)
  128. self.assertTrue(
  129. 'minion:' in resp
  130. )