예제 #1
0
파일: apache.py 프로젝트: javierrami/GAM
def _init_htpasswd_context():

    # start with schemes built into apache
    schemes = [
        # builtin support added in apache 2.4
        # (https://bz.apache.org/bugzilla/show_bug.cgi?id=49288)
        "bcrypt",

        # support not "builtin" to apache, instead it requires support through host's crypt().
        # adding them here to allow editing htpasswd under windows and then deploying under unix.
        "sha256_crypt",
        "sha512_crypt",
        "des_crypt",

        # apache default as of 2.2.18, and still default in 2.4
        "apr_md5_crypt",

        # NOTE: apache says ONLY intended for transitioning htpasswd <-> ldap
        "ldap_sha1",

        # NOTE: apache says ONLY supported on Windows, Netware, TPF
        "plaintext"
    ]

    # apache can verify anything supported by the native crypt(),
    # though htpasswd tool can only generate a limited set of hashes.
    # (this list may overlap w/ builtin apache schemes)
    schemes.extend(registry.get_supported_os_crypt_schemes())

    # hack to remove dups and sort into preferred order
    preferred = schemes[:3] + ["apr_md5_crypt"] + schemes
    schemes = sorted(set(schemes), key=preferred.index)

    # NOTE: default will change to "portable" in passlib 2.0
    return CryptContext(schemes, default=htpasswd_defaults['portable_apache_22'])
예제 #2
0
def _init_htpasswd_context():

    # start with schemes built into apache
    schemes = [
        # builtin support added in apache 2.4
        # (https://bz.apache.org/bugzilla/show_bug.cgi?id=49288)
        "bcrypt",
        # support not "builtin" to apache, instead it requires support through host's crypt().
        # adding them here to allow editing htpasswd under windows and then deploying under unix.
        "sha256_crypt",
        "sha512_crypt",
        "des_crypt",
        # apache default as of 2.2.18, and still default in 2.4
        "apr_md5_crypt",
        # NOTE: apache says ONLY intended for transitioning htpasswd <-> ldap
        "ldap_sha1",
        # NOTE: apache says ONLY supported on Windows, Netware, TPF
        "plaintext",
    ]

    # apache can verify anything supported by the native crypt(),
    # though htpasswd tool can only generate a limited set of hashes.
    # (this list may overlap w/ builtin apache schemes)
    schemes.extend(registry.get_supported_os_crypt_schemes())

    # hack to remove dups and sort into preferred order
    preferred = schemes[:3] + ["apr_md5_crypt"] + schemes
    schemes = sorted(set(schemes), key=preferred.index)

    # NOTE: default will change to "portable" in passlib 2.0
    return CryptContext(schemes,
                        default=htpasswd_defaults["portable_apache_22"])
예제 #3
0
 def _iter_os_crypt_schemes():
     """helper which iterates over supported os_crypt schemes"""
     out = registry.get_supported_os_crypt_schemes()
     if out:
         # only offer disabled handler if there's another scheme in front,
         # as this can't actually hash any passwords
         out += ("unix_disabled", )
     return out
예제 #4
0
    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