Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asyngpg swallows error related to FIPS and MD5 #861

Closed
eseglem opened this issue Dec 8, 2021 · 0 comments · Fixed by #862
Closed

asyngpg swallows error related to FIPS and MD5 #861

eseglem opened this issue Dec 8, 2021 · 0 comments · Fixed by #862

Comments

@eseglem
Copy link

eseglem commented Dec 8, 2021

  • asyncpg version: 0.23.0 - 0.25.0
  • PostgreSQL version: 13.3, and 9.6.22 for additional testing
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
    the issue with a local PostgreSQL install?
    : Using RDS primarily. Issue happens anywhere.
  • Python version: 3.8.11, also reproduced in 3.6.8
  • Platform: CentOS 7
  • Do you use pgbouncer?: No
  • Did you install asyncpg with pip?: Yes
  • If you built asyncpg locally, which version of Cython did you use?: n/a
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : Yes

With FIPS mode enabled, md5 is not allowed. And if asyncpg attempts to connect to a DB using md5 authentication if produced a timeout error. Obviously there is an issue connection with a db configured to use md5, and I was able to connect once it was updated to use SCRAM instead, but it took forever to figure out what the issue was due to how the error is handled.

Simple script:

import asyncio
import asyncpg

async def main():
    print("start")
    c = await asyncpg.connect("postgresql://...")
    print("end")

asyncio.get_event_loop().run_until_complete(main())

In 0.25.0 it says 'start' then hangs for a minute and then produces this stack trace:

Traceback (most recent call last):
  File "test_async.py", line 9, in <module>
    asyncio.get_event_loop().run_until_complete(main())
  File "/opt/rh/rh-python38/root/lib64/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "test_async.py", line 6, in main
    c = await asyncpg.connect("postgresql://...")
  File "/home/maintuser/venv/lib64/python3.8/site-packages/asyncpg/connection.py", line 2085, in connect
    return await connect_utils._connect(
  File "/home/maintuser/venv/lib64/python3.8/site-packages/asyncpg/connect_utils.py", line 895, in _connect
    raise last_error
  File "/home/maintuser/venv/lib64/python3.8/site-packages/asyncpg/connect_utils.py", line 881, in _connect
    return await _connect_addr(
  File "/home/maintuser/venv/lib64/python3.8/site-packages/asyncpg/connect_utils.py", line 781, in _connect_addr
    return await __connect_addr(params, timeout, True, *args)
  File "/home/maintuser/venv/lib64/python3.8/site-packages/asyncpg/connect_utils.py", line 831, in __connect_addr
    await compat.wait_for(connected, timeout=timeout)
  File "/home/maintuser/venv/lib64/python3.8/site-packages/asyncpg/compat.py", line 66, in wait_for
    return await asyncio.wait_for(fut, timeout)
  File "/opt/rh/rh-python38/root/lib64/python3.8/asyncio/tasks.py", line 501, in wait_for
    raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError

The use of md5 is https://github.com/MagicStack/asyncpg/blob/master/asyncpg/protocol/coreproto.pyx#L637 unfortunately I don't know where that is getting wrapped up and ending up a timeout.

For reference this is the error you get if you try to use hashlib.md5 on a FIPS enabled machine:

$ python
Python 3.8.11 (default, Sep  1 2021, 12:33:46)
[GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> hashlib.md5()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for fips

I would expect that ValueError, or something along those lines, should be making it back to me, but somehow it gets caught in a loop inside until it hits the timeout. I am guessing there is an an except in there is catching too much, but without being familiar with the codebase I haven't found it yet.

elprans added a commit that referenced this issue Dec 8, 2021
When server sends us an authentication request message and we fail to
process it, we must terminate the connection and propagate the exception
immediately.  Currently asyncpg will just timeout waiting for
`ReadyForQuery` from the server, which will never arrive.

Fixes: #861
elprans added a commit that referenced this issue Mar 27, 2022
…#862)

When server sends us an authentication request message and we fail to
process it, we must terminate the connection and propagate the exception
immediately.  Currently asyncpg will just timeout waiting for
`ReadyForQuery` from the server, which will never arrive.

Fixes: #861
rohitsanj pushed a commit to noteable-io/asyncpg-crdb-noteable that referenced this issue May 8, 2023
…MagicStack#862)

When server sends us an authentication request message and we fail to
process it, we must terminate the connection and propagate the exception
immediately.  Currently asyncpg will just timeout waiting for
`ReadyForQuery` from the server, which will never arrive.

Fixes: MagicStack#861
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant