From 710db132b0f10fee3897e581b190660e22b0b950 Mon Sep 17 00:00:00 2001 From: Jeremy Stanley Date: Tue, 23 Apr 2013 17:39:49 +0000 Subject: [PATCH] Use byte type for passwords hash encoding * lib/mudpy/password.py: Raw hash values are manipulated as bytes for Py3K compatibility. --- lib/mudpy/password.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/mudpy/password.py b/lib/mudpy/password.py index 56bdbfe..68e1a5f 100644 --- a/lib/mudpy/password.py +++ b/lib/mudpy/password.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Password hashing functions and constants for the mudpy engine.""" -# Copyright (c) 2004-2012 Jeremy Stanley . Permission +# Copyright (c) 2004-2013 Jeremy Stanley . Permission # to use, copy, modify, and distribute this software is granted under # terms provided in the LICENSE file distributed with this software. @@ -21,12 +21,10 @@ def _pack_bytes(numbers): between 0 and 255 into a packed sequence akin to a C-style string. """ import struct - # this will need to be declared as b"" during 2to3 migration - packed = "" + packed = b"" for number in numbers: number = int(number) assert 0 <= number <= 255 - # need to use b"B" during 2to3 migration packed += struct.pack("B", number) return packed @@ -39,8 +37,8 @@ def _bytes_to_text(byte_sequence): import base64 return base64.b64encode( byte_sequence, - "./".encode("ascii") - ).rstrip("=") + b"./" + ).decode("ascii").rstrip("=") def _generate_salt(salt_len=2): @@ -71,11 +69,10 @@ def upgrade_legacy_hash(legacy_hash, salt, sep="$"): import re assert re.match("^[0-9a-f]{32}$", legacy_hash), "Not a valid MD5 hexdigest" - # this needs to be declared as b"" in 2to3 - collapsed = "" + collapsed = b"" for i in range(16): # this needs to become a byte() call in 2to3 - collapsed += chr(int(legacy_hash[2 * i:2 * i + 2], 16)) + collapsed += bytes(legacy_hash[2 * i:2 * i + 2].decode("ascii")) return "%s%s%s%s%s%s%s%s" % ( sep, MD5, @@ -164,11 +161,17 @@ def create( # iterate the hashing algorithm over its own digest the specified # number of times for i in range(2 ** rounds): - hashed = algorithms[algorithm](hashed).digest() + hashed = algorithms[algorithm](hashed.encode("utf-8")).digest() + # TODO: remove this exception trap after the switch to py2k + try: + hashed = "".join(format(x, "02x") for x in bytes(hashed)) + except ValueError: + hashed = "".join(format(ord(x), "02x") for x in bytes(hashed)) # concatenate the output fields, coercing into text form as needed return "%s%s%s%s%s%s%s%s" % ( - sep, algorithm, sep, rounds, sep, salt, sep, _bytes_to_text(hashed) + sep, algorithm, sep, rounds, sep, salt, sep, + _bytes_to_text(hashed.encode("ascii")) ) -- 2.11.0