(root)/
Python-3.11.7/
Lib/
test/
test_crypt.py
       1  import sys
       2  import unittest
       3  from test.support import check_sanitizer, warnings_helper
       4  
       5  
       6  try:
       7      if check_sanitizer(address=True, memory=True):
       8          raise unittest.SkipTest("The crypt module SEGFAULTs on ASAN/MSAN builds")
       9      crypt = warnings_helper.import_deprecated("crypt")
      10      IMPORT_ERROR = None
      11  except ImportError as ex:
      12      if sys.platform != 'win32':
      13          raise unittest.SkipTest(str(ex))
      14      crypt = None
      15      IMPORT_ERROR = str(ex)
      16  
      17  
      18  @unittest.skipUnless(sys.platform == 'win32', 'This should only run on windows')
      19  @unittest.skipIf(crypt, 'import succeeded')
      20  class ESC[4;38;5;81mTestWhyCryptDidNotImport(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      21  
      22      def test_import_failure_message(self):
      23          self.assertIn('not supported', IMPORT_ERROR)
      24  
      25  
      26  @unittest.skipUnless(crypt, 'crypt module is required')
      27  class ESC[4;38;5;81mCryptTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      28  
      29      def test_crypt(self):
      30          cr = crypt.crypt('mypassword')
      31          cr2 = crypt.crypt('mypassword', cr)
      32          self.assertEqual(cr2, cr)
      33          cr = crypt.crypt('mypassword', 'ab')
      34          if cr is not None:
      35              cr2 = crypt.crypt('mypassword', cr)
      36              self.assertEqual(cr2, cr)
      37  
      38      def test_salt(self):
      39          self.assertEqual(len(crypt._saltchars), 64)
      40          for method in crypt.methods:
      41              salt = crypt.mksalt(method)
      42              self.assertIn(len(salt) - method.salt_chars, {0, 1, 3, 4, 6, 7})
      43              if method.ident:
      44                  self.assertIn(method.ident, salt[:len(salt)-method.salt_chars])
      45  
      46      def test_saltedcrypt(self):
      47          for method in crypt.methods:
      48              cr = crypt.crypt('assword', method)
      49              self.assertEqual(len(cr), method.total_size)
      50              cr2 = crypt.crypt('assword', cr)
      51              self.assertEqual(cr2, cr)
      52              cr = crypt.crypt('assword', crypt.mksalt(method))
      53              self.assertEqual(len(cr), method.total_size)
      54  
      55      def test_methods(self):
      56          self.assertTrue(len(crypt.methods) >= 1)
      57          if sys.platform.startswith('openbsd'):
      58              self.assertEqual(crypt.methods, [crypt.METHOD_BLOWFISH])
      59          else:
      60              self.assertEqual(crypt.methods[-1], crypt.METHOD_CRYPT)
      61  
      62      @unittest.skipUnless(
      63          crypt
      64          and (
      65              crypt.METHOD_SHA256 in crypt.methods or crypt.METHOD_SHA512 in crypt.methods
      66          ),
      67          'requires support of SHA-2',
      68      )
      69      def test_sha2_rounds(self):
      70          for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512):
      71              for rounds in 1000, 10_000, 100_000:
      72                  salt = crypt.mksalt(method, rounds=rounds)
      73                  self.assertIn('$rounds=%d$' % rounds, salt)
      74                  self.assertEqual(len(salt) - method.salt_chars,
      75                                   11 + len(str(rounds)))
      76                  cr = crypt.crypt('mypassword', salt)
      77                  self.assertTrue(cr)
      78                  cr2 = crypt.crypt('mypassword', cr)
      79                  self.assertEqual(cr2, cr)
      80  
      81      @unittest.skipUnless(
      82          crypt and crypt.METHOD_BLOWFISH in crypt.methods, 'requires support of Blowfish'
      83      )
      84      def test_blowfish_rounds(self):
      85          for log_rounds in range(4, 11):
      86              salt = crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1 << log_rounds)
      87              self.assertIn('$%02d$' % log_rounds, salt)
      88              self.assertIn(len(salt) - crypt.METHOD_BLOWFISH.salt_chars, {6, 7})
      89              cr = crypt.crypt('mypassword', salt)
      90              self.assertTrue(cr)
      91              cr2 = crypt.crypt('mypassword', cr)
      92              self.assertEqual(cr2, cr)
      93  
      94      def test_invalid_rounds(self):
      95          for method in (crypt.METHOD_SHA256, crypt.METHOD_SHA512,
      96                         crypt.METHOD_BLOWFISH):
      97              with self.assertRaises(TypeError):
      98                  crypt.mksalt(method, rounds='4096')
      99              with self.assertRaises(TypeError):
     100                  crypt.mksalt(method, rounds=4096.0)
     101              for rounds in (0, 1, -1, 1<<999):
     102                  with self.assertRaises(ValueError):
     103                      crypt.mksalt(method, rounds=rounds)
     104          with self.assertRaises(ValueError):
     105              crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=1000)
     106          for method in (crypt.METHOD_CRYPT, crypt.METHOD_MD5):
     107              with self.assertRaisesRegex(ValueError, 'support'):
     108                  crypt.mksalt(method, rounds=4096)
     109  
     110  
     111  if __name__ == "__main__":
     112      unittest.main()