| | |
| | | import itertools |
| | | |
| | | from zope.interface import implements |
| | | from zope.interface import implementer |
| | | |
| | | from repoze.who.interfaces import IAuthenticator |
| | | from repoze.who.utils import resolveDotted |
| | | from repoze.who._compat import izip_longest |
| | | |
| | | |
| | | def _padding_for_file_lines(): |
| | | yield 'aaaaaa:bbbbbb' |
| | | |
| | | |
| | | @implementer(IAuthenticator) |
| | | class HTPasswdPlugin(object): |
| | | |
| | | implements(IAuthenticator) |
| | | |
| | | def __init__(self, filename, check): |
| | | self.filename = filename |
| | |
| | | # assumed to have a readline |
| | | self.filename.seek(0) |
| | | f = self.filename |
| | | must_close = False |
| | | else: |
| | | try: |
| | | f = open(self.filename, 'r') |
| | | must_close = True |
| | | except IOError: |
| | | environ['repoze.who.logger'].warn('could not open htpasswd ' |
| | | 'file %s' % self.filename) |
| | |
| | | maybe_user = username |
| | | to_check = hashed |
| | | |
| | | if must_close: |
| | | f.close() |
| | | |
| | | # Check *something* here, to mitigate a timing attack. |
| | | password_ok = self.check(password, to_check) |
| | | |
| | |
| | | def _same_string(x, y): |
| | | # Attempt at isochronous string comparison. |
| | | mismatches = filter(None, [a != b for a, b, ignored |
| | | in itertools.izip_longest(x, y, PADDING)]) |
| | | in izip_longest(x, y, PADDING)]) |
| | | if type(mismatches) != list: #pragma NO COVER Python >= 3.0 |
| | | mismatches = list(mismatches) |
| | | return len(mismatches) == 0 |
| | | |
| | | def crypt_check(password, hashed): |
| | |
| | | salt = hashed[:2] |
| | | return _same_string(hashed, crypt(password, salt)) |
| | | |
| | | def sha1_check(password, hashed): |
| | | from hashlib import sha1 |
| | | from base64 import standard_b64encode |
| | | from repoze.who._compat import must_encode |
| | | encrypted_string = standard_b64encode(sha1(must_encode(password)).digest()) |
| | | if hasattr(encrypted_string, "decode"): |
| | | encrypted_string = encrypted_string.decode() |
| | | return _same_string(hashed, "%s%s" % ("{SHA}", encrypted_string)) |
| | | |
| | | def plain_check(password, hashed): |
| | | return _same_string(password, hashed) |
| | | |