Opened 2 years ago

Last modified 3 weeks ago

#5549 new defect

python3 password check does not work

Reported by: Marco Strigl Owned by:
Priority: major Milestone:
Component: programming Keywords:
Cc: Parent Tickets:

Description

I have a installation of mediagoblin on openSUSE Tumbleweed.
I run python3.

Everything runs fine until I logout. I am not able to login, because the stored_hash seems not to be encoded.

If I print the stored_hash I get:
b'$2b$12$i2E5Kg.Ro82c6WqNgrrtPuURbG0cSyMHjN/Aoeam0/5flHuY3CQCa'

In python3-bcrypto the following check raises the error:
if isinstance(password, six.text_type) or isinstance(salt, six.text_type):

And the traceback attached:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/waitress-1.1.0-py3.6.egg/waitress/channel.py", line 338, in service
    task.service()
  File "/usr/lib/python3.6/site-packages/waitress-1.1.0-py3.6.egg/waitress/task.py", line 169, in service
    self.execute()
  File "/usr/lib/python3.6/site-packages/waitress-1.1.0-py3.6.egg/waitress/task.py", line 399, in execute
    app_iter = self.channel.server.application(env, start_response)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/app.py", line 342, in __call__
    return self.call_backend(environ, start_response)
  File "/srv/mediagoblin.example.org/mediagoblin/lib/python3.6/site-packages/Werkzeug-0.12.2-py3.6.egg/werkzeug/wsgi.py", line 600, in __call__
    return self.app(environ, start_response)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/app.py", line 276, in call_backend
    return self._finish_call_backend(request, environ, start_response)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/app.py", line 318, in _finish_call_backend
    response = controller(request)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/decorators.py", line 367, in wrapper
    return controller(request, *args, **kwargs)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/auth/views.py", line 93, in login
    login_form.password.data)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/auth/tools.py", line 167, in check_login_simple
    if not auth.check_password(password, user.pw_hash):
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/auth/__init__.py", line 43, in check_password
    raw_pass, stored_hash, extra_salt)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/tools/pluginapi.py", line 308, in hook_handle
    result = callable(*args, **kwargs)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/plugins/basic_auth/__init__.py", line 92, in check_password
    stored_hash, extra_salt)
  File "/srv/mediagoblin.example.org/mediagoblin/mediagoblin/plugins/basic_auth/tools.py", line 45, in bcrypt_check_password
    hashed_pass = bcrypt.hashpw(raw_pass.encode('utf-8'), stored_hash)
  File "/usr/lib64/python3.6/site-packages/bcrypt/__init__.py", line 65, in hashpw
    raise TypeError("Unicode-objects must be encoded before hashing")
TypeError: Unicode-objects must be encoded before hashing

Subtickets

Attachments (1)

fix_hash (551 bytes) - added by Marco Strigl 2 years ago.

Download all attachments as: .zip

Change History (5)

comment:1 Changed 2 years ago by Marco Strigl

I managed to fix it with this patch:

*** tools.py    2017-11-13 14:29:18.255113996 +0100
--- tools.py_fix        2017-11-13 14:30:17.505473997 +0100
***************
*** 68,75 ****
      if extra_salt:
          raw_pass = u"%s:%s" % (extra_salt, raw_pass)
  
!     return six.text_type(
!         bcrypt.hashpw(raw_pass.encode('utf-8'), bcrypt.gensalt()))
  
  
  def fake_login_attempt():
--- 68,74 ----
      if extra_salt:
          raw_pass = u"%s:%s" % (extra_salt, raw_pass)
  
!     return bcrypt.hashpw(raw_pass.encode('utf-8'), bcrypt.gensalt())
  
  
  def fake_login_attempt():

But I am not sure that this breaks nothing for python2.

Changed 2 years ago by Marco Strigl

Attachment: fix_hash added

comment:2 Changed 2 years ago by Marco Strigl

I tested master with python2.7 and I get the same error (without the applied patch):

File "/usr/lib64/python2.7/site-packages/bcrypt/__init__.py", line 62, in hashpw
    raise TypeError("Unicode-objects must be encoded before hashing")
TypeError: Unicode-objects must be encoded before hashing

I applied above patch. Still no success. With the following code in plugins/basic_auth/tools.py it works (together with the patch above):

if isinstance(stored_hash, six.text_type):
        stored_hash = stored_hash.encode('utf-8')

comment:3 Changed 2 years ago by Marco Strigl

I found the underlying problem:
I am not using a virtualenv and therefore installed the dependencies myself.

I accidentally installed bcrypt instead of py-bcrypt. And this cause the problem.
My patch allows bcrypt and py-bcrypt compatibility.

Perhaps bycrypt should be used anyway, because the last change to py-bcrypt was in 2013-08-25.

comment:4 Changed 3 weeks ago by Ben Sturmfels

Thanks Marco, glad you were able to figure it out. Sounds like it could be worth switching from py-bcrypt to bcrypt. On the other hand though, old software isn't necessarily bad, especially if it's something specific like a hashing library.

Would you mind attaching a patch file as explained here:
https://wiki.mediagoblin.org/Git_workflow

eg. git format-patch --stdout <remote>/master > issue_<number>.patch

Note: See TracTickets for help on using tickets.