Skip to content

Commit abb139b

Browse files
thereisnosunTeodor Morozmethane
authored
Support ssl_mode setting with mariadb client (#475)
According to https://mariadb.com/kb/en/mysql_optionsv/ MariaDB supports TLS enforcing in its own way. So the idea behind this PR is to keep the same interface for MariaDB based clients, but behind the scenes handle it accordingly.(MariaDB gets its own args set, instead of ssl_mode dict supported by MySQL). Co-authored-by: Teodor Moroz <[email protected]> Co-authored-by: Inada Naoki <[email protected]>
1 parent 9953e50 commit abb139b

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

MySQLdb/_mysql.c

+25-11
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,14 @@ static int _mysql_ResultObject_clear(_mysql_ResultObject *self)
380380
return 0;
381381
}
382382

383-
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
383+
enum {
384+
SSLMODE_DISABLED = 1,
385+
SSLMODE_PREFERRED = 2,
386+
SSLMODE_REQUIRED = 3,
387+
SSLMODE_VERIFY_CA = 4,
388+
SSLMODE_VERIFY_IDENTITY = 5
389+
};
390+
384391
static int
385392
_get_ssl_mode_num(char *ssl_mode)
386393
{
@@ -395,7 +402,6 @@ _get_ssl_mode_num(char *ssl_mode)
395402
}
396403
return -1;
397404
}
398-
#endif
399405

400406
static int
401407
_mysql_ConnectionObject_Initialize(
@@ -429,6 +435,7 @@ _mysql_ConnectionObject_Initialize(
429435
int read_timeout = 0;
430436
int write_timeout = 0;
431437
int compress = -1, named_pipe = -1, local_infile = -1;
438+
int ssl_mode_num = SSLMODE_DISABLED;
432439
char *init_command=NULL,
433440
*read_default_file=NULL,
434441
*read_default_group=NULL,
@@ -469,15 +476,10 @@ _mysql_ConnectionObject_Initialize(
469476
_stringsuck(cipher, value, ssl);
470477
}
471478
if (ssl_mode) {
472-
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
473-
if (_get_ssl_mode_num(ssl_mode) <= 0) {
479+
if ((ssl_mode_num = _get_ssl_mode_num(ssl_mode)) <= 0) {
474480
PyErr_SetString(_mysql_NotSupportedError, "Unknown ssl_mode specification");
475481
return -1;
476482
}
477-
#else
478-
PyErr_SetString(_mysql_NotSupportedError, "MySQL client library does not support ssl_mode specification");
479-
return -1;
480-
#endif
481483
}
482484

483485
conn = mysql_init(&(self->connection));
@@ -487,6 +489,7 @@ _mysql_ConnectionObject_Initialize(
487489
}
488490
Py_BEGIN_ALLOW_THREADS ;
489491
self->open = 1;
492+
490493
if (connect_timeout) {
491494
unsigned int timeout = connect_timeout;
492495
mysql_options(&(self->connection), MYSQL_OPT_CONNECT_TIMEOUT,
@@ -521,12 +524,23 @@ _mysql_ConnectionObject_Initialize(
521524
if (ssl) {
522525
mysql_ssl_set(&(self->connection), key, cert, ca, capath, cipher);
523526
}
524-
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
525527
if (ssl_mode) {
526-
int ssl_mode_num = _get_ssl_mode_num(ssl_mode);
528+
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
527529
mysql_options(&(self->connection), MYSQL_OPT_SSL_MODE, &ssl_mode_num);
528-
}
530+
#else
531+
// MariaDB doesn't support MYSQL_OPT_SSL_MODE.
532+
// See https://github.com/PyMySQL/mysqlclient/issues/474
533+
// TODO: Does MariaDB supports PREFERRED and VERIFY_CA?
534+
// We support only two levels for now.
535+
if (sslmode_num >= SSLMODE_REQUIRED) {
536+
mysql_optionsv(&(self->connection), MYSQL_OPT_SSL_ENFORCE, (void *)&enforce_tls);
537+
}
538+
if (sslmode_num >= SSLMODE_VERIFY_CA) {
539+
mysql_optionsv(&(self->connection), MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (void *)&enforce_tls);
540+
}
529541
#endif
542+
}
543+
530544
if (charset) {
531545
mysql_options(&(self->connection), MYSQL_SET_CHARSET_NAME, charset);
532546
}

0 commit comments

Comments
 (0)