summaryrefslogtreecommitdiff
path: root/passlib/handlers/misc.py
diff options
context:
space:
mode:
Diffstat (limited to 'passlib/handlers/misc.py')
-rw-r--r--passlib/handlers/misc.py65
1 files changed, 46 insertions, 19 deletions
diff --git a/passlib/handlers/misc.py b/passlib/handlers/misc.py
index 06d9400..4244e14 100644
--- a/passlib/handlers/misc.py
+++ b/passlib/handlers/misc.py
@@ -8,8 +8,8 @@ import logging; log = logging.getLogger(__name__)
from warnings import warn
#site
#libs
-from passlib.utils import to_native_str
-from passlib.utils.compat import bytes, unicode
+from passlib.utils import to_native_str, consteq
+from passlib.utils.compat import bytes, unicode, u
import passlib.utils.handlers as uh
#pkg
#local
@@ -37,55 +37,82 @@ class unix_fallback(uh.StaticHandler):
"""
name = "unix_fallback"
context_kwds = ("enable_wildcard",)
- _stub_config = "!"
@classmethod
def identify(cls, hash):
return hash is not None
- @classmethod
- def genhash(cls, secret, hash, enable_wildcard=False):
+ def __init__(self, enable_wildcard=False, **kwds):
+ super(unix_fallback, self).__init__(**kwds)
+ self.enable_wildcard = enable_wildcard
+
+ def _calc_checksum(self, secret):
if secret is None:
raise TypeError("secret must be string")
- if hash is None:
- raise ValueError("no hash provided")
- # NOTE: hash will generally be "!"
- return to_native_str(hash, "ascii", errname="hash")
+ if self.checksum:
+ # NOTE: hash will generally be "!", but we want to preserve
+ # it in case it's something else, like "*".
+ return self.checksum
+ else:
+ return u("!")
@classmethod
def verify(cls, secret, hash, enable_wildcard=False):
- if hash is None:
+ if secret is None:
+ raise TypeError("secret must be string")
+ elif hash is None:
raise ValueError("no hash provided")
elif hash:
return False
else:
return enable_wildcard
-class plaintext(uh.StaticHandler):
+class plaintext(object):
"""This class stores passwords in plaintext, and follows the :ref:`password-hash-api`.
Unicode passwords will be encoded using 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)
+
+ # NOTE: this is subclassed by ldap_plaintext
+
name = "plaintext"
+ setting_kwds = ()
+ context_kwds = ()
+ _hash_encoding = "utf-8"
@classmethod
def identify(cls, hash):
+ # by default, identify ALL strings
return hash is not None
- # 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)
+ @classmethod
+ def encrypt(cls, secret):
+ return to_native_str(secret, cls._hash_encoding, "secret")
@classmethod
- def genhash(cls, secret, hash):
- return to_native_str(secret, "utf-8", errname="secret")
+ def verify(cls, secret, hash):
+ if hash is None:
+ raise TypeError("no hash specified")
+ elif not cls.identify(hash):
+ raise ValueError("not a %s hash" % (cls.name,))
+ hash = to_native_str(hash, cls._hash_encoding, "hash")
+ return consteq(cls.encrypt(secret), hash)
@classmethod
- def _norm_hash(cls, hash):
- return to_native_str(hash, "utf-8", errname="hash")
+ def genconfig(cls):
+ return None
+
+ @classmethod
+ def genhash(cls, secret, hash):
+ if hash is not None and not cls.identify(hash):
+ raise ValueError("not a %s hash" % (cls.name,))
+ return cls.encrypt(secret)
#=========================================================
#eof