Skip to content

Commit 8caa4b5

Browse files
committed
Fix handling of non-ASCII passwords
Fixes: #1018
1 parent 511aeb2 commit 8caa4b5

File tree

2 files changed

+20
-17
lines changed

2 files changed

+20
-17
lines changed

Diff for: asyncpg/protocol/coreproto.pyx

+5-5
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ cdef class CoreProtocol:
634634
WriteBuffer msg
635635

636636
msg = WriteBuffer.new_message(b'p')
637-
msg.write_bytestring(self.password.encode('ascii'))
637+
msg.write_bytestring(self.password.encode(self.encoding))
638638
msg.end_message()
639639

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

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

653-
msg.write_bytestring(b'md5' + hash)
653+
msg.write_bytestring(b'md5' + md5_2.encode('ascii'))
654654
msg.end_message()
655655

656656
return msg

Diff for: tests/test_connect.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ def test_server_version_02(self):
117117
self.assertEqual(expected, result)
118118

119119

120+
CORRECT_PASSWORD = 'correct\u1680password'
121+
122+
120123
class TestAuthentication(tb.ConnectedTestCase):
121124
def setUp(self):
122125
super().setUp()
@@ -127,9 +130,9 @@ def setUp(self):
127130
methods = [
128131
('trust', None),
129132
('reject', None),
130-
('scram-sha-256', 'correctpassword'),
131-
('md5', 'correctpassword'),
132-
('password', 'correctpassword'),
133+
('scram-sha-256', CORRECT_PASSWORD),
134+
('md5', CORRECT_PASSWORD),
135+
('password', CORRECT_PASSWORD),
133136
]
134137

135138
self.cluster.reset_hba()
@@ -151,7 +154,7 @@ def setUp(self):
151154
create_script.append(
152155
'CREATE ROLE {}_user WITH LOGIN{};'.format(
153156
username,
154-
' PASSWORD {!r}'.format(password) if password else ''
157+
f' PASSWORD E{(password or "")!r}'
155158
)
156159
)
157160

@@ -241,7 +244,7 @@ async def test_auth_reject(self):
241244
async def test_auth_password_cleartext(self):
242245
conn = await self.connect(
243246
user='password_user',
244-
password='correctpassword')
247+
password=CORRECT_PASSWORD)
245248
await conn.close()
246249

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

254257
async def test_auth_password_cleartext_callable(self):
255258
def get_correctpassword():
256-
return 'correctpassword'
259+
return CORRECT_PASSWORD
257260

258261
def get_wrongpassword():
259262
return 'wrongpassword'
@@ -272,7 +275,7 @@ def get_wrongpassword():
272275

273276
async def test_auth_password_cleartext_callable_coroutine(self):
274277
async def get_correctpassword():
275-
return 'correctpassword'
278+
return CORRECT_PASSWORD
276279

277280
async def get_wrongpassword():
278281
return 'wrongpassword'
@@ -291,7 +294,7 @@ async def get_wrongpassword():
291294

292295
async def test_auth_password_cleartext_callable_awaitable(self):
293296
async def get_correctpassword():
294-
return 'correctpassword'
297+
return CORRECT_PASSWORD
295298

296299
async def get_wrongpassword():
297300
return 'wrongpassword'
@@ -310,7 +313,7 @@ async def get_wrongpassword():
310313

311314
async def test_auth_password_md5(self):
312315
conn = await self.connect(
313-
user='md5_user', password='correctpassword')
316+
user='md5_user', password=CORRECT_PASSWORD)
314317
await conn.close()
315318

316319
with self.assertRaisesRegex(
@@ -325,7 +328,7 @@ async def test_auth_password_scram_sha_256(self):
325328
return
326329

327330
conn = await self.connect(
328-
user='scram_sha_256_user', password='correctpassword')
331+
user='scram_sha_256_user', password=CORRECT_PASSWORD)
329332
await conn.close()
330333

331334
with self.assertRaisesRegex(
@@ -362,7 +365,7 @@ async def test_auth_password_scram_sha_256(self):
362365
await conn.close()
363366

364367
alter_password = \
365-
"ALTER ROLE scram_sha_256_user PASSWORD 'correctpassword';"
368+
f"ALTER ROLE scram_sha_256_user PASSWORD E{CORRECT_PASSWORD!r};"
366369
await self.con.execute(alter_password)
367370
await self.con.execute("SET password_encryption = 'md5';")
368371

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

377380

378381
class TestConnectParams(tb.TestCase):

0 commit comments

Comments
 (0)