示例#1
0
    def test_crypt(self):
        """test crypt.crypt() wrappers"""
        from lib.passlib.utils import has_crypt, safe_crypt, test_crypt

        # test everything is disabled
        if not has_crypt:
            self.assertEqual(safe_crypt("test", "aa"), None)
            self.assertFalse(test_crypt("test", "aaqPiZY5xR5l."))
            raise self.skipTest("crypt.crypt() not available")

        # XXX: this assumes *every* crypt() implementation supports des_crypt.
        #      if this fails for some platform, this test will need modifying.

        # test return type
        self.assertIsInstance(safe_crypt(u("test"), u("aa")), unicode)

        # test ascii password
        h1 = u('aaqPiZY5xR5l.')
        self.assertEqual(safe_crypt(u('test'), u('aa')), h1)
        self.assertEqual(safe_crypt(b('test'), b('aa')), h1)

        # test utf-8 / unicode password
        h2 = u('aahWwbrUsKZk.')
        self.assertEqual(safe_crypt(u('test\u1234'), 'aa'), h2)
        self.assertEqual(safe_crypt(b('test\xe1\x88\xb4'), 'aa'), h2)

        # test latin-1 password
        hash = safe_crypt(b('test\xff'), 'aa')
        if PY3:  # py3 supports utf-8 bytes only.
            self.assertEqual(hash, None)
        else:  # but py2 is fine.
            self.assertEqual(hash, u('aaOx.5nbTU/.M'))

        # test rejects null chars in password
        self.assertRaises(ValueError, safe_crypt, '\x00', 'aa')

        # check test_crypt()
        h1x = h1[:-1] + 'x'
        self.assertTrue(test_crypt("test", h1))
        self.assertFalse(test_crypt("test", h1x))

        # check crypt returning variant error indicators
        # some platforms return None on errors, others empty string,
        # The BSDs in some cases return ":"
        import lib.passlib.utils as mod
        orig = mod._crypt
        try:
            fake = None
            mod._crypt = lambda secret, hash: fake
            for fake in [None, "", ":", ":0", "*0"]:
                self.assertEqual(safe_crypt("test", "aa"), None)
                self.assertFalse(test_crypt("test", h1))
            fake = 'xxx'
            self.assertEqual(safe_crypt("test", "aa"), "xxx")
        finally:
            mod._crypt = orig
示例#2
0
 def _calc_checksum_os_crypt(self, secret):
     config = self.to_string(config=True)
     hash = safe_crypt(secret, config)
     if hash:
         assert hash.startswith(config) and len(hash) == len(config) + 29
         return hash[-28:]
     else:
         return self._calc_checksum_builtin(secret)
示例#3
0
 def _calc_checksum_os_crypt(self, secret):
     config = self.ident + self.salt
     hash = safe_crypt(secret, config)
     if hash:
         assert hash.startswith(config) and len(hash) == len(config) + 23
         return hash[-22:]
     else:
         return self._calc_checksum_builtin(secret)
示例#4
0
 def _calc_checksum_os_crypt(self, secret):
     config = self.to_string(config=True)
     hash = safe_crypt(secret, config)
     if hash:
         assert hash.startswith(config) and len(hash) == len(config) + 29
         return hash[-28:]
     else:
         return self._calc_checksum_builtin(secret)
示例#5
0
 def _calc_checksum_os_crypt(self, secret):
     config = self.to_string()
     hash = safe_crypt(secret, config)
     if hash:
         assert hash.startswith(config[:9]) and len(hash) == 20
         return hash[-11:]
     else:
         return self._calc_checksum_builtin(secret)
示例#6
0
 def _calc_checksum_os_crypt(self, secret):
     # NOTE: safe_crypt encodes unicode secret -> utf8
     # no official policy since des-crypt predates unicode
     hash = safe_crypt(secret, self.salt)
     if hash:
         assert hash.startswith(self.salt) and len(hash) == 13
         return hash[2:]
     else:
         return self._calc_checksum_builtin(secret)
示例#7
0
 def _calc_checksum_os_crypt(self, secret):
     config = self.ident + self.salt
     hash = safe_crypt(secret, config)
     if hash:
         assert hash.startswith(config) and len(hash) == len(config) + 23
         return hash[-22:]
     else:
         # py3's crypt.crypt() can't handle non-utf8 bytes.
         # fallback to builtin alg, which is always available.
         return self._calc_checksum_builtin(secret)
示例#8
0
 def _calc_checksum_os_crypt(self, secret):
     hash = safe_crypt(secret, self.to_string())
     if hash:
         # NOTE: avoiding full parsing routine via from_string().checksum,
         # and just extracting the bit we need.
         cs = self.checksum_size
         assert hash.startswith(self.ident) and hash[-cs - 1] == _UDOLLAR
         return hash[-cs:]
     else:
         return self._calc_checksum_builtin(secret)
示例#9
0
 def _calc_checksum_os_crypt(self, secret):
     config = self.to_string()
     hash = safe_crypt(secret, config)
     if hash:
         assert hash.startswith(config[:9]) and len(hash) == 20
         return hash[-11:]
     else:
         # py3's crypt.crypt() can't handle non-utf8 bytes.
         # fallback to builtin alg, which is always available.
         return self._calc_checksum_builtin(secret)
示例#10
0
 def _calc_checksum_os_crypt(self, secret):
     hash = safe_crypt(secret, self.to_string())
     if hash:
         # NOTE: avoiding full parsing routine via from_string().checksum,
         # and just extracting the bit we need.
         cs = self.checksum_size
         assert hash.startswith(self.ident) and hash[-cs-1] == _UDOLLAR
         return hash[-cs:]
     else:
         return self._calc_checksum_builtin(secret)
示例#11
0
 def _calc_checksum_os_crypt(self, secret):
     # NOTE: we let safe_crypt() encode unicode secret -> utf8;
     #       no official policy since des-crypt predates unicode
     hash = safe_crypt(secret, self.salt)
     if hash:
         assert hash.startswith(self.salt) and len(hash) == 13
         return hash[2:]
     else:
         # py3's crypt.crypt() can't handle non-utf8 bytes.
         # fallback to builtin alg, which is always available.
         return self._calc_checksum_builtin(secret)
示例#12
0
 def _calc_checksum_os_crypt(self, secret):
     hash = safe_crypt(secret, self.to_string())
     if hash:
         # NOTE: avoiding full parsing routine via from_string().checksum,
         # and just extracting the bit we need.
         cs = self.checksum_size
         assert hash.startswith(self.ident) and hash[-cs - 1] == _UDOLLAR
         return hash[-cs:]
     else:
         # py3's crypt.crypt() can't handle non-utf8 bytes.
         # fallback to builtin alg, which is always available.
         return self._calc_checksum_builtin(secret)
示例#13
0
 def _calc_checksum_os_crypt(self, secret, config):
     hash = safe_crypt(secret, config)
     if hash:
         assert hash.startswith(config) and len(hash) == len(config)+31
         return hash[-31:]
     else:
         # NOTE: Have to raise this error because python3's crypt.crypt() only accepts unicode.
         #       This means it can't handle any passwords that aren't either unicode
         #       or utf-8 encoded bytes.  However, hashing a password with an alternate
         #       encoding should be a pretty rare edge case; if user needs it, they can just
         #       install bcrypt backend.
         # XXX: is this the right error type to raise?
         #      maybe have safe_crypt() not swallow UnicodeDecodeError, and have handlers
         #      like sha256_crypt trap it if they have alternate method of handling them?
         raise uh.exc.MissingBackendError(
             "non-utf8 encoded passwords can't be handled by crypt.crypt() under python3, "
             "recommend running `pip install bcrypt`.",
             )