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

Fix handling of non-ASCII passwords #1062

Merged
merged 1 commit into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions asyncpg/protocol/coreproto.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ cdef class CoreProtocol:
WriteBuffer msg

msg = WriteBuffer.new_message(b'p')
msg.write_bytestring(self.password.encode('ascii'))
msg.write_bytestring(self.password.encode(self.encoding))
msg.end_message()

return msg
Expand All @@ -646,11 +646,11 @@ cdef class CoreProtocol:
msg = WriteBuffer.new_message(b'p')

# 'md5' + md5(md5(password + username) + salt))
userpass = ((self.password or '') + (self.user or '')).encode('ascii')
hash = hashlib.md5(hashlib.md5(userpass).hexdigest().\
encode('ascii') + salt).hexdigest().encode('ascii')
userpass = (self.password or '') + (self.user or '')
md5_1 = hashlib.md5(userpass.encode(self.encoding)).hexdigest()
md5_2 = hashlib.md5(md5_1.encode('ascii') + salt).hexdigest()

msg.write_bytestring(b'md5' + hash)
msg.write_bytestring(b'md5' + md5_2.encode('ascii'))
msg.end_message()

return msg
Expand Down
27 changes: 15 additions & 12 deletions tests/test_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ def test_server_version_02(self):
self.assertEqual(expected, result)


CORRECT_PASSWORD = 'correct\u1680password'


class TestAuthentication(tb.ConnectedTestCase):
def setUp(self):
super().setUp()
Expand All @@ -127,9 +130,9 @@ def setUp(self):
methods = [
('trust', None),
('reject', None),
('scram-sha-256', 'correctpassword'),
('md5', 'correctpassword'),
('password', 'correctpassword'),
('scram-sha-256', CORRECT_PASSWORD),
('md5', CORRECT_PASSWORD),
('password', CORRECT_PASSWORD),
]

self.cluster.reset_hba()
Expand All @@ -151,7 +154,7 @@ def setUp(self):
create_script.append(
'CREATE ROLE {}_user WITH LOGIN{};'.format(
username,
' PASSWORD {!r}'.format(password) if password else ''
f' PASSWORD E{(password or "")!r}'
)
)

Expand Down Expand Up @@ -241,7 +244,7 @@ async def test_auth_reject(self):
async def test_auth_password_cleartext(self):
conn = await self.connect(
user='password_user',
password='correctpassword')
password=CORRECT_PASSWORD)
await conn.close()

with self.assertRaisesRegex(
Expand All @@ -253,7 +256,7 @@ async def test_auth_password_cleartext(self):

async def test_auth_password_cleartext_callable(self):
def get_correctpassword():
return 'correctpassword'
return CORRECT_PASSWORD

def get_wrongpassword():
return 'wrongpassword'
Expand All @@ -272,7 +275,7 @@ def get_wrongpassword():

async def test_auth_password_cleartext_callable_coroutine(self):
async def get_correctpassword():
return 'correctpassword'
return CORRECT_PASSWORD

async def get_wrongpassword():
return 'wrongpassword'
Expand All @@ -291,7 +294,7 @@ async def get_wrongpassword():

async def test_auth_password_cleartext_callable_awaitable(self):
async def get_correctpassword():
return 'correctpassword'
return CORRECT_PASSWORD

async def get_wrongpassword():
return 'wrongpassword'
Expand All @@ -310,7 +313,7 @@ async def get_wrongpassword():

async def test_auth_password_md5(self):
conn = await self.connect(
user='md5_user', password='correctpassword')
user='md5_user', password=CORRECT_PASSWORD)
await conn.close()

with self.assertRaisesRegex(
Expand All @@ -325,7 +328,7 @@ async def test_auth_password_scram_sha_256(self):
return

conn = await self.connect(
user='scram_sha_256_user', password='correctpassword')
user='scram_sha_256_user', password=CORRECT_PASSWORD)
await conn.close()

with self.assertRaisesRegex(
Expand Down Expand Up @@ -362,7 +365,7 @@ async def test_auth_password_scram_sha_256(self):
await conn.close()

alter_password = \
"ALTER ROLE scram_sha_256_user PASSWORD 'correctpassword';"
f"ALTER ROLE scram_sha_256_user PASSWORD E{CORRECT_PASSWORD!r};"
await self.con.execute(alter_password)
await self.con.execute("SET password_encryption = 'md5';")

Expand All @@ -372,7 +375,7 @@ async def test_auth_md5_unsupported(self, _):
exceptions.InternalClientError,
".*no md5.*",
):
await self.connect(user='md5_user', password='correctpassword')
await self.connect(user='md5_user', password=CORRECT_PASSWORD)


class TestConnectParams(tb.TestCase):
Expand Down