Skip to content

Commit 89d5bd0

Browse files
authored
Fix handling of non-ASCII passwords (#1062)
Fixes: #1018
1 parent 922fcd1 commit 89d5bd0

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
@@ -642,7 +642,7 @@ cdef class CoreProtocol:
642642
WriteBuffer msg
643643

644644
msg = WriteBuffer.new_message(b'p')
645-
msg.write_bytestring(self.password.encode('ascii'))
645+
msg.write_bytestring(self.password.encode(self.encoding))
646646
msg.end_message()
647647

648648
return msg
@@ -654,11 +654,11 @@ cdef class CoreProtocol:
654654
msg = WriteBuffer.new_message(b'p')
655655

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

661-
msg.write_bytestring(b'md5' + hash)
661+
msg.write_bytestring(b'md5' + md5_2.encode('ascii'))
662662
msg.end_message()
663663

664664
return msg

Diff for: tests/test_connect.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ def test_server_version_02(self):
126126
self.assertEqual(expected, result)
127127

128128

129+
CORRECT_PASSWORD = 'correct\u1680password'
130+
131+
129132
class TestAuthentication(tb.ConnectedTestCase):
130133
def setUp(self):
131134
super().setUp()
@@ -136,9 +139,9 @@ def setUp(self):
136139
methods = [
137140
('trust', None),
138141
('reject', None),
139-
('scram-sha-256', 'correctpassword'),
140-
('md5', 'correctpassword'),
141-
('password', 'correctpassword'),
142+
('scram-sha-256', CORRECT_PASSWORD),
143+
('md5', CORRECT_PASSWORD),
144+
('password', CORRECT_PASSWORD),
142145
]
143146

144147
self.cluster.reset_hba()
@@ -160,7 +163,7 @@ def setUp(self):
160163
create_script.append(
161164
'CREATE ROLE {}_user WITH LOGIN{};'.format(
162165
username,
163-
' PASSWORD {!r}'.format(password) if password else ''
166+
f' PASSWORD E{(password or "")!r}'
164167
)
165168
)
166169

@@ -250,7 +253,7 @@ async def test_auth_reject(self):
250253
async def test_auth_password_cleartext(self):
251254
conn = await self.connect(
252255
user='password_user',
253-
password='correctpassword')
256+
password=CORRECT_PASSWORD)
254257
await conn.close()
255258

256259
with self.assertRaisesRegex(
@@ -262,7 +265,7 @@ async def test_auth_password_cleartext(self):
262265

263266
async def test_auth_password_cleartext_callable(self):
264267
def get_correctpassword():
265-
return 'correctpassword'
268+
return CORRECT_PASSWORD
266269

267270
def get_wrongpassword():
268271
return 'wrongpassword'
@@ -281,7 +284,7 @@ def get_wrongpassword():
281284

282285
async def test_auth_password_cleartext_callable_coroutine(self):
283286
async def get_correctpassword():
284-
return 'correctpassword'
287+
return CORRECT_PASSWORD
285288

286289
async def get_wrongpassword():
287290
return 'wrongpassword'
@@ -300,7 +303,7 @@ async def get_wrongpassword():
300303

301304
async def test_auth_password_cleartext_callable_awaitable(self):
302305
async def get_correctpassword():
303-
return 'correctpassword'
306+
return CORRECT_PASSWORD
304307

305308
async def get_wrongpassword():
306309
return 'wrongpassword'
@@ -319,7 +322,7 @@ async def get_wrongpassword():
319322

320323
async def test_auth_password_md5(self):
321324
conn = await self.connect(
322-
user='md5_user', password='correctpassword')
325+
user='md5_user', password=CORRECT_PASSWORD)
323326
await conn.close()
324327

325328
with self.assertRaisesRegex(
@@ -334,7 +337,7 @@ async def test_auth_password_scram_sha_256(self):
334337
return
335338

336339
conn = await self.connect(
337-
user='scram_sha_256_user', password='correctpassword')
340+
user='scram_sha_256_user', password=CORRECT_PASSWORD)
338341
await conn.close()
339342

340343
with self.assertRaisesRegex(
@@ -371,7 +374,7 @@ async def test_auth_password_scram_sha_256(self):
371374
await conn.close()
372375

373376
alter_password = \
374-
"ALTER ROLE scram_sha_256_user PASSWORD 'correctpassword';"
377+
f"ALTER ROLE scram_sha_256_user PASSWORD E{CORRECT_PASSWORD!r};"
375378
await self.con.execute(alter_password)
376379
await self.con.execute("SET password_encryption = 'md5';")
377380

@@ -381,7 +384,7 @@ async def test_auth_md5_unsupported(self, _):
381384
exceptions.InternalClientError,
382385
".*no md5.*",
383386
):
384-
await self.connect(user='md5_user', password='correctpassword')
387+
await self.connect(user='md5_user', password=CORRECT_PASSWORD)
385388

386389

387390
class TestConnectParams(tb.TestCase):

0 commit comments

Comments
 (0)