diff -r 058bb3dc685f -r 0b59724cb3f2 md5crypt.py --- a/md5crypt.py Mon Jan 04 18:40:30 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -# md5crypt.py -# -# 0423.2000 by michal wallace http://www.sabren.com/ -# based on perl's Crypt::PasswdMD5 by Luis Munoz (lem@cantv.net) -# based on /usr/src/libcrypt/crypt.c from FreeBSD 2.2.5-RELEASE -# -# MANY THANKS TO -# -# Carey Evans - http://home.clear.net.nz/pages/c.evans/ -# Dennis Marti - http://users.starpower.net/marti1/ -# -# For the patches that got this thing working! -# -# modification by logilab: -# * remove usage of the string module -# * don't include the magic string in the output string -# for true crypt.crypt compatibility -# * use hashlib module instead of md5 -######################################################### -"""md5crypt.py - Provides interoperable MD5-based crypt() function - -SYNOPSIS - - import md5crypt.py - - cryptedpassword = md5crypt.md5crypt(password, salt); - -DESCRIPTION - -unix_md5_crypt() provides a crypt()-compatible interface to the -rather new MD5-based crypt() function found in modern operating systems. -It's based on the implementation found on FreeBSD 2.2.[56]-RELEASE and -contains the following license in it: - - "THE BEER-WARE LICENSE" (Revision 42): - wrote this file. As long as you retain this notice you - can do whatever you want with this stuff. If we meet some day, and you think - this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp -""" - -MAGIC = b'$1$' # Magic string -ITOA64 = b"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - -from hashlib import md5 # pylint: disable=E0611 - -from six import text_type, indexbytes -from six.moves import range - - -def to64 (v, n): - ret = bytearray() - while (n - 1 >= 0): - n = n - 1 - ret.append(ITOA64[v & 0x3f]) - v = v >> 6 - return ret - -def crypt(pw, salt): - if isinstance(pw, text_type): - pw = pw.encode('utf-8') - if isinstance(salt, text_type): - salt = salt.encode('ascii') - # Take care of the magic string if present - if salt.startswith(MAGIC): - salt = salt[len(MAGIC):] - # salt can have up to 8 characters: - salt = salt.split(b'$', 1)[0] - salt = salt[:8] - ctx = pw + MAGIC + salt - final = md5(pw + salt + pw).digest() - for pl in range(len(pw), 0, -16): - if pl > 16: - ctx = ctx + final[:16] - else: - ctx = ctx + final[:pl] - # Now the 'weird' xform (??) - i = len(pw) - while i: - if i & 1: - ctx = ctx + b'\0' #if ($i & 1) { $ctx->add(pack("C", 0)); } - else: - ctx = ctx + pw[0] - i = i >> 1 - final = md5(ctx).digest() - # The following is supposed to make - # things run slower. - # my question: WTF??? - for i in range(1000): - ctx1 = b'' - if i & 1: - ctx1 = ctx1 + pw - else: - ctx1 = ctx1 + final[:16] - if i % 3: - ctx1 = ctx1 + salt - if i % 7: - ctx1 = ctx1 + pw - if i & 1: - ctx1 = ctx1 + final[:16] - else: - ctx1 = ctx1 + pw - final = md5(ctx1).digest() - # Final xform - passwd = b'' - passwd += to64((indexbytes(final, 0) << 16) - |(indexbytes(final, 6) << 8) - |(indexbytes(final, 12)),4) - passwd += to64((indexbytes(final, 1) << 16) - |(indexbytes(final, 7) << 8) - |(indexbytes(final, 13)), 4) - passwd += to64((indexbytes(final, 2) << 16) - |(indexbytes(final, 8) << 8) - |(indexbytes(final, 14)), 4) - passwd += to64((indexbytes(final, 3) << 16) - |(indexbytes(final, 9) << 8) - |(indexbytes(final, 15)), 4) - passwd += to64((indexbytes(final, 4) << 16) - |(indexbytes(final, 10) << 8) - |(indexbytes(final, 5)), 4) - passwd += to64((indexbytes(final, 11)), 2) - return passwd