I am trying to connect to a Azure MySQL 5.7 with SSL, but I have run into an error that I cannot seem to resolve.
Connecting works fine for
Connecting doesn't work for
I call mysql.exe with the following working command
mysql.exe -h server.mysql.database.azure.com -u user@server -p --ssl
This connects and doesn't present any issues. MySQL Workbench 8.0 works fine too.
But then using the Qt MySQL plugin to connect yields this error.
SSL connection error: socket layer receive error
This is the Qt code I'm using to connect
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("server.mysql.database.azure.com");
db.setPort(3306);
db.setDatabaseName("databasename");
db.setUserName("user@server");
db.setPassword("password");
db.setConnectOptions("SSL_CA=C:/Users/User/Downloads/BaltimoreCyberTrustRoot.crt.pem");
if (!db.open()) {
std::cout << db.lastError().text().toStdString() << "\n";
}
Next I tried using the MySQL Connector/C (which Qt uses underneath) to directly connect to the Azure database.
MYSQL* mysql = mysql_init(nullptr);
char* t = "C:/Users/User/Downloads/BaltimoreCyberTrustRoot.crt.pem";
mysql_ssl_set(mysql, nullptr, nullptr, t, nullptr, nullptr);
if (!mysql_real_connect(mysql, "server.mysql.database.azure.com", "user@server", "password", "databasename", 3306, nullptr, 0)) {
fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(mysql));
}
mysql_close(mysql);
Which both produce the socket layer error.
Disabling SSL in Azure allows me to connect with both Qt and MySQL Connector/C. This means that the connection data (username, password, hostname) are correct, but that there is possibly an issue with setting SSL options.
Qt version 5.13.1
MySQL Connector/C 8.0.18
MySQL DB 5.7
I don't have any exposure to Qt, but I do MySQL and SSL, so after reading your question was intrigued.
I'm afraid to tell you that it would appear Qt have inadvertently coded out the transport security capabilities with this update:
https://codereview.qt-project.org/c/qt/qtbase/+/96849/11/src/sql/drivers/mysql/qsql_mysql.cpp
I say inadvertently because I can't believe that they intended on replacing CLIENT_SSL with client certificate authentication. CLIENT_SSL is still a valid option for the mysql_real_connect interface, but options validation is ignoring it. Without reaching out I can only assume that a developer was tasked with updating the code to support client certificates and confused client certs with transport encryption, swapping the functionality instead of adding to it.
This breaking change was introduced in version 5.5. If you're feeling daring enough, you could pull the codebase and change:
else if (opt == QLatin1String("CLIENT_SSL"))
qWarning("QMYSQLDriver: SSL_KEY, SSL_CERT and SSL_CA should be used instead of CLIENT_SSL.");
To:
else if (opt == QLatin1String("CLIENT_SSL"))
optionFlags |= CLIENT_SSL;
Compile & much luck...or you have these options.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With