Bug 245906

Summary: www/radicale2: Fails to run: bcrypt: no backends available under Python 3.x
Product: Ports & Packages Reporter: Alexander Sieg <ports>
Component: Individual Port(s)Assignee: Bernhard Froehlich <decke>
Status: Closed Overcome By Events    
Severity: Affects Many People CC: andrew, decke, koobs
Priority: --- Keywords: needs-qa
Version: LatestFlags: bugzilla: maintainer-feedback? (decke)
koobs: merge-quarterly?
Hardware: Any   
OS: Any   
Attachments:
Description Flags
passlib bcrypt on Python 3 bugfix koobs: maintainer-approval+

Description Alexander Sieg 2020-04-25 10:50:55 UTC
When trying to start radicale2 with `htpasswd_encryption = bcrypt` the following error is printed.

# service radicale start
Starting radicale.
[800a39000] ERROR: An exception occurred during server startup: bcrypt: no backends available -- recommend you install one (e.g. 'pip install bcrypt')
/usr/local/etc/rc.d/radicale: WARNING: failed to start radicale

# pkg query %n
gettext-runtime
indexinfo
libffi
pkg
py37-bcrypt
py37-dateutil
py37-passlib
py37-radicale2
py37-setuptools
py37-six
py37-vobject
python37
readline
Comment 1 Bernhard Froehlich freebsd_committer freebsd_triage 2020-04-25 20:37:27 UTC
Works fine for me. Is there anything special with your environment?

You could try to reinstall all packages and make sure to start with a fresh radicale storage directory.
Comment 2 Alexander Sieg 2020-04-26 06:35:59 UTC
This is a FreeBSD 12.1-RELEASE-p2 jail with the radicale installed via pkg.

I reinstalled all packages with `pkg upgrade -f` and created a new storage directory, but the error continues to exists.

# pkg query "%n %v"

gettext-runtime 0.20.1
indexinfo 0.3.1
libffi 3.2.1_3
pkg 1.13.2
py37-bcrypt 3.1.7
py37-dateutil 2.8.0
py37-passlib 1.7.2
py37-radicale2 2.1.11
py37-setuptools 44.0.0
py37-six 1.14.0
py37-vobject 0.9.6.1
python37 3.7.7
readline 8.0.4
Comment 3 Bernhard Froehlich freebsd_committer freebsd_triage 2020-05-04 20:54:43 UTC
I can reproduce it now. It only happens if you have an htpasswd_filename with proper bcrypt hashes in it.
Comment 4 Bernhard Froehlich freebsd_committer freebsd_triage 2020-05-04 21:06:37 UTC
This is the stacktrace that I got:

root@tester:/usr/local/etc/radicale2 # /usr/local/bin/radicale -C /usr/local/etc/radicale2/config
[800a3a000] INFO: Starting Radicale
[800a3a000] INFO: Authentication type is 'htpasswd'
[800a3a000] ERROR: An exception occurred during server startup: bcrypt: no backends available -- recommend you install one (e.g. 'pip install bcrypt')
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/radicale/__main__.py", line 138, in run
    serve(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/__main__.py", line 229, in serve
    application = Application(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/__init__.py", line 251, in __init__
    self.Auth = auth.load(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/auth.py", line 85, in load
    return class_(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/auth.py", line 174, in __init__
    bcrypt.encrypt("test-bcrypt-backend")
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/decor.py", line 191, in wrapper
    return func(*args, **kwds)
  File "/usr/local/lib/python3.7/site-packages/passlib/ifc.py", line 154, in encrypt
    return cls.hash(*args, **kwds)
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/handlers.py", line 780, in hash
    self.checksum = self._calc_checksum(secret)
  File "/usr/local/lib/python3.7/site-packages/passlib/handlers/bcrypt.py", line 533, in _calc_checksum
    self._stub_requires_backend()
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/handlers.py", line 2255, in _stub_requires_backend
    cls.set_backend()
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/handlers.py", line 2177, in set_backend
    raise default_error
passlib.exc.MissingBackendError: bcrypt: no backends available -- recommend you install one (e.g. 'pip install bcrypt')


looks a lot like an issue in passlib to me.
Comment 5 Bernhard Froehlich freebsd_committer freebsd_triage 2020-05-04 21:13:42 UTC
For reference my user entry (test/test) is:
test:$2y$10$dytFIe/wlgobtDZeZbBOLuNjvVglE2bh6JMaleSBRERzj9N5AAfHW
Comment 6 Kubilay Kocak freebsd_committer freebsd_triage 2020-05-24 09:33:55 UTC
The error indeed appears to come from passlib.

I investigated the following:

1) radicale2 (2.1.12)'s dependencies [1]:

    extras_require={
        "test": tests_require,
        "md5": "passlib",
        "bcrypt": "passlib[bcrypt]"}, <--------

Apart from the unnecessary '>=1.6.5' version-spec in the radicale2 port RUN_DEPENDS lines, this is fine, and the current security/py-passlib version satisfies it.

2) security/py-passlib dependencies

The port doesn't explicitly depend on, or have OPTIONS for any specific backends, leaving it up to the user to install whatever backends they'd like.

The upstream setup.py defines the following for bcrypt support:

    # recommended library for bcrypt backend (if not present on host)
    "bcrypt": "bcrypt>=3.1.0",

This is satisfied by the security/py-bcrypt port (current version: 3.1.7)

3) py-passlib port test suite, looking for bcrypt issues, which passes:

   Ran 3291 tests in 310.033s OK (skipped=1355)


[1] https://github.com/Kozea/Radicale/blob/2.1.12/setup.py
Comment 7 Kubilay Kocak freebsd_committer freebsd_triage 2020-05-24 09:43:29 UTC
From the BUGFIXES section in the next 1.7 release notes [1]

bcrypt: Under python 3, OS native backend wasn’t being detected on BSD platforms. This was due to a few internal issues in feature-detection code, which have been fixed.

This description is too similar to the issue reported here to be a coincidence, so I'll backport the patch and attach it here for testing/confirmation.

The tests just passed with that patch applied: Ran 3291 tests in 281.933s OK (skipped=1355)

[1] https://passlib.readthedocs.io/en/stable/history/1.7.html#bugfixes
Comment 8 Kubilay Kocak freebsd_committer freebsd_triage 2020-05-24 10:13:54 UTC
Created attachment 214804 [details]
passlib bcrypt on Python 3 bugfix
Comment 9 Kubilay Kocak freebsd_committer freebsd_triage 2020-05-24 10:14:48 UTC
@Alexander/Bernhard Can you test attachment 214804 [details] and confirm that it resolves the issue please
Comment 10 Bernhard Froehlich freebsd_committer freebsd_triage 2020-05-26 07:10:11 UTC
I've tried the patch now and it does not seem to help. Test was done with the current radicale 2.1.12 and passlib recompiled with the patch.

py37-bcrypt-3.1.7
py37-passlib-1.7.2_1
py37-radicale2-2.1.12

Output was exactly the same:

# /usr/local/bin/radicale -C /usr/local/etc/radicale2/config
[800a3a000] INFO: Starting Radicale
[800a3a000] INFO: Authentication type is 'htpasswd'
[800a3a000] ERROR: An exception occurred during server startup: bcrypt: no backends available -- recommend you install one (e.g. 'pip install bcrypt')
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/radicale/__main__.py", line 138, in run
    serve(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/__main__.py", line 229, in serve
    application = Application(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/__init__.py", line 251, in __init__
    self.Auth = auth.load(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/auth.py", line 85, in load
    return class_(configuration, logger)
  File "/usr/local/lib/python3.7/site-packages/radicale/auth.py", line 174, in __init__
    bcrypt.encrypt("test-bcrypt-backend")
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/decor.py", line 191, in wrapper
    return func(*args, **kwds)
  File "/usr/local/lib/python3.7/site-packages/passlib/ifc.py", line 154, in encrypt
    return cls.hash(*args, **kwds)
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/handlers.py", line 780, in hash
    self.checksum = self._calc_checksum(secret)
  File "/usr/local/lib/python3.7/site-packages/passlib/handlers/bcrypt.py", line 533, in _calc_checksum
    self._stub_requires_backend()
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/handlers.py", line 2255, in _stub_requires_backend
    cls.set_backend()
  File "/usr/local/lib/python3.7/site-packages/passlib/utils/handlers.py", line 2177, in set_backend
    raise default_error
passlib.exc.MissingBackendError: bcrypt: no backends available -- recommend you install one (e.g. 'pip install bcrypt')
Comment 11 Kubilay Kocak freebsd_committer freebsd_triage 2020-06-10 04:22:04 UTC
(In reply to Bernhard Froehlich from comment #10)

Perhaps its worth asking upstream? I'm surprised the update wasn't/isn't the issue
Comment 12 Bernhard Froehlich freebsd_committer freebsd_triage 2020-06-10 08:23:53 UTC
The radicale port was updated to 3.0.x in the meantime and that is almost a rewrite so I will test if that problem still exists and if the proposed fix works in that combination.
Comment 13 Andrew Fyfe 2020-09-10 13:24:05 UTC
I've just run into this with www/radicale (3.0.3), the problem is security/py-bcrypt, it lists py-cffi and py-six as build dependencies, they should be runtime dependencies.

Installing into a virtual enviroment lists the following installed python modules:

pkg install python3
python3 -m venv /tmp/radicale-test
/tmp/radicale-test/bin/python -m pip install radicale[bcrypt]
/tmp/radicale-test/bin/python -m pip freeze

bcrypt==3.2.0
cffi==1.14.2
defusedxml==0.6.0
passlib==1.7.2
pycparser==2.20
python-dateutil==2.8.1
Radicale==3.0.5
six==1.15.0
vobject==0.9.6.1
Comment 14 Andrew Fyfe 2020-09-10 13:37:35 UTC
(In reply to Andrew Fyfe from comment #13)
I've created a bug report for security/py-bcrypt bug #249235
Comment 15 Bernhard Froehlich freebsd_committer freebsd_triage 2020-09-12 18:33:43 UTC
Thanks a lot!