Skip to content

Added to pass ssl_mode in configuration. #347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions MySQLdb/_mysql.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ _mysql_ConnectionObject_Initialize(
*capath = NULL, *cipher = NULL;
PyObject *ssl_keepref[5] = {NULL};
int n_ssl_keepref = 0;
int ssl_mode = 0;
char *host = NULL, *user = NULL, *passwd = NULL,
*db = NULL, *unix_socket = NULL;
unsigned int port = 0;
Expand All @@ -393,7 +394,7 @@ _mysql_ConnectionObject_Initialize(
"connect_timeout", "compress",
"named_pipe", "init_command",
"read_default_file", "read_default_group",
"client_flag", "ssl",
"client_flag", "ssl", "ssl_mode",
"local_infile",
"read_timeout", "write_timeout", "charset",
"auth_plugin",
Expand All @@ -412,15 +413,15 @@ _mysql_ConnectionObject_Initialize(
self->open = 0;

if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|ssssisOiiisssiOiiiss:connect",
"|ssssisOiiisssiOiiiiss:connect",
kwlist,
&host, &user, &passwd, &db,
&port, &unix_socket, &conv,
&connect_timeout,
&compress, &named_pipe,
&init_command, &read_default_file,
&read_default_group,
&client_flag, &ssl,
&client_flag, &ssl, &ssl_mode,
&local_infile,
&read_timeout,
&write_timeout,
Expand Down Expand Up @@ -480,6 +481,16 @@ _mysql_ConnectionObject_Initialize(
if (local_infile != -1)
mysql_options(&(self->connection), MYSQL_OPT_LOCAL_INFILE, (char *) &local_infile);

#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)
#define HAVE_ENUM_MYSQL_OPT_SSL_MODE
if (ssl_mode) {
mysql_options(&(self->connection), MYSQL_OPT_SSL_MODE, &ssl_mode);
}
#endif
if (ssl) {
mysql_ssl_set(&(self->connection), key, cert, ca, capath, cipher);
}
Expand Down Expand Up @@ -1516,6 +1527,20 @@ _mysql_get_client_info(
return PyUnicode_FromString(mysql_get_client_info());
}

static char _mysql_get_have_enum_mysql_opt_ssl_mode__doc__[] =
"Returns whether enum MYSQL_OPT_SSL_MODE is defined.";
static PyObject *
_mysql_get_have_enum_mysql_opt_ssl_mode(
PyObject *self,
PyObject *noargs)
{
#ifdef HAVE_ENUM_MYSQL_OPT_SSL_MODE
Py_RETURN_TRUE;
#else
Py_RETURN_FALSE;
#endif
}

static char _mysql_ConnectionObject_get_host_info__doc__[] =
"Returns a string that represents the MySQL client library\n\
version. Non-standard.\n\
Expand Down Expand Up @@ -2567,6 +2592,12 @@ _mysql_methods[] = {
METH_NOARGS,
_mysql_get_client_info__doc__
},
{
"get_have_enum_mysql_opt_ssl_mode",
(PyCFunction)_mysql_get_have_enum_mysql_opt_ssl_mode,
METH_NOARGS,
_mysql_get_have_enum_mysql_opt_ssl_mode__doc__
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't add new API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see.

{NULL, NULL} /* sentinel */
};

Expand Down
17 changes: 16 additions & 1 deletion MySQLdb/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ class object, used to create cursors (keyword only)
:param int client_flag:
flags to use or 0 (see MySQL docs or constants/CLIENTS.py)

:param str ssl_mode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:param str ssl_mode
:param str ssl_mode:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

specify the security settings for connection to the server;
see the MySQL documentation for more details
(mysql_option(), MYSQL_OPT_SSL_MODE).
Only one of 'DISABLED', 'PREFERRED', 'REQUIRED',
'VERIFY_CA', 'VERIFY_IDENTITY' can be specified.

:param dict ssl:
dictionary or mapping contains SSL connection parameters;
see the MySQL documentation for more details
Expand All @@ -123,7 +130,7 @@ class object, used to create cursors (keyword only)
There are a number of undocumented, non-standard methods. See the
documentation for the MySQL C API for some hints on what they do.
"""
from MySQLdb.constants import CLIENT, FIELD_TYPE
from MySQLdb.constants import CLIENT, FIELD_TYPE, SSL_MODE
from MySQLdb.converters import conversions, _bytes_or_str
from weakref import proxy

Expand Down Expand Up @@ -162,6 +169,14 @@ class object, used to create cursors (keyword only)

kwargs2['client_flag'] = client_flag

if 'ssl_mode' in kwargs:
if not _mysql.get_have_enum_mysql_opt_ssl_mode():
raise NotSupportedError('Does not support ssl_mode specification: %s' % _mysql.get_client_info())
if hasattr(SSL_MODE, kwargs['ssl_mode']):
kwargs2['ssl_mode'] = getattr(SSL_MODE, kwargs['ssl_mode'])
else:
raise NotSupportedError('Unknown MySQL ssl_mode specification: %s' % kwargs['ssl_mode'])

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implement this block in C.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented error checking on the C lang side.
And removed MySQLdb.constants.SSL_MODE, which is no longer needed.

# PEP-249 requires autocommit to be initially off
autocommit = kwargs2.pop('autocommit', False)

Expand Down
11 changes: 11 additions & 0 deletions MySQLdb/constants/SSL_MODE.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""MySQL SSL_MODE Constants

These constants are used to specify SSL_MODE.

"""

DISABLED = 1
PREFERRED = 2
REQUIRED = 3
VERIFY_CA = 4
VERIFY_IDENTITY = 5
2 changes: 1 addition & 1 deletion MySQLdb/constants/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__all__ = ['CR', 'FIELD_TYPE','CLIENT','ER','FLAG']
__all__ = ['CR', 'FIELD_TYPE','CLIENT','ER','FLAG','SSL_MODE']
7 changes: 7 additions & 0 deletions doc/MySQLdb.constants.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,10 @@ constants Package
:undoc-members:
:show-inheritance:

:mod:`SSL_MODE` Module
------------------

.. automodule:: MySQLdb.constants.SSL_MODE
:members:
:undoc-members:
:show-inheritance:
12 changes: 12 additions & 0 deletions doc/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,18 @@ connect(parameters...)

*This must be a keyword parameter.*

ssl_mode
If present, specify the security settings for the
connection to the server. For more information on ssl_mode,
see the MySQL documentation. Only one of 'DISABLED',
'PREFERRED', 'REQUIRED', 'VERIFY_CA', 'VERIFY_IDENTITY'
can be specified.

If not present, the session ssl_mode will be unchanged,
but in version 5.7 and later, the default is PREFERRED.

*This must be a keyword parameter.*

ssl
This parameter takes a dictionary or mapping, where the
keys are parameter names used by the mysql_ssl_set_ MySQL
Expand Down
1 change: 1 addition & 0 deletions metadata.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ py_modules:
MySQLdb.constants.ER
MySQLdb.constants.FIELD_TYPE
MySQLdb.constants.FLAG
MySQLdb.constants.SSL_MODE