123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- import hashlib
- import hmac
- from persistent.mapping import PersistentMapping
- from zope.annotation.interfaces import IAnnotations
- from zope.interface import implements
- from AccessControl.AuthEncoding import pw_encrypt
- from AccessControl.AuthEncoding import pw_validate
- from Products.remember.config import ANNOT_KEY
- from Products.remember.interfaces import IHashPW
- class BaseHash(object):
- """
- Abstract base class for actual hashing implementations.
- """
- implements(IHashPW)
- def __init__(self, context):
- self.context = context
- def isAvailable(self):
- return True
- def hashPassword(self, password):
- raise NotImplementedError
- def validate(self, reference, attempt):
- """
- Check to see if the reference is a hash of the attempt.
- """
- return self.hashPassword(attempt) == reference
- class BCryptHash(BaseHash):
- """
- Adapts from IAnnotatable to IHashPW. Uses bcrypt to hash the
- password
- """
- try:
- import bcrypt
- except ImportError:
- bcrypt = None
- def __init__(self, context):
- self.context = context
- if self.bcrypt is None:
- return
- annotations = IAnnotations(context)
- storage = annotations.setdefault(ANNOT_KEY,
- PersistentMapping())
- storage.setdefault('bcrypt_salt', self.bcrypt.gensalt())
- self.storage = storage
- def isAvailable(self):
- return self.bcrypt is not None
- def hashPassword(self, password):
- """
- Return a hashed version of password using bcrypt
- """
- return self.bcrypt.hashpw(password, self.storage['bcrypt_salt'])
- class SHAHash(BaseHash):
- """
- Adapts from IAnnotatable to IHashPW. Uses SHA to hash the password
- """
- def hashPassword(self, password):
- """
- Return a hashed version of password using SHA
- """
- return hashlib.sha1(password).hexdigest()
- class HMACHash(BaseHash):
- """
- Adapts from IAnnotatable to IHashPW. Uses SHA to hash the password
- """
- def __init__(self, context):
- self.context = context
- key = str(context)
- annotations = IAnnotations(context)
- storage = annotations.setdefault(ANNOT_KEY,
- PersistentMapping())
- storage.setdefault('hmac_key', key)
- self.storage = storage
- def hashPassword(self, password):
- """
- Return a hashed version of password using SHA
- """
- return hmac.new(self.storage['hmac_key'], password, hashlib.sha1
- ).hexdigest()
- class ZAuthHash(BaseHash):
- """
- Adapts from IAnnotatable to IHashPW. Uses Zope 2's
- AccessControl.AuthEncoding module to hash the password.
- """
- def hashPassword(self, password):
- """
- Delegate to AccessControl.AuthEncoding.
- """
- return pw_encrypt(password)
- def validate(self, reference, attempt):
- """
- Check to see if the reference is a hash of the attempt.
- """
- return pw_validate(reference, attempt)
|