/usr/share/pyshared/passlib/handlers/nthash.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 | """passlib.handlers.nthash - unix-crypt compatible nthash passwords"""
#=========================================================
#imports
#=========================================================
#core
import re
import logging; log = logging.getLogger(__name__)
from warnings import warn
#site
#libs
from passlib.utils import handlers as uh, to_unicode, to_hash_str, to_bytes, bytes
from passlib.utils.md4 import md4
#pkg
#local
__all__ = [
"NTHash",
]
#=========================================================
#handler
#=========================================================
class nthash(uh.HasManyIdents, uh.GenericHandler):
"""This class implements the NT Password hash in a manner compatible with the :ref:`modular-crypt-format`, and follows the :ref:`password-hash-api`.
It has no salt and a single fixed round.
The :meth:`encrypt()` and :meth:`genconfig` methods accept no optional keywords.
"""
#TODO: verify where $NT$ is being used.
##:param ident:
##This handler supports two different :ref:`modular-crypt-format` identifiers.
##It defaults to ``3``, but users may specify the alternate ``NT`` identifier
##which is used in some contexts.
#=========================================================
#class attrs
#=========================================================
#--GenericHandler--
name = "nthash"
setting_kwds = ("ident",)
checksum_chars = uh.LC_HEX_CHARS
_stub_checksum = u"0" * 32
#--HasManyIdents--
default_ident = u"$3$$"
ident_values = (u"$3$$", u"$NT$")
ident_aliases = {u"3": u"$3$$", u"NT": u"$NT$"}
#=========================================================
#formatting
#=========================================================
@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 nthash")
chk = hash[len(ident):]
return cls(ident=ident, checksum=chk, strict=True)
def to_string(self):
hash = self.ident + (self.checksum or self._stub_checksum)
return to_hash_str(hash)
#=========================================================
#primary interface
#=========================================================
def calc_checksum(self, secret):
return self.raw_nthash(secret, hex=True)
@staticmethod
def raw_nthash(secret, hex=False):
"""encode password using md4-based NTHASH algorithm
:returns:
returns string of raw bytes if ``hex=False``,
returns digest as hexidecimal unicode if ``hex=True``.
"""
secret = to_unicode(secret, "utf-8")
hash = md4(secret.encode("utf-16le"))
if hex:
return to_unicode(hash.hexdigest(), 'ascii')
else:
return hash.digest()
#=========================================================
#eoc
#=========================================================
#=========================================================
#eof
#=========================================================
|