Skip to content

Commit 1a5ae1d

Browse files
migimigimethane
authored andcommitted
Added to pass ssl_mode in configuration. (#347)
1 parent 102fe7b commit 1a5ae1d

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

MySQLdb/_mysql.c

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ PERFORMANCE OF THIS SOFTWARE.
3434
#define my_bool _Bool
3535
#endif
3636

37+
#if ((MYSQL_VERSION_ID >= 50555 && MYSQL_VERSION_ID <= 50599) || \
38+
(MYSQL_VERSION_ID >= 50636 && MYSQL_VERSION_ID <= 50699) || \
39+
(MYSQL_VERSION_ID >= 50711 && MYSQL_VERSION_ID <= 50799) || \
40+
(MYSQL_VERSION_ID >= 80000)) && \
41+
!defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID)
42+
#define HAVE_ENUM_MYSQL_OPT_SSL_MODE
43+
#endif
44+
3745
#define PY_SSIZE_T_CLEAN 1
3846
#include "Python.h"
3947

@@ -371,6 +379,23 @@ static int _mysql_ResultObject_clear(_mysql_ResultObject *self)
371379
return 0;
372380
}
373381

382+
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
383+
static int
384+
_get_ssl_mode_num(char *ssl_mode)
385+
{
386+
static char *ssl_mode_list[] = { "DISABLED", "PREFERRED",
387+
"REQUIRED", "VERIFY_CA", "VERIFY_IDENTITY" };
388+
unsigned int i;
389+
for (i=0; i < sizeof(ssl_mode_list)/sizeof(ssl_mode_list[0]); i++) {
390+
if (strcmp(ssl_mode, ssl_mode_list[i]) == 0) {
391+
// SSL_MODE one-based
392+
return i + 1;
393+
}
394+
}
395+
return -1;
396+
}
397+
#endif
398+
374399
static int
375400
_mysql_ConnectionObject_Initialize(
376401
_mysql_ConnectionObject *self,
@@ -380,6 +405,7 @@ _mysql_ConnectionObject_Initialize(
380405
MYSQL *conn = NULL;
381406
PyObject *conv = NULL;
382407
PyObject *ssl = NULL;
408+
char *ssl_mode = NULL;
383409
const char *key = NULL, *cert = NULL, *ca = NULL,
384410
*capath = NULL, *cipher = NULL;
385411
PyObject *ssl_keepref[5] = {NULL};
@@ -393,7 +419,7 @@ _mysql_ConnectionObject_Initialize(
393419
"connect_timeout", "compress",
394420
"named_pipe", "init_command",
395421
"read_default_file", "read_default_group",
396-
"client_flag", "ssl",
422+
"client_flag", "ssl", "ssl_mode",
397423
"local_infile",
398424
"read_timeout", "write_timeout", "charset",
399425
"auth_plugin",
@@ -412,15 +438,15 @@ _mysql_ConnectionObject_Initialize(
412438
self->open = 0;
413439

414440
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
415-
"|ssssisOiiisssiOiiiss:connect",
441+
"|ssssisOiiisssiOsiiiss:connect",
416442
kwlist,
417443
&host, &user, &passwd, &db,
418444
&port, &unix_socket, &conv,
419445
&connect_timeout,
420446
&compress, &named_pipe,
421447
&init_command, &read_default_file,
422448
&read_default_group,
423-
&client_flag, &ssl,
449+
&client_flag, &ssl, &ssl_mode,
424450
&local_infile,
425451
&read_timeout,
426452
&write_timeout,
@@ -441,6 +467,17 @@ _mysql_ConnectionObject_Initialize(
441467
_stringsuck(key, value, ssl);
442468
_stringsuck(cipher, value, ssl);
443469
}
470+
if (ssl_mode) {
471+
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
472+
if (_get_ssl_mode_num(ssl_mode) <= 0) {
473+
PyErr_SetString(_mysql_NotSupportedError, "Unknown ssl_mode specification");
474+
return -1;
475+
}
476+
#else
477+
PyErr_SetString(_mysql_NotSupportedError, "MySQL client library does not support ssl_mode specification");
478+
return -1;
479+
#endif
480+
}
444481

445482
conn = mysql_init(&(self->connection));
446483
if (!conn) {
@@ -483,6 +520,12 @@ _mysql_ConnectionObject_Initialize(
483520
if (ssl) {
484521
mysql_ssl_set(&(self->connection), key, cert, ca, capath, cipher);
485522
}
523+
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
524+
if (ssl_mode) {
525+
int ssl_mode_num = _get_ssl_mode_num(ssl_mode);
526+
mysql_options(&(self->connection), MYSQL_OPT_SSL_MODE, &ssl_mode_num);
527+
}
528+
#endif
486529
if (charset) {
487530
mysql_options(&(self->connection), MYSQL_SET_CHARSET_NAME, charset);
488531
}

MySQLdb/connections.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ class object, used to create cursors (keyword only)
102102
:param int client_flag:
103103
flags to use or 0 (see MySQL docs or constants/CLIENTS.py)
104104
105+
:param str ssl_mode:
106+
specify the security settings for connection to the server;
107+
see the MySQL documentation for more details
108+
(mysql_option(), MYSQL_OPT_SSL_MODE).
109+
Only one of 'DISABLED', 'PREFERRED', 'REQUIRED',
110+
'VERIFY_CA', 'VERIFY_IDENTITY' can be specified.
111+
105112
:param dict ssl:
106113
dictionary or mapping contains SSL connection parameters;
107114
see the MySQL documentation for more details

doc/MySQLdb.constants.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,3 @@ constants Package
4848
:members:
4949
:undoc-members:
5050
:show-inheritance:
51-

doc/user_guide.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,18 @@ connect(parameters...)
357357

358358
*This must be a keyword parameter.*
359359

360+
ssl_mode
361+
If present, specify the security settings for the
362+
connection to the server. For more information on ssl_mode,
363+
see the MySQL documentation. Only one of 'DISABLED',
364+
'PREFERRED', 'REQUIRED', 'VERIFY_CA', 'VERIFY_IDENTITY'
365+
can be specified.
366+
367+
If not present, the session ssl_mode will be unchanged,
368+
but in version 5.7 and later, the default is PREFERRED.
369+
370+
*This must be a keyword parameter.*
371+
360372
ssl
361373
This parameter takes a dictionary or mapping, where the
362374
keys are parameter names used by the mysql_ssl_set_ MySQL

0 commit comments

Comments
 (0)