From 29e7c681bed9a2a9b96f71b56b0bf4edca8ef044 Mon Sep 17 00:00:00 2001 From: Eli Collins Date: Tue, 17 Apr 2012 15:09:21 -0400 Subject: updated passlib.apache module's api - more flexible to use, changed some ambiguous method names --- passlib/handlers/digests.py | 62 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'passlib/handlers/digests.py') diff --git a/passlib/handlers/digests.py b/passlib/handlers/digests.py index ec08056..22c1c6a 100644 --- a/passlib/handlers/digests.py +++ b/passlib/handlers/digests.py @@ -9,7 +9,7 @@ import logging; log = logging.getLogger(__name__) from warnings import warn #site #libs -from passlib.utils import to_native_str +from passlib.utils import to_native_str, to_bytes, render_bytes, consteq from passlib.utils.compat import bascii_to_str, bytes, unicode, str_to_uascii import passlib.utils.handlers as uh from passlib.utils.md4 import md4 @@ -75,6 +75,66 @@ hex_sha1 = create_hex_hash(hashlib.sha1, "sha1") hex_sha256 = create_hex_hash(hashlib.sha256, "sha256") hex_sha512 = create_hex_hash(hashlib.sha512, "sha512") +#========================================================= +# htdigest +#========================================================= +class htdigest(object): + """htdigest hash function. + + .. todo:: + document this hash + """ + name = "htdigest" + setting_kwds = () + context_kwds = ("user", "realm") + + @classmethod + def encrypt(cls, secret, user, realm, encoding="utf-8"): + # NOTE: deliberately written so that raw bytes are passed through + # unchanged, encoding only used to handle unicode values. + uh.validate_secret(secret) + if isinstance(secret, unicode): + secret = secret.encode(encoding) + user = to_bytes(user, encoding, "user") + realm = to_bytes(realm, encoding, "realm") + data = render_bytes("%s:%s:%s", user, realm, secret) + return hashlib.md5(data).hexdigest() + + @classmethod + def _norm_hash(cls, hash): + "normalize hash to native string, and validate it" + hash = to_native_str(hash, errname="hash") + if len(hash) != 32: + raise uh.exc.MalformedHashError(cls, "wrong size") + for char in hash: + if char not in uh.LC_HEX_CHARS: + raise uh.exc.MalformedHashError(cls, "invalid chars in hash") + return hash + + @classmethod + def verify(cls, secret, hash, user, realm, encoding="utf-8"): + hash = cls._norm_hash(hash) + other = cls.encrypt(secret, user, realm, encoding) + return consteq(hash, other) + + @classmethod + def identify(cls, hash): + try: + cls._norm_hash(hash) + except ValueError: + return False + return True + + @classmethod + def genconfig(cls): + return None + + @classmethod + def genhash(cls, secret, config, user, realm, encoding="utf-8"): + if config is not None: + cls._norm_hash(config) + return cls.encrypt(secret, user, realm, encoding) + #========================================================= #eof #========================================================= -- cgit v1.2.1