Remove UTF-8 encoding header from Python files
[mudpy.git] / lib / mudpy / password.py
index bad5579..2e37b91 100644 (file)
@@ -1,10 +1,16 @@
-# -*- coding: utf-8 -*-
 """Password hashing functions and constants for the mudpy engine."""
 
 """Password hashing functions and constants for the mudpy engine."""
 
-# Copyright (c) 2004-2013 Jeremy Stanley <fungi@yuggoth.org>. Permission
+# Copyright (c) 2004-2015 Jeremy Stanley <fungi@yuggoth.org>. Permission
 # to use, copy, modify, and distribute this software is granted under
 # terms provided in the LICENSE file distributed with this software.
 
 # to use, copy, modify, and distribute this software is granted under
 # terms provided in the LICENSE file distributed with this software.
 
+import base64
+import hashlib
+import math
+import random
+import re
+import struct
+
 # convenience constants for indexing the supported hashing algorithms,
 # guaranteed a stable part of the interface
 MD5 = 0  # hashlib.md5
 # convenience constants for indexing the supported hashing algorithms,
 # guaranteed a stable part of the interface
 MD5 = 0  # hashlib.md5
@@ -16,11 +22,11 @@ SHA512 = 5  # hashlib.sha512
 
 
 def _pack_bytes(numbers):
 
 
 def _pack_bytes(numbers):
-    """
+    """Make a packed byte sequence:
+
     This is a wrapper around struct.pack, used to turn a list of integers
     between 0 and 255 into a packed sequence akin to a C-style string.
     """
     This is a wrapper around struct.pack, used to turn a list of integers
     between 0 and 255 into a packed sequence akin to a C-style string.
     """
-    import struct
     packed = b""
     for number in numbers:
         number = int(number)
     packed = b""
     for number in numbers:
         number = int(number)
@@ -30,11 +36,11 @@ def _pack_bytes(numbers):
 
 
 def _bytes_to_text(byte_sequence):
 
 
 def _bytes_to_text(byte_sequence):
-    """
+    """Generate printable representation of 8-bit data:
+
     This is a wrapper around base64.b64encode with preferences
     appropriate for encoding Unix-style passwd hash strings.
     """
     This is a wrapper around base64.b64encode with preferences
     appropriate for encoding Unix-style passwd hash strings.
     """
-    import base64
     return base64.b64encode(
         byte_sequence,
         b"./"
     return base64.b64encode(
         byte_sequence,
         b"./"
@@ -42,7 +48,8 @@ def _bytes_to_text(byte_sequence):
 
 
 def _generate_salt(salt_len=2):
 
 
 def _generate_salt(salt_len=2):
-    """
+    """Generate salt for a password hash:
+
     This simply generates a sequence of pseudo-random characters (with
     6-bits of effective entropy per character). Since it relies on base64
     encoding (which operates on 6-bit chunks of data), we only generate
     This simply generates a sequence of pseudo-random characters (with
     6-bits of effective entropy per character). Since it relies on base64
     encoding (which operates on 6-bit chunks of data), we only generate
@@ -50,8 +57,6 @@ def _generate_salt(salt_len=2):
     need and discard any excess characters over the specified length.
     This ensures full distribution over each character of the salt.
     """
     need and discard any excess characters over the specified length.
     This ensures full distribution over each character of the salt.
     """
-    import math
-    import random
     salt = []
     for i in range(int(math.ceil(salt_len * 0.75))):
         salt.append(random.randint(0, 255))
     salt = []
     for i in range(int(math.ceil(salt_len * 0.75))):
         salt.append(random.randint(0, 255))
@@ -59,14 +64,14 @@ def _generate_salt(salt_len=2):
 
 
 def upgrade_legacy_hash(legacy_hash, salt, sep="$"):
 
 
 def upgrade_legacy_hash(legacy_hash, salt, sep="$"):
-    """
+    """Upgrade an older password hash:
+
     This utility function is meant to provide a migration path for users
     of mudpy's legacy account-name-salted MD5 hexdigest password hashes.
     By passing the old passhash (as legacy_hash) and name (as salt)
     facets to this function, a conforming new-style password hash will be
     returned.
     """
     This utility function is meant to provide a migration path for users
     of mudpy's legacy account-name-salted MD5 hexdigest password hashes.
     By passing the old passhash (as legacy_hash) and name (as salt)
     facets to this function, a conforming new-style password hash will be
     returned.
     """
-    import re
     assert re.match("^[0-9a-f]{32}$",
                     legacy_hash), "Not a valid MD5 hexdigest"
     collapsed = b""
     assert re.match("^[0-9a-f]{32}$",
                     legacy_hash), "Not a valid MD5 hexdigest"
     collapsed = b""
@@ -93,7 +98,8 @@ def create(
     salt_len=2,
     sep="$"
 ):
     salt_len=2,
     sep="$"
 ):
-    """
+    """Generate a password hash:
+
     The meat of the module, this function takes a provided password and
     generates a Unix-like passwd hash suitable for storage in portable,
     text-based data files. The password is prepended with a salt (which
     The meat of the module, this function takes a provided password and
     generates a Unix-like passwd hash suitable for storage in portable,
     text-based data files. The password is prepended with a salt (which
@@ -126,7 +132,6 @@ def create(
 
        create(password, algorithm=SHA256, rounds=12, salt_len=16)
     """
 
        create(password, algorithm=SHA256, rounds=12, salt_len=16)
     """
-    import hashlib
 
     # if a specific salt wasn't specified, we need to generate one
     if not salt:
 
     # if a specific salt wasn't specified, we need to generate one
     if not salt:
@@ -162,11 +167,7 @@ def create(
     # number of times
     for i in range(2 ** rounds):
         hashed = algorithms[algorithm](hashed.encode("utf-8")).digest()
     # number of times
     for i in range(2 ** rounds):
         hashed = algorithms[algorithm](hashed.encode("utf-8")).digest()
-        # TODO: remove this check after the switch to py3k
-        try:
-            hashed = "".join(format(x, "02x") for x in bytes(hashed))
-        except ValueError:
-            hashed = "".join(format(ord(x), "02x") for x in bytes(hashed))
+        hashed = "".join(format(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" % (
 
     # concatenate the output fields, coercing into text form as needed
     return "%s%s%s%s%s%s%s%s" % (
@@ -176,14 +177,14 @@ def create(
 
 
 def verify(password, encoded_hash):
 
 
 def verify(password, encoded_hash):
-    """
+    """Verify a password:
+
     This simple function requires a text password and a mudpy-format
     password hash (as generated by the create function). It returns True
     if the password, hashed with the parameters from the encoded_hash,
     comes out the same as the encoded_hash.
     """
     sep = encoded_hash[0]
     This simple function requires a text password and a mudpy-format
     password hash (as generated by the create function). It returns True
     if the password, hashed with the parameters from the encoded_hash,
     comes out the same as the encoded_hash.
     """
     sep = encoded_hash[0]
-    import mudpy.misc
     algorithm, rounds, salt, hashed = encoded_hash.split(sep)[1:]
     if encoded_hash == create(
        password=password,
     algorithm, rounds, salt, hashed = encoded_hash.split(sep)[1:]
     if encoded_hash == create(
        password=password,