summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2020-11-20 08:40:12 (GMT)
committerGitHub <noreply@github.com>2020-11-20 08:40:12 (GMT)
commit5c36da78d738d0e5fdb539a758cc15abc47c843b (patch)
tree3d26c24a2abc76fb63bc1db318936c93b8210221
parent03c8ddd9e94c7bddf1f06cf785027b8d2bf00ff0 (diff)
downloadcpython-5c36da78d738d0e5fdb539a758cc15abc47c843b.zip
cpython-5c36da78d738d0e5fdb539a758cc15abc47c843b.tar.gz
cpython-5c36da78d738d0e5fdb539a758cc15abc47c843b.tar.bz2
bpo-42333: Port _ssl extension module to heap types (GH-23392)
All types in _ssl module are now heap types.
-rw-r--r--Misc/NEWS.d/next/Library/2020-11-12-18-21-15.bpo-42333.J9vFmV.rst1
-rw-r--r--Modules/_ssl.c682
-rw-r--r--Modules/clinic/_ssl.c.h16
3 files changed, 363 insertions, 336 deletions
diff --git a/Misc/NEWS.d/next/Library/2020-11-12-18-21-15.bpo-42333.J9vFmV.rst b/Misc/NEWS.d/next/Library/2020-11-12-18-21-15.bpo-42333.J9vFmV.rst
new file mode 100644
index 0000000..f8755c7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-11-12-18-21-15.bpo-42333.J9vFmV.rst
@@ -0,0 +1 @@
+Port _ssl extension module to heap types.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index a34313b..130dce4 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -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;
-
- m = PyModule_Create(&_sslmodule);
- if (m == NULL)
- return NULL;
- d = PyModule_GetDict(m);
-
- /* Load _socket module and its C API */
- socket_api = PySocketModule_ImportModuleAndAPI();
- if (!socket_api)
- return NULL;
- PySocketModule = *socket_api;
+ /* 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;
-#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
+ 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;
-#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
+ r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION));
+ if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r))
+ return -1;
- /* Add symbols to module dict */
- sslerror_type_slots[0].pfunc = PyExc_OSError;
- PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec);
- if (PySSLErrorObject == NULL)
- 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))
+ return -1;
- /* 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;
diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h
index 2375f83..43469d3 100644
--- a/Modules/clinic/_ssl.c.h
+++ b/Modules/clinic/_ssl.c.h
@@ -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]*/