diff --git a/doc/user_guide.rst b/doc/user_guide.rst index ab33615..4e724be 100644 --- a/doc/user_guide.rst +++ b/doc/user_guide.rst @@ -393,6 +393,10 @@ connect(parameters...) an exception is raised. *This must be a keyword parameter.* + ssl + specifies path to a RSA public key used by caching sha2 password authentication. + See https://dev.mysql.com/doc/refman/9.0/en/caching-sha2-pluggable-authentication.html + .. _mysql_ssl_set: http://dev.mysql.com/doc/refman/en/mysql-ssl-set.html diff --git a/src/MySQLdb/_mysql.c b/src/MySQLdb/_mysql.c index 1468f3e..2511dea 100644 --- a/src/MySQLdb/_mysql.c +++ b/src/MySQLdb/_mysql.c @@ -36,13 +36,18 @@ PERFORMANCE OF THIS SOFTWARE. #endif #if ((MYSQL_VERSION_ID >= 50555 && MYSQL_VERSION_ID <= 50599) || \ -(MYSQL_VERSION_ID >= 50636 && MYSQL_VERSION_ID <= 50699) || \ -(MYSQL_VERSION_ID >= 50711 && MYSQL_VERSION_ID <= 50799) || \ -(MYSQL_VERSION_ID >= 80000)) && \ -!defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID) + (MYSQL_VERSION_ID >= 50636 && MYSQL_VERSION_ID <= 50699) || \ + (MYSQL_VERSION_ID >= 50711 && MYSQL_VERSION_ID <= 50799) || \ + (MYSQL_VERSION_ID >= 80000)) && \ + !defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID) #define HAVE_ENUM_MYSQL_OPT_SSL_MODE #endif +#if defined(MARIADB_VERSION_ID) && MARIADB_VERSION_ID >= 100403 || \ + !defined(MARIADB_VERSION_ID) && MYSQL_VERSION_ID >= 50723 +#define HAVE_MYSQL_SERVER_PUBLIC_KEY +#endif + #define PY_SSIZE_T_CLEAN 1 #include "Python.h" @@ -431,7 +436,7 @@ _mysql_ConnectionObject_Initialize( "client_flag", "ssl", "ssl_mode", "local_infile", "read_timeout", "write_timeout", "charset", - "auth_plugin", + "auth_plugin", "server_public_key_path", NULL } ; int connect_timeout = 0; int read_timeout = 0; @@ -442,7 +447,8 @@ _mysql_ConnectionObject_Initialize( *read_default_file=NULL, *read_default_group=NULL, *charset=NULL, - *auth_plugin=NULL; + *auth_plugin=NULL, + *server_public_key_path=NULL; self->converter = NULL; self->open = false; @@ -462,10 +468,19 @@ _mysql_ConnectionObject_Initialize( &read_timeout, &write_timeout, &charset, - &auth_plugin + &auth_plugin, + &server_public_key_path )) return -1; +#ifndef HAVE_MYSQL_SERVER_PUBLIC_KEY + if (server_public_key_path) { + PyErr_SetString(_mysql_NotSupportedError, "server_public_key_path is not supported"); + return -1; + } +#endif + // For compatibility with PyPy, we need to keep strong reference + // to unicode objects until we use UTF8. #define _stringsuck(d,t,s) {t=PyMapping_GetItemString(s,#d);\ if(t){d=PyUnicode_AsUTF8(t);ssl_keepref[n_ssl_keepref++]=t;}\ PyErr_Clear();} @@ -542,6 +557,10 @@ _mysql_ConnectionObject_Initialize( mysql_options(&(self->connection), MYSQL_OPT_SSL_CAPATH, capath); mysql_options(&(self->connection), MYSQL_OPT_SSL_CIPHER, cipher); } + for (int i=0 ; i= SSLMODE_REQUIRED) { - mysql_optionsv(&(self->connection), MYSQL_OPT_SSL_ENFORCE, (void *)&my_true); + mysql_options(&(self->connection), MYSQL_OPT_SSL_ENFORCE, (void *)&my_true); } else { - mysql_optionsv(&(self->connection), MYSQL_OPT_SSL_ENFORCE, (void *)&my_false); + mysql_options(&(self->connection), MYSQL_OPT_SSL_ENFORCE, (void *)&my_false); } if (ssl_mode_num >= SSLMODE_VERIFY_CA) { - mysql_optionsv(&(self->connection), MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (void *)&my_true); + mysql_options(&(self->connection), MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (void *)&my_true); } else { - mysql_optionsv(&(self->connection), MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (void *)&my_false); + mysql_options(&(self->connection), MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (void *)&my_false); } #endif @@ -574,17 +593,17 @@ _mysql_ConnectionObject_Initialize( if (auth_plugin) { mysql_options(&(self->connection), MYSQL_DEFAULT_AUTH, auth_plugin); } +#ifdef HAVE_MYSQL_SERVER_PUBLIC_KEY + if (server_public_key_path) { + mysql_options(&(self->connection), MYSQL_SERVER_PUBLIC_KEY, server_public_key_path); + } +#endif Py_BEGIN_ALLOW_THREADS conn = mysql_real_connect(&(self->connection), host, user, passwd, db, port, unix_socket, client_flag); Py_END_ALLOW_THREADS - for (int i=0; i