summaryrefslogtreecommitdiff
path: root/passlib
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2012-04-27 02:00:47 -0400
committerEli Collins <elic@assurancetechnologies.com>2012-04-27 02:00:47 -0400
commitd8aad831a7579bfb6a8829e934695477dcb3e833 (patch)
treece10aa1f2d687dad2baf3acc9b4411b76517bc3c /passlib
parented21857d8a616fda97836a519ce353896c9fed69 (diff)
downloadpasslib-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.py11
-rw-r--r--passlib/handlers/misc.py37
-rw-r--r--passlib/handlers/windows.py18
-rw-r--r--passlib/utils/handlers.py9
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",)