Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_sspi.py 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. # Some tests of the win32security sspi functions.
  2. # Stolen from Roger's original test_sspi.c, a version of which is in "Demos"
  3. # See also the other SSPI demos.
  4. import re
  5. import unittest
  6. import sspi
  7. import sspicon
  8. import win32api
  9. import win32security
  10. from pywin32_testutil import TestSkipped, str2bytes, testmain
  11. # It is quite likely that the Kerberos tests will fail due to not being
  12. # installed. The NTLM tests do *not* get the same behaviour as they should
  13. # always be there.
  14. def applyHandlingSkips(func, *args):
  15. try:
  16. return func(*args)
  17. except win32api.error as exc:
  18. if exc.winerror in [
  19. sspicon.SEC_E_NO_CREDENTIALS,
  20. sspicon.SEC_E_NO_AUTHENTICATING_AUTHORITY,
  21. ]:
  22. raise TestSkipped(exc)
  23. raise
  24. class TestSSPI(unittest.TestCase):
  25. def assertRaisesHRESULT(self, hr, func, *args):
  26. try:
  27. return func(*args)
  28. raise RuntimeError("expecting %s failure" % (hr,))
  29. except win32security.error as exc:
  30. self.assertEqual(exc.winerror, hr)
  31. def _doAuth(self, pkg_name):
  32. sspiclient = sspi.ClientAuth(pkg_name, targetspn=win32api.GetUserName())
  33. sspiserver = sspi.ServerAuth(pkg_name)
  34. sec_buffer = None
  35. err = 1
  36. while err != 0:
  37. err, sec_buffer = sspiclient.authorize(sec_buffer)
  38. err, sec_buffer = sspiserver.authorize(sec_buffer)
  39. return sspiclient, sspiserver
  40. def _doTestImpersonate(self, pkg_name):
  41. # Just for the sake of code exercising!
  42. sspiclient, sspiserver = self._doAuth(pkg_name)
  43. sspiserver.ctxt.ImpersonateSecurityContext()
  44. sspiserver.ctxt.RevertSecurityContext()
  45. def testImpersonateKerberos(self):
  46. applyHandlingSkips(self._doTestImpersonate, "Kerberos")
  47. def testImpersonateNTLM(self):
  48. self._doTestImpersonate("NTLM")
  49. def _doTestEncrypt(self, pkg_name):
  50. sspiclient, sspiserver = self._doAuth(pkg_name)
  51. pkg_size_info = sspiclient.ctxt.QueryContextAttributes(
  52. sspicon.SECPKG_ATTR_SIZES
  53. )
  54. msg = str2bytes("some data to be encrypted ......")
  55. trailersize = pkg_size_info["SecurityTrailer"]
  56. encbuf = win32security.PySecBufferDescType()
  57. encbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
  58. encbuf.append(
  59. win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)
  60. )
  61. encbuf[0].Buffer = msg
  62. sspiclient.ctxt.EncryptMessage(0, encbuf, 1)
  63. sspiserver.ctxt.DecryptMessage(encbuf, 1)
  64. self.assertEqual(msg, encbuf[0].Buffer)
  65. # and test the higher-level functions
  66. data_in = str2bytes("hello")
  67. data, sig = sspiclient.encrypt(data_in)
  68. self.assertEqual(sspiserver.decrypt(data, sig), data_in)
  69. data, sig = sspiserver.encrypt(data_in)
  70. self.assertEqual(sspiclient.decrypt(data, sig), data_in)
  71. def _doTestEncryptStream(self, pkg_name):
  72. # Test out the SSPI/GSSAPI interop wrapping examples at
  73. # https://docs.microsoft.com/en-us/windows/win32/secauthn/sspi-kerberos-interoperability-with-gssapi
  74. sspiclient, sspiserver = self._doAuth(pkg_name)
  75. pkg_size_info = sspiclient.ctxt.QueryContextAttributes(
  76. sspicon.SECPKG_ATTR_SIZES
  77. )
  78. msg = str2bytes("some data to be encrypted ......")
  79. trailersize = pkg_size_info["SecurityTrailer"]
  80. blocksize = pkg_size_info["BlockSize"]
  81. encbuf = win32security.PySecBufferDescType()
  82. encbuf.append(
  83. win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)
  84. )
  85. encbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
  86. encbuf.append(
  87. win32security.PySecBufferType(blocksize, sspicon.SECBUFFER_PADDING)
  88. )
  89. encbuf[1].Buffer = msg
  90. sspiclient.ctxt.EncryptMessage(0, encbuf, 1)
  91. encmsg = encbuf[0].Buffer + encbuf[1].Buffer + encbuf[2].Buffer
  92. decbuf = win32security.PySecBufferDescType()
  93. decbuf.append(
  94. win32security.PySecBufferType(len(encmsg), sspicon.SECBUFFER_STREAM)
  95. )
  96. decbuf.append(win32security.PySecBufferType(0, sspicon.SECBUFFER_DATA))
  97. decbuf[0].Buffer = encmsg
  98. sspiserver.ctxt.DecryptMessage(decbuf, 1)
  99. self.assertEqual(msg, decbuf[1].Buffer)
  100. def testEncryptNTLM(self):
  101. self._doTestEncrypt("NTLM")
  102. def testEncryptStreamNTLM(self):
  103. self._doTestEncryptStream("NTLM")
  104. def testEncryptKerberos(self):
  105. applyHandlingSkips(self._doTestEncrypt, "Kerberos")
  106. def testEncryptStreamKerberos(self):
  107. applyHandlingSkips(self._doTestEncryptStream, "Kerberos")
  108. def _doTestSign(self, pkg_name):
  109. sspiclient, sspiserver = self._doAuth(pkg_name)
  110. pkg_size_info = sspiclient.ctxt.QueryContextAttributes(
  111. sspicon.SECPKG_ATTR_SIZES
  112. )
  113. msg = str2bytes("some data to be encrypted ......")
  114. sigsize = pkg_size_info["MaxSignature"]
  115. sigbuf = win32security.PySecBufferDescType()
  116. sigbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
  117. sigbuf.append(win32security.PySecBufferType(sigsize, sspicon.SECBUFFER_TOKEN))
  118. sigbuf[0].Buffer = msg
  119. sspiclient.ctxt.MakeSignature(0, sigbuf, 0)
  120. sspiserver.ctxt.VerifySignature(sigbuf, 0)
  121. # and test the higher-level functions
  122. sspiclient.next_seq_num = 1
  123. sspiserver.next_seq_num = 1
  124. data = str2bytes("hello")
  125. key = sspiclient.sign(data)
  126. sspiserver.verify(data, key)
  127. key = sspiclient.sign(data)
  128. self.assertRaisesHRESULT(
  129. sspicon.SEC_E_MESSAGE_ALTERED, sspiserver.verify, data + data, key
  130. )
  131. # and the other way
  132. key = sspiserver.sign(data)
  133. sspiclient.verify(data, key)
  134. key = sspiserver.sign(data)
  135. self.assertRaisesHRESULT(
  136. sspicon.SEC_E_MESSAGE_ALTERED, sspiclient.verify, data + data, key
  137. )
  138. def testSignNTLM(self):
  139. self._doTestSign("NTLM")
  140. def testSignKerberos(self):
  141. applyHandlingSkips(self._doTestSign, "Kerberos")
  142. def _testSequenceSign(self):
  143. # Only Kerberos supports sequence detection.
  144. sspiclient, sspiserver = self._doAuth("Kerberos")
  145. key = sspiclient.sign(b"hello")
  146. sspiclient.sign(b"hello")
  147. self.assertRaisesHRESULT(
  148. sspicon.SEC_E_OUT_OF_SEQUENCE, sspiserver.verify, b"hello", key
  149. )
  150. def testSequenceSign(self):
  151. applyHandlingSkips(self._testSequenceSign)
  152. def _testSequenceEncrypt(self):
  153. # Only Kerberos supports sequence detection.
  154. sspiclient, sspiserver = self._doAuth("Kerberos")
  155. blob, key = sspiclient.encrypt(b"hello")
  156. blob, key = sspiclient.encrypt(b"hello")
  157. self.assertRaisesHRESULT(
  158. sspicon.SEC_E_OUT_OF_SEQUENCE, sspiserver.decrypt, blob, key
  159. )
  160. def testSequenceEncrypt(self):
  161. applyHandlingSkips(self._testSequenceEncrypt)
  162. def testSecBufferRepr(self):
  163. desc = win32security.PySecBufferDescType()
  164. assert re.match(
  165. "PySecBufferDesc\(ulVersion: 0 \| cBuffers: 0 \| pBuffers: 0x[\da-fA-F]{8,16}\)",
  166. repr(desc),
  167. )
  168. buffer1 = win32security.PySecBufferType(0, sspicon.SECBUFFER_TOKEN)
  169. assert re.match(
  170. "PySecBuffer\(cbBuffer: 0 \| BufferType: 2 \| pvBuffer: 0x[\da-fA-F]{8,16}\)",
  171. repr(buffer1),
  172. )
  173. "PySecBuffer(cbBuffer: 0 | BufferType: 2 | pvBuffer: 0x000001B8CC6D8020)"
  174. desc.append(buffer1)
  175. assert re.match(
  176. "PySecBufferDesc\(ulVersion: 0 \| cBuffers: 1 \| pBuffers: 0x[\da-fA-F]{8,16}\)",
  177. repr(desc),
  178. )
  179. buffer2 = win32security.PySecBufferType(4, sspicon.SECBUFFER_DATA)
  180. assert re.match(
  181. "PySecBuffer\(cbBuffer: 4 \| BufferType: 1 \| pvBuffer: 0x[\da-fA-F]{8,16}\)",
  182. repr(buffer2),
  183. )
  184. desc.append(buffer2)
  185. assert re.match(
  186. "PySecBufferDesc\(ulVersion: 0 \| cBuffers: 2 \| pBuffers: 0x[\da-fA-F]{8,16}\)",
  187. repr(desc),
  188. )
  189. if __name__ == "__main__":
  190. testmain()