Port hash_password to Python 3 (#4161)

* port hash_password

* changelog
pull/4163/head
Amber Brown 2018-11-08 04:57:28 +11:00 committed by GitHub
parent b3708830b8
commit 264cb14402
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 8 deletions

1
changelog.d/4161.bugfix Normal file
View File

@ -0,0 +1 @@
The hash_password script now works on Python 3.

View File

@ -3,13 +3,15 @@
import argparse import argparse
import getpass import getpass
import sys import sys
import unicodedata
import bcrypt import bcrypt
import yaml import yaml
bcrypt_rounds=12 bcrypt_rounds = 12
password_pepper = "" password_pepper = ""
def prompt_for_pass(): def prompt_for_pass():
password = getpass.getpass("Password: ") password = getpass.getpass("Password: ")
@ -23,19 +25,27 @@ def prompt_for_pass():
return password return password
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Calculate the hash of a new password, so that passwords" description=(
" can be reset") "Calculate the hash of a new password, so that passwords can be reset"
)
)
parser.add_argument( parser.add_argument(
"-p", "--password", "-p",
"--password",
default=None, default=None,
help="New password for user. Will prompt if omitted.", help="New password for user. Will prompt if omitted.",
) )
parser.add_argument( parser.add_argument(
"-c", "--config", "-c",
"--config",
type=argparse.FileType('r'), type=argparse.FileType('r'),
help="Path to server config file. Used to read in bcrypt_rounds and password_pepper.", help=(
"Path to server config file. "
"Used to read in bcrypt_rounds and password_pepper."
),
) )
args = parser.parse_args() args = parser.parse_args()
@ -49,4 +59,21 @@ if __name__ == "__main__":
if not password: if not password:
password = prompt_for_pass() password = prompt_for_pass()
print bcrypt.hashpw(password + password_pepper, bcrypt.gensalt(bcrypt_rounds)) # On Python 2, make sure we decode it to Unicode before we normalise it
if isinstance(password, bytes):
try:
password = password.decode(sys.stdin.encoding)
except UnicodeDecodeError:
print(
"ERROR! Your password is not decodable using your terminal encoding (%s)."
% (sys.stdin.encoding,)
)
pw = unicodedata.normalize("NFKC", password)
hashed = bcrypt.hashpw(
pw.encode('utf8') + password_pepper.encode("utf8"),
bcrypt.gensalt(bcrypt_rounds),
).decode('ascii')
print(hashed)

View File

@ -122,7 +122,7 @@ skip_install = True
basepython = python3.6 basepython = python3.6
deps = deps =
flake8 flake8
commands = /bin/sh -c "flake8 synapse tests scripts scripts-dev scripts/register_new_matrix_user scripts/synapse_port_db synctl {env:PEP8SUFFIX:}" commands = /bin/sh -c "flake8 synapse tests scripts scripts-dev scripts/hash_password scripts/register_new_matrix_user scripts/synapse_port_db synctl {env:PEP8SUFFIX:}"
[testenv:check_isort] [testenv:check_isort]
skip_install = True skip_install = True