def _load_backend_os_crypt(cls): # XXX: what to do if "2" isn't supported, but "2a" is? # "2" is *very* rare, and can fake it using "2a"+repeat_string h1 = '$2$04$......................1O4gOrCYaqBG3o/4LnT2ykQUt1wbyju' h2 = '$2a$04$......................qiOQjkB8hxU8OzRhS.GhRMa4VUnkPty' if test_crypt("test", h1) and test_crypt("test", h2): return cls._calc_checksum_os_crypt return None
def test_crypt(self): "test crypt.crypt() wrappers" from 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 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
def _load_backend_os_crypt(cls): if test_crypt("test", '$sha1$1$Wq3GL2Vp$C8U25GvfHS8qGHim' 'ExLaiSFlGkAe'): cls._set_calc_checksum_backend(cls._calc_checksum_os_crypt) return True else: return False
def _load_backend_os_crypt(cls): if test_crypt("test", 'abgOeLfPimXQo'): cls._set_calc_checksum_backend(cls._calc_checksum_os_crypt) return True else: return False
def _has_backend_os_crypt(cls): return test_crypt("test", '$1$test$pi/xDtU5WFVRqYS6BMU8X/')
def _has_backend_os_crypt(cls): return test_crypt( "test", "$6$rounds=1000$test$2M/Lx6Mtobqj" "Ljobw0Wmo4Q5OFx5nVLJvmgseatA6oMn" "yWeBdRDx4DU.1H3eGmse6pgsOgDisWBG" "I5c7TZauS0")
def _load_backend_os_crypt(cls): if test_crypt("test", '_/...lLDAxARksGCHin.'): return cls._calc_checksum_os_crypt return None
def _load_backend_os_crypt(cls): if test_crypt(*cls._test_hash): return cls._calc_checksum_os_crypt return None
def _load_backend_os_crypt(cls): if test_crypt("test", "$1$test$pi/xDtU5WFVRqYS6BMU8X/"): return cls._calc_checksum_os_crypt return None
def _has_backend_os_crypt(cls): # XXX: what to do if only h2 is supported? h1 is *very* rare. h1 = "$2$04$......................1O4gOrCYaqBG3o/4LnT2ykQUt1wbyju" h2 = "$2a$04$......................qiOQjkB8hxU8OzRhS.GhRMa4VUnkPty" return test_crypt("test", h1) and test_crypt("test", h2)
def _load_backend_os_crypt(cls): if test_crypt("test", '$1$test$pi/xDtU5WFVRqYS6BMU8X/'): return cls._calc_checksum_os_crypt return None
def _load_backend_os_crypt(cls): if test_crypt("test", '$sha1$1$Wq3GL2Vp$C8U25GvfHS8qGHim' 'ExLaiSFlGkAe'): return cls._calc_checksum_os_crypt return None
def _load_backend_os_crypt(cls): if test_crypt("test", '$1$test$pi/xDtU5WFVRqYS6BMU8X/'): cls._set_calc_checksum_backend(cls._calc_checksum_os_crypt) return True else: return False
def test_crypt(self): """test crypt.crypt() wrappers""" from passlib.utils import has_crypt, safe_crypt, test_crypt from passlib.registry import get_supported_os_crypt_schemes, get_crypt_handler # test everything is disabled supported = get_supported_os_crypt_schemes() if not has_crypt: self.assertEqual(supported, ()) self.assertEqual(safe_crypt("test", "aa"), None) self.assertFalse(test_crypt("test", "aaqPiZY5xR5l.")) # des_crypt() hash of "test" raise self.skipTest("crypt.crypt() not available") # expect there to be something supported, if crypt() is present if not supported: # NOTE: failures here should be investigated. usually means one of: # 1) at least one of passlib's os_crypt detection routines is giving false negative # 2) crypt() ONLY supports some hash alg which passlib doesn't know about # 3) crypt() is present but completely disabled (never encountered this yet) raise self.fail("crypt() present, but no supported schemes found!") # pick cheap alg if possible, with minimum rounds, to speed up this test. # NOTE: trusting hasher class works properly (should have been verified using it's own UTs) for scheme in ("md5_crypt", "sha256_crypt"): if scheme in supported: break else: scheme = supported[-1] hasher = get_crypt_handler(scheme) if getattr(hasher, "min_rounds", None): hasher = hasher.using(rounds=hasher.min_rounds) # helpers to generate hashes & config strings to work with def get_hash(secret): assert isinstance(secret, unicode) hash = hasher.hash(secret) if isinstance(hash, bytes): # py2 hash = hash.decode("utf-8") assert isinstance(hash, unicode) return hash # test ascii password & return type s1 = u("test") h1 = get_hash(s1) result = safe_crypt(s1, h1) self.assertIsInstance(result, unicode) self.assertEqual(result, h1) self.assertEqual(safe_crypt(to_bytes(s1), to_bytes(h1)), h1) # make sure crypt doesn't just blindly return h1 for whatever we pass in h1x = h1[:-2] + 'xx' self.assertEqual(safe_crypt(s1, h1x), h1) # test utf-8 / unicode password s2 = u('test\u1234') h2 = get_hash(s2) self.assertEqual(safe_crypt(s2, h2), h2) self.assertEqual(safe_crypt(to_bytes(s2), to_bytes(h2)), h2) # test rejects null chars in password self.assertRaises(ValueError, safe_crypt, '\x00', h1) # check test_crypt() 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 passlib.utils as mod orig = mod._crypt try: retval = None mod._crypt = lambda secret, hash: retval for retval in [None, "", ":", ":0", "*0"]: self.assertEqual(safe_crypt("test", h1), None) self.assertFalse(test_crypt("test", h1)) retval = 'xxx' self.assertEqual(safe_crypt("test", h1), "xxx") self.assertFalse(test_crypt("test", h1)) finally: mod._crypt = orig
def _load_backend_os_crypt(cls): if test_crypt("test", "_/...lLDAxARksGCHin."): return cls._calc_checksum_os_crypt return None
def _load_backend_os_crypt(cls): if test_crypt("test", 'abgOeLfPimXQo'): return cls._calc_checksum_os_crypt return None
def _load_backend_mixin(mixin_cls, name, dryrun): if not test_crypt("test", TEST_HASH_2A): return False return mixin_cls._finalize_backend_mixin(name, dryrun)
def _has_backend_os_crypt(cls): return test_crypt( "test", "$5$rounds=1000$test$QmQADEXMG8POI5W" "Dsaeho0P36yK3Tcrgboabng6bkb/")
def _has_backend_os_crypt(cls): return test_crypt("test", '$sha1$1$Wq3GL2Vp$C8U25GvfHS8qGHim' 'ExLaiSFlGkAe')
def _load_backend_os_crypt(cls): if test_crypt(*cls._test_hash): cls._set_calc_checksum_backend(cls._calc_checksum_os_crypt) return True else: return False
def _has_backend_os_crypt(cls): return test_crypt("test", 'abgOeLfPimXQo')
def _has_backend_os_crypt(cls): return test_crypt("test", '_/...lLDAxARksGCHin.')
def _load_backend_os_crypt(cls): if test_crypt("test", '_/...lLDAxARksGCHin.'): cls._set_calc_checksum_backend(cls._calc_checksum_os_crypt) return True else: return False
def _has_backend_os_crypt(cls): return test_crypt("test", "$5$rounds=1000$test$QmQADEXMG8POI5W" "Dsaeho0P36yK3Tcrgboabng6bkb/")
def _load_backend_os_crypt(cls): if test_crypt("test", "abgOeLfPimXQo"): return cls._calc_checksum_os_crypt return None
def _has_backend_os_crypt(cls): return test_crypt("test", "$6$rounds=1000$test$2M/Lx6Mtobqj" "Ljobw0Wmo4Q5OFx5nVLJvmgseatA6oMn" "yWeBdRDx4DU.1H3eGmse6pgsOgDisWBG" "I5c7TZauS0")
def _has_backend_os_crypt(cls): # XXX: what to do if only h2 is supported? h1 is *very* rare. h1 = '$2$04$......................1O4gOrCYaqBG3o/4LnT2ykQUt1wbyju' h2 = '$2a$04$......................qiOQjkB8hxU8OzRhS.GhRMa4VUnkPty' return test_crypt("test",h1) and test_crypt("test", h2)