diff options
author | Eli Collins <elic@assurancetechnologies.com> | 2012-04-27 02:00:47 -0400 |
---|---|---|
committer | Eli Collins <elic@assurancetechnologies.com> | 2012-04-27 02:00:47 -0400 |
commit | d8aad831a7579bfb6a8829e934695477dcb3e833 (patch) | |
tree | ce10aa1f2d687dad2baf3acc9b4411b76517bc3c /passlib | |
parent | ed21857d8a616fda97836a519ce353896c9fed69 (diff) | |
download | passlib-d8aad831a7579bfb6a8829e934695477dcb3e833.tar.gz |
made support for encoding context keyword uniform
- plaintext, ldap_plaintext, lmhash, htdigest all support it
- also expose default_encoding attribute
- moved HasEncodingContext from lmhash to handlers
Diffstat (limited to 'passlib')
-rw-r--r-- | passlib/handlers/digests.py | 11 | ||||
-rw-r--r-- | passlib/handlers/misc.py | 37 | ||||
-rw-r--r-- | passlib/handlers/windows.py | 18 | ||||
-rw-r--r-- | passlib/utils/handlers.py | 9 |
4 files changed, 42 insertions, 33 deletions
diff --git a/passlib/handlers/digests.py b/passlib/handlers/digests.py index e5de2eb..b746f52 100644 --- a/passlib/handlers/digests.py +++ b/passlib/handlers/digests.py @@ -86,12 +86,15 @@ class htdigest(object): """ name = "htdigest" setting_kwds = () - context_kwds = ("user", "realm") + context_kwds = ("user", "realm", "encoding") + default_encoding = "utf-8" @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. + def encrypt(cls, secret, user, realm, encoding=None): + # NOTE: this was deliberately written so that raw bytes are passed through + # unchanged, the encoding kwd is only used to handle unicode values. + if not encoding: + encoding = cls.default_encoding uh.validate_secret(secret) if isinstance(secret, unicode): secret = secret.encode(encoding) diff --git a/passlib/handlers/misc.py b/passlib/handlers/misc.py index ac6e72a..dcb56c6 100644 --- a/passlib/handlers/misc.py +++ b/passlib/handlers/misc.py @@ -150,21 +150,22 @@ class unix_disabled(object): class plaintext(object): """This class stores passwords in plaintext, and follows the :ref:`password-hash-api`. - Unicode passwords will be encoded using utf-8. + :type encoding: str + :param encoding: + This controls the character encoding to use (defaults to ``utf-8``). - Under Python 3, existing 'hashes' must decode as utf-8. - """ - # NOTE: this tries to avoid decoding bytes under py2, - # for applications that are using latin-1 or some other encoding. - # they'll just have to stop using plaintext under py3 :) - # (or re-encode as utf-8) + This encoding will be used to encode :class:`!unicode` passwords + under Python 2, and decode :class:`!bytes` hashes under Python 3. + .. versionchanged:: 1.6 + The ``encoding`` keyword was added. + """ # NOTE: this is subclassed by ldap_plaintext name = "plaintext" setting_kwds = () - context_kwds = () - _hash_encoding = "utf-8" + context_kwds = ("encoding",) + default_encoding = "utf-8" @classmethod def identify(cls, hash): @@ -174,26 +175,30 @@ class plaintext(object): raise uh.exc.ExpectedStringError(hash, "hash") @classmethod - def encrypt(cls, secret): + def encrypt(cls, secret, encoding=None): uh.validate_secret(secret) - return to_native_str(secret, cls._hash_encoding, "secret") + if not encoding: + encoding = cls.default_encoding + return to_native_str(secret, encoding, "secret") @classmethod - def verify(cls, secret, hash): - hash = to_native_str(hash, cls._hash_encoding, "hash") + def verify(cls, secret, hash, encoding=None): + if not encoding: + encoding = cls.default_encoding + hash = to_native_str(hash, encoding, "hash") if not cls.identify(hash): raise uh.exc.InvalidHashError(cls) - return consteq(cls.encrypt(secret), hash) + return consteq(cls.encrypt(secret, encoding), hash) @classmethod def genconfig(cls): return None @classmethod - def genhash(cls, secret, hash): + def genhash(cls, secret, hash, encoding=None): if hash is not None and not cls.identify(hash): raise uh.exc.InvalidHashError(cls) - return cls.encrypt(secret) + return cls.encrypt(secret, encoding) #========================================================= #eof diff --git a/passlib/handlers/windows.py b/passlib/handlers/windows.py index 1670d5c..bb9fdac 100644 --- a/passlib/handlers/windows.py +++ b/passlib/handlers/windows.py @@ -26,17 +26,7 @@ __all__ = [ #========================================================= # lanman hash #========================================================= - -class _HasEncodingContext(uh.GenericHandler): - # NOTE: consider moving this to helpers if other classes could use it. - context_kwds = ("encoding",) - _default_encoding = "utf-8" - - def __init__(self, encoding=None, **kwds): - super(_HasEncodingContext, self).__init__(**kwds) - self.encoding = encoding or self._default_encoding - -class lmhash(_HasEncodingContext, uh.StaticHandler): +class lmhash(uh.HasEncodingContext, uh.StaticHandler): """This class implements the Lan Manager Password hash, and follows the :ref:`password-hash-api`. It has no salt and a single fixed round. @@ -59,7 +49,7 @@ class lmhash(_HasEncodingContext, uh.StaticHandler): name = "lmhash" checksum_chars = uh.HEX_CHARS checksum_size = 32 - _default_encoding = "cp437" + default_encoding = "cp437" #========================================================= # methods @@ -75,7 +65,7 @@ class lmhash(_HasEncodingContext, uh.StaticHandler): _magic = b("KGS!@#$%") @classmethod - def raw(cls, secret, encoding="cp437"): + def raw(cls, secret, encoding=None): """encode password using LANMAN hash algorithm. :arg secret: secret as unicode or utf-8 encoded bytes @@ -86,6 +76,8 @@ class lmhash(_HasEncodingContext, uh.StaticHandler): :returns: returns string of raw bytes """ + if not encoding: + encoding = cls.default_encoding # some nice empircal data re: different encodings is at... # http://www.openwall.com/lists/john-dev/2011/08/01/2 # http://www.freerainbowtables.com/phpBB3/viewtopic.php?t=387&p=12163 diff --git a/passlib/utils/handlers.py b/passlib/utils/handlers.py index 76de5bc..e956cc3 100644 --- a/passlib/utils/handlers.py +++ b/passlib/utils/handlers.py @@ -678,6 +678,15 @@ class StaticHandler(GenericHandler): #===================================================== #GenericHandler mixin classes #===================================================== +class HasEncodingContext(GenericHandler): + """helper for classes which require knowledge of the encoding used""" + context_kwds = ("encoding",) + default_encoding = "utf-8" + + def __init__(self, encoding=None, **kwds): + super(HasEncodingContext, self).__init__(**kwds) + self.encoding = encoding or self.default_encoding + class HasUserContext(GenericHandler): """helper for classes which require a user context keyword""" context_kwds = ("user",) |