mysql-net / MySqlConnector

MySQL Connector for .NET
https://mysqlconnector.net
MIT License
1.38k stars 331 forks source link

Authentication problem against MariaDB 10.4 with PAM #703

Closed wollud1969 closed 4 years ago

wollud1969 commented 4 years ago

Authentication fails against MariaDB 10.4 with PAM. LDAP trace reveals that last character of password is swallowed. Tests with HeidiSQL 10.1.0.5464 and MariaDB 10.3.13 CLI client (Windows) using the same credentials and against the same server work.

bgrainger commented 4 years ago

If this is a "non-standard" MariaDB configuration (the tests routinely pass against vanilla MariaDB 10.4, e.g., https://travis-ci.org/mysql-net/MySqlConnector/jobs/587524438), are you able to provide a Dockerfile (or similar) that reproduces the problem?

wollud1969 commented 4 years ago

I've prepare something to reproduce the scenario. You find it here: https://gitlab.com/wolutator/mariadb-with-ldap-pam. Use the branch forTestPurposes. In the directory testyou find a script startEnv.sh to start an LDAP server with one user record and the MariaDB server configured to authenticate against that LDAP server. There are sleep statements in the script to give both the LDAP and the database server time to start before loading bootstrap data into it. On my laptop these sleep times are fine, on a really small Azure VM, which I just used to double check the script and the test they are still too short. In the directory test/dotnet you find a small snippet of code which uses MySqlConnector to access the database. Just run dotnet build && dotnet run. Username, password and all the stuff is hardcoded.

I've attached a pcap file with the LDAP requests during the run of the dotnet test tool.

Here is also a screenshot with the interesting part from that trace: image

Note in the authentication section the simple: test12, here the last character from the password is stripped.

The second pcap file in the archive is from a working database connection using the mariadb/mysql CLI.

The interesting part from the LDAP traffic is here: image Here, the password is complete.

Attached file with LDAP-traces: ldap.zip

Thank you very much!

wollud1969 commented 4 years ago

I'm trying to track this down on my own. For this purpose I installed the most recent version of dotnet core (3.0.100) and tried to run the tests according to your contribution guide before trying to change anything: start the MySQL server using the docker command, copied the config.json.example, changed nothing within since I'm using your docker command to start the server and issue dotnet test -c Release from tests/SideBySide. However, everything I'm seeing is:

C:\Users\dehottgw\workspaces\workspace-main\MySqlConnector-cloned\tests\SideBySide [master ≡]> dotnet test -c Release
C:\Program Files\dotnet\sdk\3.0.100\Microsoft.Common.CurrentVersion.targets(1175,5): error MSB3644: Die Verweisassemblys für ".NETFramework,Version=v4.5.2" wurden nicht gefunden. Installieren Sie zum Beheben dieses Problems das Developer Pack (SDK/Paket zur Festlegung von Zielversionen) für diese Frameworkversion, oder richten Sie Ihre Anwendung neu aus. Sie können .NET Framework Developer Packs unter https://aka.ms/msbuild/developerpacks herunterladen. [C:\Users\dehottgw\workspaces\workspace-main\MySqlConnector-cloned\tests\SideBySide\SideBySide.csproj]
C:\Program Files\dotnet\sdk\3.0.100\Microsoft.Common.CurrentVersion.targets(1175,5): error MSB3644: Die Verweisassemblys für ".NETFramework,Version=v4.6.1" wurden nicht gefunden. Installieren Sie zum Beheben dieses Problems das Developer Pack (SDK/Paket zur Festlegung von Zielversionen) für diese Frameworkversion, oder richten Sie Ihre Anwendung neu aus. Sie können .NET Framework Developer Packs unter https://aka.ms/msbuild/developerpacks herunterladen. [C:\Users\dehottgw\workspaces\workspace-main\MySqlConnector-cloned\tests\SideBySide\SideBySide.csproj]
C:\Program Files\dotnet\sdk\3.0.100\Microsoft.Common.CurrentVersion.targets(1175,5): error MSB3644: Die Verweisassemblys für ".NETFramework,Version=v4.7.2" wurden nicht gefunden. Installieren Sie zum Beheben dieses Problems das Developer Pack (SDK/Paket zur Festlegung von Zielversionen) für diese Frameworkversion, oder richten Sie Ihre Anwendung neu aus. Sie können .NET Framework Developer Packs unter https://aka.ms/msbuild/developerpacks herunterladen. [C:\Users\dehottgw\workspaces\workspace-main\MySqlConnector-cloned\tests\SideBySide\SideBySide.csproj]
C:\Users\dehottgw\workspaces\workspace-main\MySqlConnector-cloned\tests\SideBySide [master ≡]>

Is there anything else besides dotnet core I need to install?

wollud1969 commented 4 years ago

Is this related to #268?

bgrainger commented 4 years ago

It sounds like there are problems compiling for net452, etc. This block in the CSPROJ is supposed to address that (and it does, on Linux, where the tests pass):

https://github.com/mysql-net/MySqlConnector/blob/master/tests/SideBySide/SideBySide.csproj#L52-L57

Are you on Linux or macOS?

One workaround would be to change https://github.com/mysql-net/MySqlConnector/blob/c28126ed97700c4f71f3845c0f9f9cbcc12d6c47/tests/SideBySide/SideBySide.csproj#L4 to just <TargetFramework>netcoreapp3.0</TargetFramework> so you're not compiling for the full .NET Framework.

bgrainger commented 4 years ago

Is this related to #268?

I suppose it could be. I haven't set up your test environment yet, but since (I assume) MariaDB is sending the password in clear text to the LDAP server, it must also have received it in clear text from MySqlConnector. The only way for that to happen is mysql_clear_password.

At a first glance, it looks like the client is sending the entire password, which must mean that MariaDB is truncating the last character. Is there supposed to be a NULL padding byte?

bgrainger commented 4 years ago

MariaDB expects a trailing NULL: https://github.com/MariaDB/mariadb-connector-c/blob/9ba8e32f6d0fe449114d8eb369cf29303257b460/plugins/auth/mariadb_cleartext.c#L50-L51

bgrainger commented 4 years ago

The mysql-connector-j client writes a trailing NULL: https://github.com/mysql/mysql-connector-j/blob/66459e9d39c8fd09767992bc592acd2053279be6/src/main/protocol-impl/java/com/mysql/cj/protocol/a/authentication/MysqlClearPasswordPlugin.java#L77-L80

Adding a NULL byte in MySqlConnector should be a simple fix (and would be compatible with any server that's performing a simple strcmp on the submitted password).

bgrainger commented 4 years ago

Another example of NULL terminator being written: https://github.com/mysql/mysql-server/blob/4869291f7ee258e136ef03f5a50135fe7329ffb9/sql-common/client.cc#L8365-L8367

wollud1969 commented 4 years ago

I'm alternatively on Windows or on Linux. I suppose the failing tests concerning UnixDomainSockets on Windows are okay, aren't they.

That was a fast fix, thank you very much indeed. Will there be a new package on nuget shortly?

bgrainger commented 4 years ago

Yes, 0.59.0 should be shipping later today.

bgrainger commented 4 years ago

Fixed in 0.59.0.