bpo-42333: Port _ssl extension module to heap types (GH-23392)

All types in _ssl module are now heap types.
This commit is contained in:
Christian Heimes 2020-11-20 09:40:12 +01:00 committed by GitHub
parent 03c8ddd9e9
commit 5c36da78d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 363 additions and 336 deletions

View File

@ -0,0 +1 @@
Port _ssl extension module to heap types.

View File

@ -487,10 +487,10 @@ typedef struct {
PySSLContext *ctx;
} PySSLSession;
static PyTypeObject PySSLContext_Type;
static PyTypeObject PySSLSocket_Type;
static PyTypeObject PySSLMemoryBIO_Type;
static PyTypeObject PySSLSession_Type;
static PyTypeObject *PySSLContext_Type;
static PyTypeObject *PySSLSocket_Type;
static PyTypeObject *PySSLMemoryBIO_Type;
static PyTypeObject *PySSLSession_Type;
static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode)
{
@ -508,12 +508,12 @@ static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode)
/*[clinic input]
module _ssl
class _ssl._SSLContext "PySSLContext *" "&PySSLContext_Type"
class _ssl._SSLSocket "PySSLSocket *" "&PySSLSocket_Type"
class _ssl.MemoryBIO "PySSLMemoryBIO *" "&PySSLMemoryBIO_Type"
class _ssl.SSLSession "PySSLSession *" "&PySSLSession_Type"
class _ssl._SSLContext "PySSLContext *" "PySSLContext_Type"
class _ssl._SSLSocket "PySSLSocket *" "PySSLSocket_Type"
class _ssl.MemoryBIO "PySSLMemoryBIO *" "PySSLMemoryBIO_Type"
class _ssl.SSLSession "PySSLSession *" "PySSLSession_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bdc67fafeeaa8109]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cc4883756da17954]*/
#include "clinic/_ssl.c.h"
@ -521,9 +521,9 @@ static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout);
static int PySSL_set_owner(PySSLSocket *, PyObject *, void *);
static int PySSL_set_session(PySSLSocket *, PyObject *, void *);
#define PySSLSocket_Check(v) Py_IS_TYPE(v, &PySSLSocket_Type)
#define PySSLMemoryBIO_Check(v) Py_IS_TYPE(v, &PySSLMemoryBIO_Type)
#define PySSLSession_Check(v) Py_IS_TYPE(v, &PySSLSession_Type)
#define PySSLSocket_Check(v) Py_IS_TYPE(v, PySSLSocket_Type)
#define PySSLMemoryBIO_Check(v) Py_IS_TYPE(v, PySSLMemoryBIO_Type)
#define PySSLSession_Check(v) Py_IS_TYPE(v, PySSLSession_Type)
typedef enum {
SOCKET_IS_NONBLOCKING,
@ -587,7 +587,6 @@ SSLError_str(PyOSErrorObject *self)
}
static PyType_Slot sslerror_type_slots[] = {
{Py_tp_base, NULL}, /* Filled out in module init as it's not a constant */
{Py_tp_doc, (void*)SSLError_doc},
{Py_tp_str, SSLError_str},
{0, 0},
@ -937,7 +936,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
SSL_CTX *ctx = sslctx->ctx;
_PySSLError err = { 0 };
self = PyObject_New(PySSLSocket, &PySSLSocket_Type);
self = PyObject_New(PySSLSocket, PySSLSocket_Type);
if (self == NULL)
return NULL;
@ -2194,7 +2193,7 @@ static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) {
static int PySSL_set_context(PySSLSocket *self, PyObject *value,
void *closure) {
if (PyObject_TypeCheck(value, &PySSLContext_Type)) {
if (PyObject_TypeCheck(value, PySSLContext_Type)) {
#if !HAVE_SNI
PyErr_SetString(PyExc_NotImplementedError, "setting a socket's "
"context is not supported by your OpenSSL library");
@ -2289,6 +2288,7 @@ PySSL_clear(PySSLSocket *self)
static void
PySSL_dealloc(PySSLSocket *self)
{
PyTypeObject *tp = Py_TYPE(self);
if (self->ssl)
SSL_free(self->ssl);
Py_XDECREF(self->Socket);
@ -2296,6 +2296,7 @@ PySSL_dealloc(PySSLSocket *self)
Py_XDECREF(self->server_hostname);
Py_XDECREF(self->owner);
PyObject_Del(self);
Py_DECREF(tp);
}
/* If the socket has a timeout, do a select()/poll() on the socket.
@ -2895,7 +2896,7 @@ PySSL_get_session(PySSLSocket *self, void *closure) {
Py_RETURN_NONE;
}
#endif
pysess = PyObject_GC_New(PySSLSession, &PySSLSession_Type);
pysess = PyObject_GC_New(PySSLSession, PySSLSession_Type);
if (pysess == NULL) {
SSL_SESSION_free(session);
return NULL;
@ -3008,38 +3009,21 @@ static PyMethodDef PySSLMethods[] = {
{NULL, NULL}
};
static PyTypeObject PySSLSocket_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_ssl._SSLSocket", /*tp_name*/
sizeof(PySSLSocket), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)PySSL_dealloc, /*tp_dealloc*/
0, /*tp_vectorcall_offset*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_as_async*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
(traverseproc) PySSL_traverse, /*tp_traverse*/
(inquiry) PySSL_clear, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
PySSLMethods, /*tp_methods*/
0, /*tp_members*/
ssl_getsetlist, /*tp_getset*/
static PyType_Slot PySSLSocket_slots[] = {
{Py_tp_methods, PySSLMethods},
{Py_tp_getset, ssl_getsetlist},
{Py_tp_dealloc, PySSL_dealloc},
{Py_tp_traverse, PySSL_traverse},
{Py_tp_clear, PySSL_clear},
{0, 0},
};
static PyType_Spec PySSLSocket_spec = {
"_ssl._SSLSocket",
sizeof(PySSLSocket),
0,
Py_TPFLAGS_DEFAULT,
PySSLSocket_slots,
};
@ -3316,6 +3300,7 @@ context_clear(PySSLContext *self)
static void
context_dealloc(PySSLContext *self)
{
PyTypeObject *tp = Py_TYPE(self);
/* bpo-31095: UnTrack is needed before calling any callbacks */
PyObject_GC_UnTrack(self);
context_clear(self);
@ -3327,6 +3312,7 @@ context_dealloc(PySSLContext *self)
PyMem_FREE(self->alpn_protocols);
#endif
Py_TYPE(self)->tp_free(self);
Py_DECREF(tp);
}
/*[clinic input]
@ -4366,8 +4352,8 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
/*[clinic input]
_ssl._SSLContext._wrap_bio
incoming: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *")
outgoing: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *")
incoming: object(subclass_of="PySSLMemoryBIO_Type", type="PySSLMemoryBIO *")
outgoing: object(subclass_of="PySSLMemoryBIO_Type", type="PySSLMemoryBIO *")
server_side: int
server_hostname as hostname_obj: object = None
*
@ -4381,7 +4367,7 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
PySSLMemoryBIO *outgoing, int server_side,
PyObject *hostname_obj, PyObject *owner,
PyObject *session)
/*[clinic end generated code: output=5c5d6d9b41f99332 input=8cf22f4d586ac56a]*/
/*[clinic end generated code: output=5c5d6d9b41f99332 input=63867b8f3e1a1aa3]*/
{
char *hostname = NULL;
PyObject *res;
@ -4829,45 +4815,22 @@ static struct PyMethodDef context_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyTypeObject PySSLContext_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_ssl._SSLContext", /*tp_name*/
sizeof(PySSLContext), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)context_dealloc, /*tp_dealloc*/
0, /*tp_vectorcall_offset*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_as_async*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
0, /*tp_doc*/
(traverseproc) context_traverse, /*tp_traverse*/
(inquiry) context_clear, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
context_methods, /*tp_methods*/
0, /*tp_members*/
context_getsetlist, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
0, /*tp_init*/
0, /*tp_alloc*/
_ssl__SSLContext, /*tp_new*/
static PyType_Slot PySSLContext_slots[] = {
{Py_tp_methods, context_methods},
{Py_tp_getset, context_getsetlist},
{Py_tp_new, _ssl__SSLContext},
{Py_tp_dealloc, context_dealloc},
{Py_tp_traverse, context_traverse},
{Py_tp_clear, context_clear},
{0, 0},
};
static PyType_Spec PySSLContext_spec = {
"_ssl._SSLContext",
sizeof(PySSLContext),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
PySSLContext_slots,
};
@ -4915,8 +4878,10 @@ _ssl_MemoryBIO_impl(PyTypeObject *type)
static void
memory_bio_dealloc(PySSLMemoryBIO *self)
{
PyTypeObject *tp = Py_TYPE(self);
BIO_free(self->bio);
Py_TYPE(self)->tp_free(self);
Py_DECREF(tp);
}
static PyObject *
@ -5054,47 +5019,21 @@ static struct PyMethodDef memory_bio_methods[] = {
{NULL, NULL} /* sentinel */
};
static PyTypeObject PySSLMemoryBIO_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_ssl.MemoryBIO", /*tp_name*/
sizeof(PySSLMemoryBIO), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)memory_bio_dealloc, /*tp_dealloc*/
0, /*tp_vectorcall_offset*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_as_async*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
memory_bio_methods, /*tp_methods*/
0, /*tp_members*/
memory_bio_getsetlist, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
0, /*tp_init*/
0, /*tp_alloc*/
_ssl_MemoryBIO, /*tp_new*/
static PyType_Slot PySSLMemoryBIO_slots[] = {
{Py_tp_methods, memory_bio_methods},
{Py_tp_getset, memory_bio_getsetlist},
{Py_tp_new, _ssl_MemoryBIO},
{Py_tp_dealloc, memory_bio_dealloc},
{0, 0},
};
static PyType_Spec PySSLMemoryBIO_spec = {
"_ssl.MemoryBIO",
sizeof(PySSLMemoryBIO),
0,
Py_TPFLAGS_DEFAULT,
PySSLMemoryBIO_slots,
};
/*
* SSL Session object
@ -5103,6 +5042,7 @@ static PyTypeObject PySSLMemoryBIO_Type = {
static void
PySSLSession_dealloc(PySSLSession *self)
{
PyTypeObject *tp = Py_TYPE(self);
/* bpo-31095: UnTrack is needed before calling any callbacks */
PyObject_GC_UnTrack(self);
Py_XDECREF(self->ctx);
@ -5110,6 +5050,7 @@ PySSLSession_dealloc(PySSLSession *self)
SSL_SESSION_free(self->session);
}
PyObject_GC_Del(self);
Py_DECREF(tp);
}
static PyObject *
@ -5251,37 +5192,21 @@ static PyGetSetDef PySSLSession_getsetlist[] = {
{NULL}, /* sentinel */
};
static PyTypeObject PySSLSession_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_ssl.Session", /*tp_name*/
sizeof(PySSLSession), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)PySSLSession_dealloc, /*tp_dealloc*/
0, /*tp_vectorcall_offset*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_as_async*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
0, /*tp_doc*/
(traverseproc)PySSLSession_traverse, /*tp_traverse*/
(inquiry)PySSLSession_clear, /*tp_clear*/
PySSLSession_richcompare, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
0, /*tp_methods*/
0, /*tp_members*/
PySSLSession_getsetlist, /*tp_getset*/
static PyType_Slot PySSLSession_slots[] = {
{Py_tp_getset,PySSLSession_getsetlist},
{Py_tp_richcompare, PySSLSession_richcompare},
{Py_tp_dealloc, PySSLSession_dealloc},
{Py_tp_traverse, PySSLSession_traverse},
{Py_tp_clear, PySSLSession_clear},
{0, 0},
};
static PyType_Spec PySSLSession_spec = {
"_ssl.SSLSession",
sizeof(PySSLSession),
0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
PySSLSession_slots,
};
@ -5979,23 +5904,195 @@ static int _setup_ssl_threads(void) {
#endif /* HAVE_OPENSSL_CRYPTO_LOCK for OpenSSL < 1.1.0 */
PyDoc_STRVAR(module_doc,
"Implementation module for SSL socket operations. See the socket module\n\
for documentation.");
static int
sslmodule_init_types(PyObject *module)
{
PySSLContext_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
module, &PySSLContext_spec, NULL
);
if (PySSLContext_Type == NULL)
return -1;
PySSLSocket_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
module, &PySSLSocket_spec, NULL
);
if (PySSLSocket_Type == NULL)
return -1;
static struct PyModuleDef _sslmodule = {
PyModuleDef_HEAD_INIT,
"_ssl",
module_doc,
-1,
PySSL_methods,
NULL,
NULL,
NULL,
NULL
};
PySSLMemoryBIO_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
module, &PySSLMemoryBIO_spec, NULL
);
if (PySSLMemoryBIO_Type == NULL)
return -1;
PySSLSession_Type = (PyTypeObject *)PyType_FromModuleAndSpec(
module, &PySSLSession_spec, NULL
);
if (PySSLSession_Type == NULL)
return -1;
if (PyModule_AddType(module, PySSLContext_Type))
return -1;
if (PyModule_AddType(module, PySSLSocket_Type))
return -1;
if (PyModule_AddType(module, PySSLMemoryBIO_Type))
return -1;
if (PyModule_AddType(module, PySSLSession_Type))
return -1;
return 0;
}
static int
sslmodule_init_exceptions(PyObject *module)
{
PyObject *bases = NULL;
#define add_exception(exc, name, doc, base) \
do { \
(exc) = PyErr_NewExceptionWithDoc("ssl." name, (doc), (base), NULL); \
if ((exc) == NULL) goto error; \
if (PyModule_AddObjectRef(module, name, exc) < 0) goto error; \
} while(0)
bases = PyTuple_Pack(1, PyExc_OSError);
if (bases == NULL) {
goto error;
}
PySSLErrorObject = PyType_FromSpecWithBases(&sslerror_type_spec, bases);
Py_CLEAR(bases);
if (PySSLErrorObject == NULL) {
goto error;
}
if (PyModule_AddObjectRef(module, "SSLError", PySSLErrorObject) < 0) {
goto error;
}
/* ssl.CertificateError used to be a subclass of ValueError */
bases = PyTuple_Pack(2, PySSLErrorObject, PyExc_ValueError);
if (bases == NULL) {
goto error;
}
add_exception(
PySSLCertVerificationErrorObject,
"SSLCertVerificationError",
SSLCertVerificationError_doc,
bases
);
Py_CLEAR(bases);
add_exception(
PySSLZeroReturnErrorObject,
"SSLZeroReturnError",
SSLZeroReturnError_doc,
PySSLErrorObject
);
add_exception(
PySSLWantWriteErrorObject,
"SSLWantWriteError",
SSLWantWriteError_doc,
PySSLErrorObject
);
add_exception(
PySSLWantReadErrorObject,
"SSLWantReadError",
SSLWantReadError_doc,
PySSLErrorObject
);
add_exception(
PySSLSyscallErrorObject,
"SSLSyscallError",
SSLSyscallError_doc,
PySSLErrorObject
);
add_exception(
PySSLEOFErrorObject,
"SSLEOFError",
SSLEOFError_doc,
PySSLErrorObject
);
#undef add_exception
return 0;
error:
Py_XDECREF(bases);
return -1;
}
static int
sslmodule_init_socketapi(PyObject *module)
{
PySocketModule_APIObject *socket_api;
/* Load _socket module and its C API */
socket_api = PySocketModule_ImportModuleAndAPI();
if (socket_api == NULL)
return -1;
PySocketModule = *socket_api;
return 0;
}
static int
sslmodule_init_errorcodes(PyObject *module)
{
struct py_ssl_error_code *errcode;
struct py_ssl_library_code *libcode;
/* Mappings for error codes */
err_codes_to_names = PyDict_New();
if (err_codes_to_names == NULL)
return -1;
err_names_to_codes = PyDict_New();
if (err_names_to_codes == NULL)
return -1;
lib_codes_to_names = PyDict_New();
if (lib_codes_to_names == NULL)
return -1;
errcode = error_codes;
while (errcode->mnemonic != NULL) {
PyObject *mnemo, *key;
mnemo = PyUnicode_FromString(errcode->mnemonic);
key = Py_BuildValue("ii", errcode->library, errcode->reason);
if (mnemo == NULL || key == NULL)
return -1;
if (PyDict_SetItem(err_codes_to_names, key, mnemo))
return -1;
if (PyDict_SetItem(err_names_to_codes, mnemo, key))
return -1;
Py_DECREF(key);
Py_DECREF(mnemo);
errcode++;
}
libcode = library_codes;
while (libcode->library != NULL) {
PyObject *mnemo, *key;
key = PyLong_FromLong(libcode->code);
mnemo = PyUnicode_FromString(libcode->library);
if (key == NULL || mnemo == NULL)
return -1;
if (PyDict_SetItem(lib_codes_to_names, key, mnemo))
return -1;
Py_DECREF(key);
Py_DECREF(mnemo);
libcode++;
}
if (PyModule_AddObject(module, "err_codes_to_names", err_codes_to_names))
return -1;
if (PyModule_AddObject(module, "err_names_to_codes", err_names_to_codes))
return -1;
if (PyModule_AddObject(module, "lib_codes_to_names", lib_codes_to_names))
return -1;
return 0;
}
static void
parse_openssl_version(unsigned long libver,
@ -6014,113 +6111,43 @@ parse_openssl_version(unsigned long libver,
*major = libver & 0xFF;
}
PyMODINIT_FUNC
PyInit__ssl(void)
static int
sslmodule_init_versioninfo(PyObject *m)
{
PyObject *m, *d, *r, *bases;
PyObject *r;
unsigned long libver;
unsigned int major, minor, fix, patch, status;
PySocketModule_APIObject *socket_api;
struct py_ssl_error_code *errcode;
struct py_ssl_library_code *libcode;
if (PyType_Ready(&PySSLContext_Type) < 0)
return NULL;
if (PyType_Ready(&PySSLSocket_Type) < 0)
return NULL;
if (PyType_Ready(&PySSLMemoryBIO_Type) < 0)
return NULL;
if (PyType_Ready(&PySSLSession_Type) < 0)
return NULL;
/* OpenSSL version */
/* SSLeay() gives us the version of the library linked against,
which could be different from the headers version.
*/
libver = OpenSSL_version_num();
r = PyLong_FromUnsignedLong(libver);
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r))
return -1;
parse_openssl_version(libver, &major, &minor, &fix, &patch, &status);
r = Py_BuildValue("IIIII", major, minor, fix, patch, status);
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r))
return -1;
m = PyModule_Create(&_sslmodule);
if (m == NULL)
return NULL;
d = PyModule_GetDict(m);
r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION));
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r))
return -1;
/* Load _socket module and its C API */
socket_api = PySocketModule_ImportModuleAndAPI();
if (!socket_api)
return NULL;
PySocketModule = *socket_api;
libver = OPENSSL_VERSION_NUMBER;
parse_openssl_version(libver, &major, &minor, &fix, &patch, &status);
r = Py_BuildValue("IIIII", major, minor, fix, patch, status);
if (r == NULL || PyModule_AddObject(m, "_OPENSSL_API_VERSION", r))
return -1;
#ifndef OPENSSL_VERSION_1_1
/* Load all algorithms and initialize cpuid */
OPENSSL_add_all_algorithms_noconf();
/* Init OpenSSL */
SSL_load_error_strings();
SSL_library_init();
#endif
#ifdef HAVE_OPENSSL_CRYPTO_LOCK
/* note that this will start threading if not already started */
if (!_setup_ssl_threads()) {
return NULL;
}
#elif OPENSSL_VERSION_1_1
/* OpenSSL 1.1.0 builtin thread support is enabled */
_ssl_locks_count++;
#endif
/* Add symbols to module dict */
sslerror_type_slots[0].pfunc = PyExc_OSError;
PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec);
if (PySSLErrorObject == NULL)
return NULL;
/* ssl.CertificateError used to be a subclass of ValueError */
bases = Py_BuildValue("OO", PySSLErrorObject, PyExc_ValueError);
if (bases == NULL)
return NULL;
PySSLCertVerificationErrorObject = PyErr_NewExceptionWithDoc(
"ssl.SSLCertVerificationError", SSLCertVerificationError_doc,
bases, NULL);
Py_DECREF(bases);
PySSLZeroReturnErrorObject = PyErr_NewExceptionWithDoc(
"ssl.SSLZeroReturnError", SSLZeroReturnError_doc,
PySSLErrorObject, NULL);
PySSLWantReadErrorObject = PyErr_NewExceptionWithDoc(
"ssl.SSLWantReadError", SSLWantReadError_doc,
PySSLErrorObject, NULL);
PySSLWantWriteErrorObject = PyErr_NewExceptionWithDoc(
"ssl.SSLWantWriteError", SSLWantWriteError_doc,
PySSLErrorObject, NULL);
PySSLSyscallErrorObject = PyErr_NewExceptionWithDoc(
"ssl.SSLSyscallError", SSLSyscallError_doc,
PySSLErrorObject, NULL);
PySSLEOFErrorObject = PyErr_NewExceptionWithDoc(
"ssl.SSLEOFError", SSLEOFError_doc,
PySSLErrorObject, NULL);
if (PySSLCertVerificationErrorObject == NULL
|| PySSLZeroReturnErrorObject == NULL
|| PySSLWantReadErrorObject == NULL
|| PySSLWantWriteErrorObject == NULL
|| PySSLSyscallErrorObject == NULL
|| PySSLEOFErrorObject == NULL)
return NULL;
if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0
|| PyDict_SetItemString(d, "SSLCertVerificationError",
PySSLCertVerificationErrorObject) != 0
|| PyDict_SetItemString(d, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0
|| PyDict_SetItemString(d, "SSLWantReadError", PySSLWantReadErrorObject) != 0
|| PyDict_SetItemString(d, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0
|| PyDict_SetItemString(d, "SSLSyscallError", PySSLSyscallErrorObject) != 0
|| PyDict_SetItemString(d, "SSLEOFError", PySSLEOFErrorObject) != 0)
return NULL;
if (PyDict_SetItemString(d, "_SSLContext",
(PyObject *)&PySSLContext_Type) != 0)
return NULL;
if (PyDict_SetItemString(d, "_SSLSocket",
(PyObject *)&PySSLSocket_Type) != 0)
return NULL;
if (PyDict_SetItemString(d, "MemoryBIO",
(PyObject *)&PySSLMemoryBIO_Type) != 0)
return NULL;
if (PyDict_SetItemString(d, "SSLSession",
(PyObject *)&PySSLSession_Type) != 0)
return NULL;
return 0;
}
static int
sslmodule_init_constants(PyObject *m)
{
PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS",
PY_SSL_DEFAULT_CIPHER_STRING);
@ -6377,72 +6404,71 @@ PyInit__ssl(void)
addbool(m, "HAS_TLSv1_3", 0);
#endif
/* Mappings for error codes */
err_codes_to_names = PyDict_New();
err_names_to_codes = PyDict_New();
if (err_codes_to_names == NULL || err_names_to_codes == NULL)
return 0;
}
static int
sslmodule_legacy(PyObject *module)
{
#ifndef OPENSSL_VERSION_1_1
/* Load all algorithms and initialize cpuid */
OPENSSL_add_all_algorithms_noconf();
/* Init OpenSSL */
SSL_load_error_strings();
SSL_library_init();
#endif
#ifdef HAVE_OPENSSL_CRYPTO_LOCK
/* note that this will start threading if not already started */
if (!_setup_ssl_threads()) {
return NULL;
errcode = error_codes;
while (errcode->mnemonic != NULL) {
PyObject *mnemo, *key;
mnemo = PyUnicode_FromString(errcode->mnemonic);
key = Py_BuildValue("ii", errcode->library, errcode->reason);
if (mnemo == NULL || key == NULL)
return NULL;
if (PyDict_SetItem(err_codes_to_names, key, mnemo))
return NULL;
if (PyDict_SetItem(err_names_to_codes, mnemo, key))
return NULL;
Py_DECREF(key);
Py_DECREF(mnemo);
errcode++;
}
if (PyModule_AddObject(m, "err_codes_to_names", err_codes_to_names))
return NULL;
if (PyModule_AddObject(m, "err_names_to_codes", err_names_to_codes))
#elif OPENSSL_VERSION_1_1
/* OpenSSL 1.1.0 builtin thread support is enabled */
_ssl_locks_count++;
#endif
return 0;
}
PyDoc_STRVAR(module_doc,
"Implementation module for SSL socket operations. See the socket module\n\
for documentation.");
static struct PyModuleDef _sslmodule = {
PyModuleDef_HEAD_INIT,
"_ssl",
module_doc,
-1,
PySSL_methods,
NULL,
NULL,
NULL,
NULL
};
PyMODINIT_FUNC
PyInit__ssl(void)
{
PyObject *m;
m = PyModule_Create(&_sslmodule);
if (m == NULL)
return NULL;
lib_codes_to_names = PyDict_New();
if (lib_codes_to_names == NULL)
if (sslmodule_init_types(m) != 0)
return NULL;
libcode = library_codes;
while (libcode->library != NULL) {
PyObject *mnemo, *key;
key = PyLong_FromLong(libcode->code);
mnemo = PyUnicode_FromString(libcode->library);
if (key == NULL || mnemo == NULL)
return NULL;
if (PyDict_SetItem(lib_codes_to_names, key, mnemo))
return NULL;
Py_DECREF(key);
Py_DECREF(mnemo);
libcode++;
}
if (PyModule_AddObject(m, "lib_codes_to_names", lib_codes_to_names))
if (sslmodule_init_exceptions(m) != 0)
return NULL;
/* OpenSSL version */
/* SSLeay() gives us the version of the library linked against,
which could be different from the headers version.
*/
libver = OpenSSL_version_num();
r = PyLong_FromUnsignedLong(libver);
if (r == NULL)
if (sslmodule_init_socketapi(m) != 0)
return NULL;
if (PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r))
if (sslmodule_init_errorcodes(m) != 0)
return NULL;
parse_openssl_version(libver, &major, &minor, &fix, &patch, &status);
r = Py_BuildValue("IIIII", major, minor, fix, patch, status);
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r))
if (sslmodule_init_constants(m) != 0)
return NULL;
r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION));
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r))
if (sslmodule_init_versioninfo(m) != 0)
return NULL;
libver = OPENSSL_VERSION_NUMBER;
parse_openssl_version(libver, &major, &minor, &fix, &patch, &status);
r = Py_BuildValue("IIIII", major, minor, fix, patch, status);
if (r == NULL || PyModule_AddObject(m, "_OPENSSL_API_VERSION", r))
if (sslmodule_legacy(m) != 0)
return NULL;
return m;

View File

@ -399,7 +399,7 @@ _ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs)
PyObject *return_value = NULL;
int proto_version;
if ((type == &PySSLContext_Type) &&
if ((type == PySSLContext_Type) &&
!_PyArg_NoKeywords("_SSLContext", kwargs)) {
goto exit;
}
@ -754,13 +754,13 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t
if (!args) {
goto exit;
}
if (!PyObject_TypeCheck(args[0], &PySSLMemoryBIO_Type)) {
_PyArg_BadArgument("_wrap_bio", "argument 'incoming'", (&PySSLMemoryBIO_Type)->tp_name, args[0]);
if (!PyObject_TypeCheck(args[0], PySSLMemoryBIO_Type)) {
_PyArg_BadArgument("_wrap_bio", "argument 'incoming'", (PySSLMemoryBIO_Type)->tp_name, args[0]);
goto exit;
}
incoming = (PySSLMemoryBIO *)args[0];
if (!PyObject_TypeCheck(args[1], &PySSLMemoryBIO_Type)) {
_PyArg_BadArgument("_wrap_bio", "argument 'outgoing'", (&PySSLMemoryBIO_Type)->tp_name, args[1]);
if (!PyObject_TypeCheck(args[1], PySSLMemoryBIO_Type)) {
_PyArg_BadArgument("_wrap_bio", "argument 'outgoing'", (PySSLMemoryBIO_Type)->tp_name, args[1]);
goto exit;
}
outgoing = (PySSLMemoryBIO *)args[1];
@ -919,11 +919,11 @@ _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
if ((type == &PySSLMemoryBIO_Type) &&
if ((type == PySSLMemoryBIO_Type) &&
!_PyArg_NoPositional("MemoryBIO", args)) {
goto exit;
}
if ((type == &PySSLMemoryBIO_Type) &&
if ((type == PySSLMemoryBIO_Type) &&
!_PyArg_NoKeywords("MemoryBIO", kwargs)) {
goto exit;
}
@ -1447,4 +1447,4 @@ exit:
#ifndef _SSL_ENUM_CRLS_METHODDEF
#define _SSL_ENUM_CRLS_METHODDEF
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
/*[clinic end generated code: output=d4e4f9cdd08819f4 input=a9049054013a1b77]*/
/*[clinic end generated code: output=2bb53a80040c9b35 input=a9049054013a1b77]*/