Skip to content

Commit 172f8cc

Browse files
author
Geert Vanderkelen
committed
BUG21529781: Fix usage of auth_plugin option with CExtension
We fix a segmentation fault when, using the CExtension, auth_plugin option is used with Python. Additionally, MySQL Error 2061 is now an InterfaceError instead of a DatabaseError. Unit tests are updated. (cherry picked from commit 7f3efa8)
1 parent 1a3e3c1 commit 172f8cc

File tree

3 files changed

+66
-54
lines changed

3 files changed

+66
-54
lines changed

lib/mysql/connector/errors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,5 @@ class MySQLFabricError(Error):
300300
2013: OperationalError,
301301
2049: NotSupportedError,
302302
2055: OperationalError,
303+
2061: InterfaceError,
303304
}

src/mysql_capi.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ MySQL_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
315315
self->result= NULL;
316316
self->fields= NULL;
317317
self->use_unicode= 1;
318-
self->auth_plugin= NULL;
318+
self->auth_plugin= PyStringFromString("mysql_native_password");
319319

320320
return (PyObject *)self;
321321
}
@@ -367,7 +367,7 @@ MySQL_init(MySQL *self, PyObject *args, PyObject *kwds)
367367
&PyStringType, &self->charset_name,
368368
&PyIntType, &con_timeout,
369369
&PyBool_Type, &use_unicode,
370-
&auth_plugin))
370+
&PyStringType, &auth_plugin))
371371
return -1;
372372

373373
if (self->buffered_at_connect)
@@ -1113,8 +1113,8 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
11131113
mysql_ssl_set(&self->session, ssl_key, ssl_cert, ssl_ca, NULL, NULL);
11141114
}
11151115

1116-
if (self->auth_plugin) {
1117-
auth_plugin= PyBytesAsString(self->auth_plugin);
1116+
if (PyString_Check(self->auth_plugin)) {
1117+
auth_plugin= PyStringAsString(self->auth_plugin);
11181118
mysql_options(&self->session, MYSQL_DEFAULT_AUTH, auth_plugin);
11191119
if (strcmp(auth_plugin, "mysql_clear_password") == 0)
11201120
{
@@ -2269,7 +2269,7 @@ MySQL_fetch_row(MySQL *self)
22692269
for (i= 0; i < num_fields; i++) {
22702270
if (row[i] == NULL)
22712271
{
2272-
Py_INCREF(Py_None);
2272+
Py_INCREF(Py_None);
22732273
PyTuple_SET_ITEM(result_row, i, Py_None);
22742274
continue;
22752275
}

tests/test_bugs.py

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,23 +2211,25 @@ class BugOra16217765(tests.MySQLConnectorTests):
22112211
"""
22122212

22132213
users = {
2214-
'sha256_password': {
2214+
'sha256user': {
22152215
'username': 'sha256user',
22162216
'password': 'sha256P@ss',
2217+
'auth_plugin': 'sha256_password',
22172218
},
2218-
'mysql_native_password': {
2219+
'nativeuser': {
22192220
'username': 'nativeuser',
22202221
'password': 'nativeP@ss',
2222+
'auth_plugin': 'mysql_native_password',
22212223
},
2222-
}
2223-
users_nopass = {
2224-
'sha256_password': {
2224+
'sha256user_np': {
22252225
'username': 'sha256user_np',
22262226
'password': '',
2227+
'auth_plugin': 'sha256_password',
22272228
},
2228-
'mysql_native_password': {
2229+
'nativeuser_np': {
22292230
'username': 'nativeuser_np',
22302231
'password': '',
2232+
'auth_plugin': 'mysql_native_password',
22312233
},
22322234
}
22332235

@@ -2271,9 +2273,16 @@ def setUp(self):
22712273
self.host = config['host']
22722274
self.admin_cnx = connection.MySQLConnection(**config)
22732275

2276+
for key, user in self.users.items():
2277+
self._create_user(self.admin_cnx, user['username'],
2278+
user['password'],
2279+
self.host,
2280+
config['database'],
2281+
plugin=user['auth_plugin'])
2282+
22742283
def tearDown(self):
2275-
for plugin_name, info in self.users.items():
2276-
self._drop_user(self.admin_cnx, info['username'], self.host)
2284+
for key, user in self.users.items():
2285+
self._drop_user(self.admin_cnx, user['username'], self.host)
22772286

22782287
@unittest.skipIf(tests.MYSQL_VERSION < (5, 6, 6),
22792288
"MySQL {0} does not support sha256_password auth".format(
@@ -2290,50 +2299,53 @@ def test_sha256(self):
22902299
'ssl_key': tests.SSL_KEY,
22912300
})
22922301

2293-
auth_plugin = 'sha256_password'
2294-
for user in (self.users[auth_plugin], self.users_nopass[auth_plugin]):
2295-
self._create_user(self.admin_cnx, user['username'],
2296-
user['password'],
2297-
self.host,
2298-
config['database'],
2299-
plugin=auth_plugin)
2302+
user = self.users['sha256user']
2303+
config['user'] = user['username']
2304+
config['password'] = user['password']
2305+
config['client_flags'] = [constants.ClientFlag.PLUGIN_AUTH]
2306+
config['auth_plugin'] = user['auth_plugin']
2307+
2308+
try:
2309+
cnx = connection.MySQLConnection(**config)
2310+
except Exception as exc:
2311+
import traceback
2312+
traceback.print_exc()
2313+
self.fail(self.errmsg.format(config['auth_plugin'], exc))
23002314

2301-
config['user'] = user['username']
2302-
config['password'] = user['password']
2303-
config['client_flags'] = [constants.ClientFlag.PLUGIN_AUTH]
2315+
try:
2316+
cnx.cmd_change_user(config['user'], config['password'])
2317+
except:
2318+
self.fail("Changing user using sha256_password auth failed "
2319+
"with pure Python connector")
23042320

2321+
if CMySQLConnection:
23052322
try:
2306-
cnx = connection.MySQLConnection(**config)
2307-
except:
2323+
cnx = CMySQLConnection(**config)
2324+
except Exception as exc:
23082325
import traceback
23092326
traceback.print_exc()
2310-
self.fail("Connecting using sha256_password auth failed")
2311-
2327+
self.fail(self.errmsg.format(config['auth_plugin'], exc))
23122328
try:
23132329
cnx.cmd_change_user(config['user'], config['password'])
23142330
except:
2315-
self.fail("Changing user using sha256_password auth failed")
2331+
self.fail("Changing user using sha256_password auth failed "
2332+
"with CExtension")
23162333

23172334
@unittest.skipIf(tests.MYSQL_VERSION < (5, 6, 6),
23182335
"MySQL {0} does not support sha256_password auth".format(
23192336
tests.MYSQL_VERSION_TXT))
23202337
def test_sha256_nonssl(self):
23212338
config = tests.get_mysql_config()
23222339
config['unix_socket'] = None
2340+
config['client_flags'] = [constants.ClientFlag.PLUGIN_AUTH]
23232341

2324-
auth_plugin = 'sha256_password'
2325-
for user in (self.users[auth_plugin], self.users_nopass[auth_plugin]):
2326-
self._create_user(self.admin_cnx, user['username'],
2327-
user['password'],
2328-
self.host,
2329-
config['database'],
2330-
plugin=auth_plugin)
2331-
2332-
config['user'] = user['username']
2333-
config['password'] = user['password']
2334-
config['client_flags'] = [constants.ClientFlag.PLUGIN_AUTH]
2335-
self.assertRaises(errors.InterfaceError, connection.MySQLConnection,
2336-
**config)
2342+
user = self.users['sha256user']
2343+
config['user'] = user['username']
2344+
config['password'] = user['password']
2345+
self.assertRaises(errors.InterfaceError, connection.MySQLConnection,
2346+
**config)
2347+
if CMySQLConnection:
2348+
self.assertRaises(errors.InterfaceError, CMySQLConnection, **config)
23372349

23382350
@unittest.skipIf(tests.MYSQL_VERSION < (5, 5, 7),
23392351
"MySQL {0} does not support authentication plugins".format(
@@ -2342,22 +2354,21 @@ def test_native(self):
23422354
config = tests.get_mysql_config()
23432355
config['unix_socket'] = None
23442356

2345-
auth_plugin = 'mysql_native_password'
2346-
for user in (self.users[auth_plugin], self.users_nopass[auth_plugin]):
2347-
self._create_user(self.admin_cnx, user['username'],
2348-
user['password'],
2349-
self.host,
2350-
config['database'],
2351-
plugin=auth_plugin)
2357+
user = self.users['nativeuser']
2358+
config['user'] = user['username']
2359+
config['password'] = user['password']
2360+
config['client_flags'] = [constants.ClientFlag.PLUGIN_AUTH]
2361+
config['auth_plugin'] = user['auth_plugin']
2362+
try:
2363+
cnx = connection.MySQLConnection(**config)
2364+
except Exception as exc:
2365+
self.fail(self.errmsg.format(config['auth_plugin'], exc))
23522366

2353-
config['user'] = user['username']
2354-
config['password'] = user['password']
2355-
config['client_flags'] = [constants.ClientFlag.PLUGIN_AUTH]
2367+
if CMySQLConnection:
23562368
try:
2357-
cnx = connection.MySQLConnection(**config)
2369+
cnx = CMySQLConnection(**config)
23582370
except Exception as exc:
2359-
self.fail("Connecting using {0} auth failed: {1}".format(
2360-
auth_plugin, exc))
2371+
self.fail(self.errmsg.format(config['auth_plugin'], exc))
23612372

23622373

23632374
class BugOra18144971(tests.MySQLConnectorTests):

0 commit comments

Comments
 (0)