isoos / postgresql-dart

Dart PostgreSQL driver: supports extended query format, binary protocol and statement reuse.
https://pub.dev/packages/postgres
BSD 3-Clause "New" or "Revised" License
128 stars 35 forks source link

cannot connect to database with password that contains an `ü` (u-umlaut) #38

Closed sma closed 1 month ago

sma commented 2 years ago

I'm using version 2.4.3 with Dart 2.18.0-149.0.dev on macOS_x86

I can connect if I change the ü to u, so I'm pretty sure it's the password that isn't accepted. I can successfully connect using the pg package with Node.js so I'm sure that PostgreSQL correctly supports passwords with unicode letters. This package, unfortunately, does not.

Here's my code:

  final conn = PostgreSQLConnection(
    "localhost",
    5432,
    "abc",
    username: "abc",
    password: "übelkübel",
  );
  await conn.open();

Here's how I start a test database using Docker:

docker run --rm --name test \
        -e POSTGRES_USER=abc \
        -e POSTGRES_DB=abc \
        -e POSTGRES_PASSWORD=übelkübel \
        -p 5432:5432 \
        -v "`pwd`/volumes/postgres:/var/lib/postgresql/data" -d \
        postgres:14.3-alpine

According to the documentation on Dockerhub, scram-sha-256 authentication will be used/required. I tried to debug that handshake process and at least checked that SaslPrep.saslprep will correctly normalize the password, using codeunit 252 for ü.

If I have to guess, I'd say that you're supposed to UTF-8 encode the password before digesting it which isn't done. Here's the relevant code in the Node.js implementation. password is a string. And I verified that update(String) will automatically UTF-8 encode its argument.

// these two digests are the same
console.log(crypto.createHash('sha256').update('A').digest())
console.log(crypto.createHash('sha256').update(Buffer.from([65]).digest())
// these aren't
console.log(crypto.createHash('sha256').update('ü').digest())
console.log(crypto.createHash('sha256').update(Buffer.from([252]).digest())
// but is one is again identical to the ü version
console.log(crypto.createHash('sha256').update(Buffer.from([195,188])).digest())
isoos commented 2 years ago

@sma: thanks for the analysis. As you are already deep debugging the code, would you be interested in writing a patch (and maybe a test) for it?

isoos commented 2 years ago

@sma: I also have this branch where I started to add configurable encoding, which may be a related area: https://github.com/isoos/postgresql-dart/tree/encoding

isoos commented 1 month ago

I believe this has been fixed.