/usr/share/pyshared/passlib/handlers/phpass.py is in python-passlib 1.5.3-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | """passlib.handlers.phpass - PHPass Portable Crypt
phppass located - http://www.openwall.com/phpass/
algorithm described - http://www.openwall.com/articles/PHP-Users-Passwords
phpass context - blowfish, bsdi_crypt, phpass
"""
#=========================================================
#imports
#=========================================================
#core
from hashlib import md5
import re
import logging; log = logging.getLogger(__name__)
from warnings import warn
#site
#libs
from passlib.utils import h64, handlers as uh, bytes, b, to_unicode, to_hash_str
#pkg
#local
__all__ = [
"phpass",
]
#=========================================================
#phpass
#=========================================================
class phpass(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.GenericHandler):
"""This class implements the PHPass Portable Hash, and follows the :ref:`password-hash-api`.
It supports a fixed-length salt, and a variable number of rounds.
The :meth:`encrypt()` and :meth:`genconfig` methods accept the following optional keywords:
:param salt:
Optional salt string.
If not specified, one will be autogenerated (this is recommended).
If specified, it must be 8 characters, drawn from the regexp range ``[./0-9A-Za-z]``.
:param rounds:
Optional number of rounds to use.
Defaults to 9, must be between 7 and 30, inclusive.
This value is logarithmic, the actual number of iterations used will be :samp:`2**{rounds}`.
:param ident:
phpBB3 uses ``H`` instead of ``P`` for it's identifier,
this may be set to ``H`` in order to generate phpBB3 compatible hashes.
it defaults to ``P``.
"""
#=========================================================
#class attrs
#=========================================================
#--GenericHandler--
name = "phpass"
setting_kwds = ("salt", "rounds", "ident")
checksum_chars = uh.H64_CHARS
#--HasSalt--
min_salt_size = max_salt_size = 8
salt_chars = uh.H64_CHARS
#--HasRounds--
default_rounds = 9
min_rounds = 7
max_rounds = 30
rounds_cost = "log2"
_strict_rounds_bounds = True
#--HasManyIdents--
default_ident = u"$P$"
ident_values = [u"$P$", u"$H$"]
ident_aliases = {u"P":u"$P$", u"H":u"$H$"}
#=========================================================
#formatting
#=========================================================
#$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0
# $P$
# 9
# IQRaTwmf
# eRo7ud9Fh4E2PdI0S3r.L0
@classmethod
def from_string(cls, hash):
if not hash:
raise ValueError("no hash specified")
if isinstance(hash, bytes):
hash = hash.decode('ascii')
for ident in cls.ident_values:
if hash.startswith(ident):
break
else:
raise ValueError("invalid phpass portable hash")
data = hash[len(ident):]
rounds, salt, chk = data[0], data[1:9], data[9:]
return cls(
ident=ident,
rounds=h64.decode_int6(rounds.encode("ascii")),
salt=salt,
checksum=chk,
strict=bool(chk),
)
def to_string(self):
hash = u"%s%s%s%s" % (self.ident,
h64.encode_int6(self.rounds).decode("ascii"),
self.salt,
self.checksum or u'')
return to_hash_str(hash)
#=========================================================
#backend
#=========================================================
def calc_checksum(self, secret):
#FIXME: can't find definitive policy on how phpass handles non-ascii.
if isinstance(secret, unicode):
secret = secret.encode("utf-8")
real_rounds = 1<<self.rounds
result = md5(self.salt.encode("ascii") + secret).digest()
r = 0
while r < real_rounds:
result = md5(result + secret).digest()
r += 1
return h64.encode_bytes(result).decode("ascii")
#=========================================================
#eoc
#=========================================================
#=========================================================
#eof
#=========================================================
|