From 132a2dda4605f9c7e6c3205771e64725b8cbde3f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:21:05 -0400 Subject: [PATCH 01/59] Make SSL objects thread safe. --- Modules/_ssl.c | 251 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 233 insertions(+), 18 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f2d3b331226a7a..ced5513880438c 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -51,6 +51,13 @@ PySSL_BEGIN_ALLOW_THREADS_S(_save); #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } +#ifdef Py_GIL_DISABLED +#define PySSL_LOCK(obj) PyMutex_Lock(obj->lock) +#define PySSL_UNLOCK(obj) PyMutex_Unlock(obj->lock) +#else +#define PySSL_LOCK(obj) +#define PySSL_UNLOCK(obj) +#endif #if defined(HAVE_POLL_H) #include @@ -310,6 +317,9 @@ typedef struct { PyObject *psk_client_callback; PyObject *psk_server_callback; #endif +#ifdef Py_GIL_DISABLED + PyMutex lock; +#endif } PySSLContext; typedef struct { @@ -335,18 +345,27 @@ typedef struct { * and shutdown methods check for chained exceptions. */ PyObject *exc; +#ifdef Py_GIL_DISABLED + PyMutex lock; +#endif } PySSLSocket; typedef struct { PyObject_HEAD BIO *bio; int eof_written; +#ifdef Py_GIL_DISABLED + PyMutex lock; +#endif } PySSLMemoryBIO; typedef struct { PyObject_HEAD SSL_SESSION *session; PySSLContext *ctx; +#ifdef Py_GIL_DISABLED + PyMutex lock; +#endif } PySSLSession; static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode) @@ -509,7 +528,9 @@ fill_and_set_sslerror(_sslmodulestate *state, const char *verify_str = NULL; long verify_code; + PySSL_LOCK(sslsock); verify_code = SSL_get_verify_result(sslsock->ssl); + PySSL_UNLOCK(sslsock); verify_code_obj = PyLong_FromLong(verify_code); if (verify_code_obj == NULL) { goto fail; @@ -616,6 +637,7 @@ PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno) _sslmodulestate *state = get_state_sock(sslsock); type = state->PySSLErrorObject; + // XXX Are ERR functions thread-safe? e = ERR_peek_last_error(); if (sslsock->ssl != NULL) { @@ -859,6 +881,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, #undef SID_CTX } + PySSL_LOCK(self); /* bpo43522 and OpenSSL < 1.1.1l: copy hostflags manually */ #if OPENSSL_VERSION < 0x101010cf X509_VERIFY_PARAM *ssl_params = SSL_get0_param(self->ssl); @@ -895,6 +918,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, } } #endif + PySSL_UNLOCK(self); if (server_hostname != NULL) { if (_ssl_configure_hostname(self, server_hostname) < 0) { @@ -906,15 +930,19 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, * to non-blocking mode (blocking is the default) */ if (sock && sock->sock_timeout >= 0) { + PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), 1); BIO_set_nbio(SSL_get_wbio(self->ssl), 1); + PySSL_UNLOCK(self); } PySSL_BEGIN_ALLOW_THREADS + PySSL_LOCK(self); if (socket_type == PY_SSL_CLIENT) SSL_set_connect_state(self->ssl); else SSL_set_accept_state(self->ssl); + PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS self->socket_type = socket_type; @@ -984,8 +1012,10 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ do { PySSL_BEGIN_ALLOW_THREADS + PySSL_LOCK(self); ret = SSL_do_handshake(self->ssl); err = _PySSL_errno(ret < 1, self->ssl, ret); + PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS self->err = err; @@ -1843,12 +1873,15 @@ _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) X509 *peer_cert; PyObject *result; + PySSL_LOCK(self); if (!SSL_is_init_finished(self->ssl)) { + PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "handshake not done yet"); return NULL; } peer_cert = SSL_get_peer_certificate(self->ssl); + PySSL_UNLOCK(self); if (peer_cert == NULL) Py_RETURN_NONE; @@ -1856,7 +1889,9 @@ _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) /* return cert in DER-encoded format */ result = _certificate_to_der(get_state_sock(self), peer_cert); } else { + PySSL_LOCK(self); verification = SSL_CTX_get_verify_mode(SSL_get_SSL_CTX(self->ssl)); + PySSL_UNLOCK(self); if ((verification & SSL_VERIFY_PEER) == 0) result = PyDict_New(); else @@ -1895,7 +1930,9 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) PyObject *retval; /* borrowed reference */ /* TODO: include SSL_get_peer_certificate() for server-side sockets */ + PySSL_LOCK(self); STACK_OF(X509) *chain = SSL_get_peer_cert_chain(self->ssl); + PySSL_UNLOCK(self); if (chain == NULL) { Py_RETURN_NONE; } @@ -1906,7 +1943,9 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) /* OpenSSL does not include peer cert for server side connections */ if (self->socket_type == PY_SSL_SERVER) { PyObject *peerobj = NULL; + PySSL_LOCK(self); X509 *peer = SSL_get_peer_certificate(self->ssl); + PySSL_UNLOCK(self); if (peer == NULL) { peerobj = Py_NewRef(Py_None); @@ -2041,10 +2080,14 @@ _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) done so, if the buffer is too small. */ + PySSL_LOCK(self); server_ciphers = SSL_get_ciphers(self->ssl); + PySSL_UNLOCK(self); if (!server_ciphers) Py_RETURN_NONE; + PySSL_LOCK(self); client_ciphers = SSL_get_client_ciphers(self->ssl); + PySSL_UNLOCK(self); if (!client_ciphers) Py_RETURN_NONE; @@ -2080,7 +2123,9 @@ _ssl__SSLSocket_cipher_impl(PySSLSocket *self) if (self->ssl == NULL) Py_RETURN_NONE; + PySSL_LOCK(self); current = SSL_get_current_cipher(self->ssl); + PySSL_UNLOCK(self); if (current == NULL) Py_RETURN_NONE; return cipher_to_tuple(current); @@ -2098,11 +2143,16 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self) if (self->ssl == NULL) Py_RETURN_NONE; + PySSL_LOCK(self); if (!SSL_is_init_finished(self->ssl)) { + PySSL_UNLOCK(self); /* handshake not finished */ Py_RETURN_NONE; } + + PySSL_LOCK(self); version = SSL_get_version(self->ssl); + PySSL_UNLOCK(self); if (!strcmp(version, "unknown")) Py_RETURN_NONE; return PyUnicode_FromString(version); @@ -2119,7 +2169,9 @@ _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self) const unsigned char *out; unsigned int outlen; + PySSL_LOCK(self); SSL_get0_alpn_selected(self->ssl, &out, &outlen); + PySSL_UNLOCK(self); if (out == NULL) Py_RETURN_NONE; @@ -2142,7 +2194,9 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self) if (self->ssl == NULL) Py_RETURN_NONE; + PySSL_LOCK(self); comp_method = SSL_get_current_compression(self->ssl); + PySSL_UNLOCK(self) if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef) Py_RETURN_NONE; short_name = OBJ_nid2sn(COMP_get_type(comp_method)); @@ -2161,12 +2215,14 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value, if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) { Py_SETREF(self->ctx, (PySSLContext *)Py_NewRef(value)); + PySSL_LOCK(self); SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); /* Set SSL* internal msg_callback to state of new context's state */ SSL_set_msg_callback( self->ssl, self->ctx->msg_cb ? _PySSL_msg_callback : NULL ); + PySSL_UNLOCK(self); } else { PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext"); return -1; @@ -2261,8 +2317,10 @@ PySSL_dealloc(PySSLSocket *self) // // See elaborate explanation at // https://github.com/python/cpython/pull/123249#discussion_r1766164530 + PySSL_LOCK(self); SSL_set_shutdown(self->ssl, SSL_SENT_SHUTDOWN | SSL_get_shutdown(self->ssl)); SSL_free(self->ssl); + PySSL_UNLOCK(self); } Py_XDECREF(self->Socket); Py_XDECREF(self->ctx); @@ -2405,7 +2463,9 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) do { PySSL_BEGIN_ALLOW_THREADS + PySSL_LOCK(self); retval = SSL_write_ex(self->ssl, b->buf, (size_t)b->len, &count); + PySSL_UNLOCK(self); err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS self->err = err; @@ -2465,7 +2525,9 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) _PySSLError err; PySSL_BEGIN_ALLOW_THREADS + PySSL_LOCK(self); count = SSL_pending(self->ssl); + PySSL_UNLOCK(self); err = _PySSL_errno(count < 0, self->ssl, count); PySSL_END_ALLOW_THREADS self->err = err; @@ -2547,8 +2609,10 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, if (sock != NULL) { /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); + PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -2558,7 +2622,9 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, do { PySSL_BEGIN_ALLOW_THREADS + PySSL_LOCK(self); retval = SSL_read_ex(self->ssl, mem, (size_t)len, &count); + PySSL_UNLOCK(self); err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS self->err = err; @@ -2647,8 +2713,10 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) /* Just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); + PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -2667,9 +2735,11 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) * function is used and the shutdown_seen_zero != 0 * condition is met. */ + PySSL_LOCK(self); if (self->shutdown_seen_zero) SSL_set_read_ahead(self->ssl, 0); ret = SSL_shutdown(self->ssl); + PySSL_UNLOCK(self); err = _PySSL_errno(ret < 0, self->ssl, ret); PySSL_END_ALLOW_THREADS self->err = err; @@ -2757,6 +2827,7 @@ _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, size_t len; if (strcmp(cb_type, "tls-unique") == 0) { + PySSL_LOCK(self); if (SSL_session_reused(self->ssl) ^ !self->socket_type) { /* if session is resumed XOR we are the client */ len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN); @@ -2765,6 +2836,7 @@ _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, /* if a new session XOR we are the server */ len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN); } + PySSL_UNLOCK(self); } else { PyErr_Format( @@ -2793,7 +2865,9 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) /*[clinic end generated code: output=532147f3b1341425 input=6bfa874810a3d889]*/ { #if defined(PySSL_HAVE_POST_HS_AUTH) + PySSL_LOCK(self); int err = SSL_verify_client_post_handshake(self->ssl); + PySSL_UNLOCK(self); if (err == 0) return _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); else @@ -2813,12 +2887,16 @@ PySSL_get_session(PySSLSocket *self, void *closure) { PySSLSession *pysess; SSL_SESSION *session; + PySSL_LOCK(self); session = SSL_get1_session(self->ssl); + PySSL_UNLOCK(self); if (session == NULL) { Py_RETURN_NONE; } pysess = PyObject_GC_New(PySSLSession, self->ctx->state->PySSLSession_Type); if (pysess == NULL) { + // It's not possible for another thread to access this, so + // we don't need to lock it. SSL_SESSION_free(session); return NULL; } @@ -2850,15 +2928,20 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, "Cannot set session for server-side SSLSocket."); return -1; } + PySSL_LOCK(self); if (SSL_is_init_finished(self->ssl)) { + PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "Cannot set session after handshake."); return -1; } + if (SSL_set_session(self->ssl, pysess->session) == 0) { + PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); return -1; } + PySSL_UNLOCK(self); return 0; } @@ -2869,11 +2952,10 @@ Get / set SSLSession."); static PyObject * PySSL_get_session_reused(PySSLSocket *self, void *closure) { - if (SSL_session_reused(self->ssl)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } + PySSL_LOCK(self); + int res = SSL_session_reused(self->ssl); + PySSL_UNLOCK(self); + return res ? Py_True : Py_False; } PyDoc_STRVAR(PySSL_get_session_reused_doc, @@ -2959,7 +3041,9 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n) /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for * server sockets and SSL_set_post_handshake_auth() for client. */ + PySSL_LOCK(self); SSL_CTX_set_verify(self->ctx, mode, NULL); + PySSL_UNLOCK(self); return 0; } @@ -3042,6 +3126,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) return NULL; } + // This is the constructor, no need to lock it. PySSL_BEGIN_ALLOW_THREADS ctx = SSL_CTX_new(method); PySSL_END_ALLOW_THREADS @@ -3244,12 +3329,16 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self) int i=0; PyObject *result = NULL, *dct; + PySSL_LOCK(self); ssl = SSL_new(self->ctx); + PySSL_UNLOCK(self); if (ssl == NULL) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); goto exit; } + PySSL_LOCK(self); sk = SSL_get_ciphers(ssl); + PySSL_UNLOCK(self); result = PyList_New(sk_SSL_CIPHER_num(sk)); if (result == NULL) { @@ -3334,9 +3423,13 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, memcpy(self->alpn_protocols, protos->buf, protos->len); self->alpn_protocols_len = (unsigned int)protos->len; - if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) + PySSL_LOCK(self); + if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) { + PySSL_UNLOCK(self); return PyErr_NoMemory(); + } SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); + PySSL_UNLOCK(self); Py_RETURN_NONE; } @@ -3381,7 +3474,9 @@ get_verify_flags(PySSLContext *self, void *c) X509_VERIFY_PARAM *param; unsigned long flags; + PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); + PySSL_UNLOCK(self); flags = X509_VERIFY_PARAM_get_flags(param); return PyLong_FromUnsignedLong(flags); } @@ -3394,7 +3489,9 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) if (!PyArg_Parse(arg, "k", &new_flags)) return -1; + PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); + PySSL_UNLOCK(self); flags = X509_VERIFY_PARAM_get_flags(param); clear = flags & ~new_flags; set = ~flags & new_flags; @@ -3476,7 +3573,9 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) default: break; } + PySSL_LOCK(self); result = SSL_CTX_set_min_proto_version(self->ctx, v); + PySSL_UNLOCK(self); } else { switch(v) { @@ -3490,7 +3589,9 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) default: break; } + PySSL_LOCK(self); result = SSL_CTX_set_max_proto_version(self->ctx, v); + PySSL_UNLOCK(self); } if (result == 0) { PyErr_Format(PyExc_ValueError, @@ -3503,7 +3604,9 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) static PyObject * get_minimum_version(PySSLContext *self, void *c) { + PySSL_LOCK(self); int v = SSL_CTX_get_min_proto_version(self->ctx); + PySSL_UNLOCK(self); if (v == 0) { v = PY_PROTO_MINIMUM_SUPPORTED; } @@ -3519,7 +3622,9 @@ set_minimum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_maximum_version(PySSLContext *self, void *c) { + PySSL_LOCK(self); int v = SSL_CTX_get_max_proto_version(self->ctx); + PySSL_UNLOCK(self); if (v == 0) { v = PY_PROTO_MAXIMUM_SUPPORTED; } @@ -3536,7 +3641,10 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_num_tickets(PySSLContext *self, void *c) { - return PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); + PySSL_LOCK(self); + PyObject *res = PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); + PySSL_UNLOCK(self); + return res; } static int @@ -3554,10 +3662,13 @@ set_num_tickets(PySSLContext *self, PyObject *arg, void *c) "SSLContext is not a server context."); return -1; } + PySSL_LOCK(self); if (SSL_CTX_set_num_tickets(self->ctx, num) != 1) { + PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "failed to set num tickets."); return -1; } + PySSL_UNLOCK(self); return 0; } @@ -3568,14 +3679,19 @@ PyDoc_STRVAR(PySSLContext_num_tickets_doc, static PyObject * get_security_level(PySSLContext *self, void *c) { - return PyLong_FromLong(SSL_CTX_get_security_level(self->ctx)); + PySSL_LOCK(self); + PyObject *res = PyLong_FromLong(SSL_CTX_get_security_level(self->ctx)); + PySSL_UNLOCK(self); + return res; } PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); static PyObject * get_options(PySSLContext *self, void *c) { + PySSL_LOCK(self); uint64_t options = SSL_CTX_get_options(self->ctx); + PySSL_UNLOCK(self); Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(options)); return PyLong_FromUnsignedLongLong(options); } @@ -3601,7 +3717,9 @@ set_options(PySSLContext *self, PyObject *arg, void *c) Py_BUILD_ASSERT(sizeof(new_opts) >= sizeof(new_opts_arg)); new_opts = (uint64_t)new_opts_arg; + PySSL_LOCK(self); opts = SSL_CTX_get_options(self->ctx); + PySSL_UNLOCK(self); clear = opts & ~new_opts; set = ~opts & new_opts; @@ -3611,12 +3729,14 @@ set_options(PySSLContext *self, PyObject *arg, void *c) return -1; } } + PySSL_LOCK(self); if (clear) { SSL_CTX_clear_options(self->ctx, clear); } if (set) { SSL_CTX_set_options(self->ctx, set); } + PySSL_UNLOCK(self); return 0; } @@ -3635,7 +3755,9 @@ set_host_flags(PySSLContext *self, PyObject *arg, void *c) if (!PyArg_Parse(arg, "I", &new_flags)) return -1; + PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); + PySSL_UNLOCK(self); self->hostflags = new_flags; X509_VERIFY_PARAM_set_hostflags(param, new_flags); return 0; @@ -3653,13 +3775,16 @@ set_check_hostname(PySSLContext *self, PyObject *arg, void *c) int check_hostname; if (!PyArg_Parse(arg, "p", &check_hostname)) return -1; + PySSL_LOCK(self); if (check_hostname && SSL_CTX_get_verify_mode(self->ctx) == SSL_VERIFY_NONE) { /* check_hostname = True sets verify_mode = CERT_REQUIRED */ if (_set_verify_mode(self, PY_SSL_CERT_REQUIRED) == -1) { + PySSL_UNLOCK(self); return -1; } } + PySSL_UNLOCK(self); self->check_hostname = check_hostname; return 0; } @@ -3822,8 +3947,10 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, /*[clinic end generated code: output=9480bc1c380e2095 input=30bc7e967ea01a58]*/ { PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; + PySSL_LOCK(self); pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx); + PySSL_UNLOCK(self); _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; int r; @@ -3852,12 +3979,16 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, "password should be a string or callable")) { goto error; } + PySSL_LOCK(self); SSL_CTX_set_default_passwd_cb(self->ctx, _password_callback); SSL_CTX_set_default_passwd_cb_userdata(self->ctx, &pw_info); + PySSL_UNLOCK(self); } PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); + PySSL_LOCK(self); r = SSL_CTX_use_certificate_chain_file(self->ctx, PyBytes_AS_STRING(certfile_bytes)); + PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); if (r != 1) { if (pw_info.error) { @@ -3874,9 +4005,11 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, goto error; } PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); + PySSL_LOCK(self); r = SSL_CTX_use_PrivateKey_file(self->ctx, PyBytes_AS_STRING(keyfile ? keyfile_bytes : certfile_bytes), SSL_FILETYPE_PEM); + PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); Py_CLEAR(keyfile_bytes); Py_CLEAR(certfile_bytes); @@ -3895,20 +4028,26 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, goto error; } PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); + PySSL_LOCK(self); r = SSL_CTX_check_private_key(self->ctx); + PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); if (r != 1) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); goto error; } + PySSL_LOCK(self); SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); + PySSL_UNLOCK(self); PyMem_Free(pw_info.password); Py_RETURN_NONE; error: + PySSL_LOCK(self); SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); + PySSL_UNLOCK(self); PyMem_Free(pw_info.password); Py_XDECREF(keyfile_bytes); Py_XDECREF(certfile_bytes); @@ -3943,7 +4082,9 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, return -1; } + PySSL_LOCK(self); store = SSL_CTX_get_cert_store(self->ctx); + PySSL_UNLOCK(self); assert(store != NULL); while (1) { @@ -3957,15 +4098,19 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, } cert = d2i_X509_bio(biobuf, NULL); } else { + PySSL_LOCK(self); cert = PEM_read_bio_X509(biobuf, NULL, SSL_CTX_get_default_passwd_cb(self->ctx), SSL_CTX_get_default_passwd_cb_userdata(self->ctx) ); + PySSL_UNLOCK(self); } if (cert == NULL) { break; } + PySSL_LOCK(self); r = X509_STORE_add_cert(store, cert); + PySSL_UNLOCK(self); X509_free(cert); if (!r) { err = ERR_peek_last_error(); @@ -4113,7 +4258,9 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, if (capath) capath_buf = PyBytes_AS_STRING(capath_bytes); PySSL_BEGIN_ALLOW_THREADS + PySSL_LOCK(self); r = SSL_CTX_load_verify_locations(self->ctx, cafile_buf, capath_buf); + PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS if (r != 1) { if (errno != 0) { @@ -4173,10 +4320,13 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) } return NULL; } + PySSL_LOCK(self); if (!SSL_CTX_set_tmp_dh(self->ctx, dh)) { + PySSL_UNLOCK(self); DH_free(dh); return _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); } + PySSL_UNLOCK(self); DH_free(dh); Py_RETURN_NONE; } @@ -4276,6 +4426,7 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self) if (r < 0) \ goto error; + PySSL_LOCK(self); ADD_STATS(number, "number"); ADD_STATS(connect, "connect"); ADD_STATS(connect_good, "connect_good"); @@ -4288,6 +4439,7 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self) ADD_STATS(misses, "misses"); ADD_STATS(timeouts, "timeouts"); ADD_STATS(cache_full, "cache_full"); + PySSL_UNLOCK(self); #undef ADD_STATS @@ -4308,7 +4460,9 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) { int rc; Py_BEGIN_ALLOW_THREADS + PySSL_LOCK(self); rc = SSL_CTX_set_default_verify_paths(self->ctx); + PySSL_UNLOCK(self); Py_END_ALLOW_THREADS if (!rc) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -4346,13 +4500,18 @@ _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } + PySSL_LOCK(self); SSL_CTX_set_tmp_ecdh(self->ctx, key); + PySSL_UNLOCK(self); EC_KEY_free(key); #else + PySSL_LOCK(self); if (!SSL_CTX_set1_groups(self->ctx, &nid, 1)) { + PySSL_UNLOCK(self); _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } + PySSL_UNLOCK(self); #endif Py_RETURN_NONE; } @@ -4480,18 +4639,24 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) } Py_CLEAR(self->set_sni_cb); if (arg == Py_None) { + PySSL_LOCK(self); SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); + PySSL_UNLOCK(self); } else { if (!PyCallable_Check(arg)) { + PySSL_LOCK(self); SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); + PySSL_UNLOCK(self); PyErr_SetString(PyExc_TypeError, "not a callable object"); return -1; } self->set_sni_cb = Py_NewRef(arg); + PySSL_LOCK(self); SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); SSL_CTX_set_tlsext_servername_arg(self->ctx, self); + PySSL_UNLOCK(self); } return 0; } @@ -4568,14 +4733,17 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) X509_OBJECT *obj; int x509 = 0, crl = 0, ca = 0, i; + PySSL_LOCK(self); store = SSL_CTX_get_cert_store(self->ctx); objs = X509_STORE_get1_objects(store); + PySSL_UNLOCK(self); if (objs == NULL) { PyErr_SetString(PyExc_MemoryError, "failed to query cert store"); return NULL; } for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { + PySSL_LOCK(self); obj = sk_X509_OBJECT_value(objs, i); switch (X509_OBJECT_get_type(obj)) { case X509_LU_X509: @@ -4591,8 +4759,11 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) /* Ignore unrecognized types. */ break; } + PySSL_UNLOCK(self); } + PySSL_LOCK(self); sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free); + PySSL_UNLOCK(self); return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl, "x509_ca", ca); } @@ -4623,8 +4794,10 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) return NULL; } + PySSL_LOCK(self); store = SSL_CTX_get_cert_store(self->ctx); objs = X509_STORE_get1_objects(store); + PySSL_UNLOCK(self); if (objs == NULL) { PyErr_SetString(PyExc_MemoryError, "failed to query cert store"); goto error; @@ -4634,16 +4807,20 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) X509_OBJECT *obj; X509 *cert; + PySSL_LOCK(self); obj = sk_X509_OBJECT_value(objs, i); if (X509_OBJECT_get_type(obj) != X509_LU_X509) { /* not a x509 cert */ + PySSL_UNLOCK(self); continue; } /* CA for any purpose */ cert = X509_OBJECT_get0_X509(obj); if (!X509_check_ca(cert)) { + PySSL_UNLOCK(self); continue; } + PySSL_UNLOCK(self); if (binary_form) { ci = _certificate_to_der(get_state_ctx(self), cert); } else { @@ -4657,11 +4834,15 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) } Py_CLEAR(ci); } + PySSL_LOCK(self); sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free); + PySSL_UNLOCK(self); return rlist; error: + PySSL_LOCK(self); sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free); + PySSL_UNLOCK(self); Py_XDECREF(ci); Py_XDECREF(rlist); return NULL; @@ -4773,7 +4954,9 @@ _ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self, Py_XINCREF(callback); self->psk_client_callback = callback; + PySSL_LOCK(self); SSL_CTX_set_psk_client_callback(self->ctx, ssl_callback); + PySSL_UNLOCK(self); Py_RETURN_NONE; #else @@ -4880,16 +5063,21 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, ssl_callback = psk_server_callback; } + PySSL_LOCK(self); if (SSL_CTX_use_psk_identity_hint(self->ctx, identity_hint) != 1) { + PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "failed to set identity hint"); return NULL; } + PySSL_UNLOCK(self); Py_XDECREF(self->psk_server_callback); Py_XINCREF(callback); self->psk_server_callback = callback; + PySSL_LOCK(self); SSL_CTX_set_psk_server_callback(self->ctx, ssl_callback); + PySSL_UNLOCK(self); Py_RETURN_NONE; #else @@ -5037,7 +5225,10 @@ memory_bio_dealloc(PySSLMemoryBIO *self) static PyObject * memory_bio_get_pending(PySSLMemoryBIO *self, void *c) { - return PyLong_FromSize_t(BIO_ctrl_pending(self->bio)); + PySSL_LOCK(self); + PyObject *res = PyLong_FromSize_t(BIO_ctrl_pending(self->bio)); + PySSL_UNLOCK(self); + return res; } PyDoc_STRVAR(PySSL_memory_bio_pending_doc, @@ -5046,8 +5237,11 @@ PyDoc_STRVAR(PySSL_memory_bio_pending_doc, static PyObject * memory_bio_get_eof(PySSLMemoryBIO *self, void *c) { - return PyBool_FromLong((BIO_ctrl_pending(self->bio) == 0) + PySSL_LOCK(self); + PyObject *res = PyBool_FromLong((BIO_ctrl_pending(self->bio) == 0) && self->eof_written); + PySSL_UNLOCK(self); + return res; } PyDoc_STRVAR(PySSL_memory_bio_eof_doc, @@ -5073,7 +5267,9 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) int avail, nbytes; PyObject *result; + PySSL_LOCK(self); avail = (int)Py_MIN(BIO_ctrl_pending(self->bio), INT_MAX); + PySSL_UNLOCK(self); if ((len < 0) || (len > avail)) len = avail; @@ -5081,7 +5277,9 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) if ((result == NULL) || (len == 0)) return result; + PySSL_LOCK(self); nbytes = BIO_read(self->bio, PyBytes_AS_STRING(result), len); + PySSL_UNLOCK(self); if (nbytes < 0) { _sslmodulestate *state = get_state_mbio(self); Py_DECREF(result); @@ -5128,7 +5326,9 @@ _ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) return NULL; } + PySSL_LOCK(self); nbytes = BIO_write(self->bio, b->buf, (int)b->len); + PySSL_UNLOCK(self); if (nbytes < 0) { _sslmodulestate *state = get_state_mbio(self); _setSSLError(state, NULL, 0, __FILE__, __LINE__); @@ -5153,8 +5353,10 @@ _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) self->eof_written = 1; /* After an EOF is written, a zero return from read() should be a real EOF * i.e. it should not be retried. Clear the SHOULD_RETRY flag. */ + PySSL_LOCK(self); BIO_clear_retry_flags(self->bio); BIO_set_mem_eof_return(self->bio, 0); + PySSL_UNLOCK(self); Py_RETURN_NONE; } @@ -5229,10 +5431,14 @@ PySSLSession_richcompare(PyObject *left, PyObject *right, int op) } else { const unsigned char *left_id, *right_id; unsigned int left_len, right_len; + PySSL_LOCK(left); left_id = SSL_SESSION_get_id(((PySSLSession *)left)->session, &left_len); + PySSL_UNLOCK(left); + PySSL_LOCK(right); right_id = SSL_SESSION_get_id(((PySSLSession *)right)->session, &right_len); + PySSL_UNLOCK(right); if (left_len == right_len) { result = memcmp(left_id, right_id, left_len); } else { @@ -5285,11 +5491,14 @@ PySSLSession_clear(PySSLSession *self) static PyObject * PySSLSession_get_time(PySSLSession *self, void *closure) { + PySSL_LOCK(self); #if OPENSSL_VERSION_NUMBER >= 0x30300000L - return _PyLong_FromTime_t(SSL_SESSION_get_time_ex(self->session)); + PyObject *res = _PyLong_FromTime_t(SSL_SESSION_get_time_ex(self->session)); #else - return PyLong_FromLong(SSL_SESSION_get_time(self->session)); + PyObject *res = PyLong_FromLong(SSL_SESSION_get_time(self->session)); #endif + PySSL_UNLOCK(self); + return res; } PyDoc_STRVAR(PySSLSession_get_time_doc, @@ -5298,7 +5507,10 @@ PyDoc_STRVAR(PySSLSession_get_time_doc, static PyObject * PySSLSession_get_timeout(PySSLSession *self, void *closure) { - return PyLong_FromLong(SSL_SESSION_get_timeout(self->session)); + PySSL_LOCK(self); + PyObject *res = PyLong_FromLong(SSL_SESSION_get_timeout(self->session)); + PySSL_UNLOCK(self); + return res; } PyDoc_STRVAR(PySSLSession_get_timeout_doc, @@ -5307,7 +5519,9 @@ PyDoc_STRVAR(PySSLSession_get_timeout_doc, static PyObject * PySSLSession_get_ticket_lifetime_hint(PySSLSession *self, void *closure) { + PySSL_LOCK(self); unsigned long hint = SSL_SESSION_get_ticket_lifetime_hint(self->session); + PySSL_UNLOCK(self); return PyLong_FromUnsignedLong(hint); } @@ -5319,7 +5533,9 @@ static PyObject * PySSLSession_get_session_id(PySSLSession *self, void *closure) { const unsigned char *id; unsigned int len; + PySSL_LOCK(self); id = SSL_SESSION_get_id(self->session, &len); + PySSL_UNLOCK(self); return PyBytes_FromStringAndSize((const char *)id, len); } @@ -5329,11 +5545,10 @@ PyDoc_STRVAR(PySSLSession_get_session_id_doc, static PyObject * PySSLSession_get_has_ticket(PySSLSession *self, void *closure) { - if (SSL_SESSION_has_ticket(self->session)) { - Py_RETURN_TRUE; - } else { - Py_RETURN_FALSE; - } + PySSL_LOCK(self); + int res = SSL_SESSION_has_ticket(self->session); + PySSL_UNLOCK(self); + return res ? Py_True : Py_False; } PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, From 572e48f71830d96a85d5b38c12db48ae06d0c135 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:25:12 -0400 Subject: [PATCH 02/59] Fix silly syntax errors. --- Modules/_ssl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index ced5513880438c..e1d15b9e74f19a 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -52,8 +52,8 @@ #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } #ifdef Py_GIL_DISABLED -#define PySSL_LOCK(obj) PyMutex_Lock(obj->lock) -#define PySSL_UNLOCK(obj) PyMutex_Unlock(obj->lock) +#define PySSL_LOCK(obj) PyMutex_Lock(&(obj)->lock) +#define PySSL_UNLOCK(obj) PyMutex_Unlock(&(obj)->lock) #else #define PySSL_LOCK(obj) #define PySSL_UNLOCK(obj) @@ -2196,7 +2196,7 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self) Py_RETURN_NONE; PySSL_LOCK(self); comp_method = SSL_get_current_compression(self->ssl); - PySSL_UNLOCK(self) + PySSL_UNLOCK(self); if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef) Py_RETURN_NONE; short_name = OBJ_nid2sn(COMP_get_type(comp_method)); @@ -5431,14 +5431,14 @@ PySSLSession_richcompare(PyObject *left, PyObject *right, int op) } else { const unsigned char *left_id, *right_id; unsigned int left_len, right_len; - PySSL_LOCK(left); + PySSL_LOCK((PySSLSession *)left); left_id = SSL_SESSION_get_id(((PySSLSession *)left)->session, &left_len); - PySSL_UNLOCK(left); - PySSL_LOCK(right); + PySSL_UNLOCK((PySSLSession *)left); + PySSL_LOCK((PySSLSession *)right); right_id = SSL_SESSION_get_id(((PySSLSession *)right)->session, &right_len); - PySSL_UNLOCK(right); + PySSL_UNLOCK((PySSLSession *)right); if (left_len == right_len) { result = memcmp(left_id, right_id, left_len); } else { From b0cd005f287af0823d79f02708674ab8a460b658 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:28:40 -0400 Subject: [PATCH 03/59] Fix thread safety for set_alpn_protocols --- Modules/_ssl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index e1d15b9e74f19a..a77bacf3e4a082 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3416,14 +3416,15 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, return NULL; } + PySSL_LOCK(self); PyMem_Free(self->alpn_protocols); self->alpn_protocols = PyMem_Malloc(protos->len); - if (!self->alpn_protocols) + if (!self->alpn_protocols) { + PySSL_UNLOCK(self); return PyErr_NoMemory(); + } memcpy(self->alpn_protocols, protos->buf, protos->len); self->alpn_protocols_len = (unsigned int)protos->len; - - PySSL_LOCK(self); if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) { PySSL_UNLOCK(self); return PyErr_NoMemory(); From 0629acdc786eea8bdd01869fff7da9daca72cb0a Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:30:42 -0400 Subject: [PATCH 04/59] Fix thread safety for configure_hostname --- Modules/_ssl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a77bacf3e4a082..f1a652cd6006dd 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -788,30 +788,39 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) if (hostname == NULL) { goto error; } + PySSL_LOCK(self); self->server_hostname = hostname; + PySSL_UNLOCK(self); /* Only send SNI extension for non-IP hostnames */ if (ip == NULL) { + PySSL_LOCK(self); if (!SSL_set_tlsext_host_name(self->ssl, server_hostname)) { + PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } + PySSL_UNLOCK(self); } if (self->ctx->check_hostname) { + PySSL_LOCK(self); X509_VERIFY_PARAM *param = SSL_get0_param(self->ssl); if (ip == NULL) { if (!X509_VERIFY_PARAM_set1_host(param, server_hostname, strlen(server_hostname))) { + PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } } else { if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), ASN1_STRING_length(ip))) { + PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } } + PySSL_UNLOCK(self); } retval = 0; error: From 3712d0558c5303e2a0cf962b61629873ef15eed1 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:36:20 -0400 Subject: [PATCH 05/59] Make some more operations atomic. --- Modules/_ssl.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f1a652cd6006dd..d1cd1d53d439a3 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1007,8 +1007,10 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); + PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -1920,7 +1922,9 @@ _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self) /*[clinic end generated code: output=802421163cdc3110 input=5fb0714f77e2bd51]*/ { /* borrowed reference */ + PySSL_LOCK(self); STACK_OF(X509) *chain = SSL_get0_verified_chain(self->ssl); + PySSL_UNLOCK(self); if (chain == NULL) { Py_RETURN_NONE; } @@ -2445,8 +2449,10 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) if (sock != NULL) { /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); + PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -2477,7 +2483,9 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) PySSL_UNLOCK(self); err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS + PySSL_LOCK(self); self->err = err; + PySSL_UNLOCK(self); if (PyErr_CheckSignals()) goto error; @@ -2539,7 +2547,9 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) PySSL_UNLOCK(self); err = _PySSL_errno(count < 0, self->ssl, count); PySSL_END_ALLOW_THREADS + PySSL_LOCK(self); self->err = err; + PySSL_UNLOCK(self); if (count < 0) return PySSL_SetError(self, __FILE__, __LINE__); @@ -2636,7 +2646,9 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, PySSL_UNLOCK(self); err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS + PySSL_LOCK(self); self->err = err; + PySSL_UNLOCK(self); if (PyErr_CheckSignals()) goto error; @@ -2751,7 +2763,9 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) PySSL_UNLOCK(self); err = _PySSL_errno(ret < 0, self->ssl, ret); PySSL_END_ALLOW_THREADS + PySSL_LOCK(self); self->err = err; + PySSL_UNLOCK(self); /* If err == 1, a secure shutdown with SSL_shutdown() is complete */ if (ret > 0) @@ -2763,7 +2777,9 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) if (++zeros > 1) break; /* Shutdown was sent, now try receiving */ + PySSL_LOCK(self); self->shutdown_seen_zero = 1; + PySSL_UNLOCK(self); continue; } @@ -3311,7 +3327,9 @@ static PyObject * _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) /*[clinic end generated code: output=3a3162f3557c0f3f input=a7ac931b9f3ca7fc]*/ { + PySSL_LOCK(self); int ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); + PySSL_UNLOCK(self); if (ret == 0) { /* Clearing the error queue is necessary on some OpenSSL versions, otherwise the error will be reported again when another SSL call From eb06e05c8b2815e4a25c62f5bf163d5b40e56b87 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:39:06 -0400 Subject: [PATCH 06/59] Fix thread safety with hostnames. --- Modules/_ssl.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index d1cd1d53d439a3..484942a5b34a96 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3468,7 +3468,10 @@ get_verify_mode(PySSLContext *self, void *c) /* ignore SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_POST_HANDSHAKE */ int mask = (SSL_VERIFY_NONE | SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); - switch (SSL_CTX_get_verify_mode(self->ctx) & mask) { + PySSL_LOCK(self); + int verify_mode = SSL_CTX_get_verify_mode(self->ctx); + PySSL_UNLOCK(self); + switch (verify_mode & mask) { case SSL_VERIFY_NONE: return PyLong_FromLong(PY_SSL_CERT_NONE); case SSL_VERIFY_PEER: @@ -3504,8 +3507,8 @@ get_verify_flags(PySSLContext *self, void *c) PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); - PySSL_UNLOCK(self); flags = X509_VERIFY_PARAM_get_flags(param); + PySSL_UNLOCK(self); return PyLong_FromUnsignedLong(flags); } @@ -3519,21 +3522,27 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) return -1; PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); - PySSL_UNLOCK(self); flags = X509_VERIFY_PARAM_get_flags(param); + PySSL_UNLOCK(self); clear = flags & ~new_flags; set = ~flags & new_flags; if (clear) { + PySSL_LOCK(self); if (!X509_VERIFY_PARAM_clear_flags(param, clear)) { + PySSL_UNLOCK(self); _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return -1; } + PySSL_UNLOCK(self); } if (set) { + PySSL_LOCK(self); if (!X509_VERIFY_PARAM_set_flags(param, set)) { + PySSL_UNLOCK(self); _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return -1; } + PySSL_UNLOCK(self); } return 0; } @@ -3785,9 +3794,9 @@ set_host_flags(PySSLContext *self, PyObject *arg, void *c) PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); - PySSL_UNLOCK(self); self->hostflags = new_flags; X509_VERIFY_PARAM_set_hostflags(param, new_flags); + PySSL_UNLOCK(self); return 0; } @@ -3812,8 +3821,8 @@ set_check_hostname(PySSLContext *self, PyObject *arg, void *c) return -1; } } - PySSL_UNLOCK(self); self->check_hostname = check_hostname; + PySSL_UNLOCK(self); return 0; } From 30fce36157e232b02f30558de013b909eea1eee5 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:42:54 -0400 Subject: [PATCH 07/59] Fix thread safety for BIO. --- Modules/_ssl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 484942a5b34a96..8436c7cc9945dd 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -4689,8 +4689,8 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) "not a callable object"); return -1; } - self->set_sni_cb = Py_NewRef(arg); PySSL_LOCK(self); + self->set_sni_cb = Py_NewRef(arg); SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); SSL_CTX_set_tlsext_servername_arg(self->ctx, self); PySSL_UNLOCK(self); @@ -4990,8 +4990,8 @@ _ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self, Py_XDECREF(self->psk_client_callback); Py_XINCREF(callback); - self->psk_client_callback = callback; PySSL_LOCK(self); + self->psk_client_callback = callback; SSL_CTX_set_psk_client_callback(self->ctx, ssl_callback); PySSL_UNLOCK(self); @@ -5111,8 +5111,8 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, Py_XDECREF(self->psk_server_callback); Py_XINCREF(callback); - self->psk_server_callback = callback; PySSL_LOCK(self); + self->psk_server_callback = callback; SSL_CTX_set_psk_server_callback(self->ctx, ssl_callback); PySSL_UNLOCK(self); @@ -5387,10 +5387,10 @@ static PyObject * _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) /*[clinic end generated code: output=d4106276ccd1ed34 input=56a945f1d29e8bd6]*/ { + PySSL_LOCK(self); self->eof_written = 1; /* After an EOF is written, a zero return from read() should be a real EOF * i.e. it should not be retried. Clear the SHOULD_RETRY flag. */ - PySSL_LOCK(self); BIO_clear_retry_flags(self->bio); BIO_set_mem_eof_return(self->bio, 0); PySSL_UNLOCK(self); From 0d63bfbc1f09826fe2bb806ab539c75f2c5cf8e3 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:43:56 -0400 Subject: [PATCH 08/59] Add blurb. --- .../next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst diff --git a/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst b/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst new file mode 100644 index 00000000000000..36d45cedb36477 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst @@ -0,0 +1 @@ +Fixed thread safety in :mod:`ssl`. From 7268ebb615ce94f403707023c787bce192db6d5d Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 22:56:30 -0400 Subject: [PATCH 09/59] Add test. --- Lib/test/test_ssl.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 216aa84a8c147b..7ce55a59fa178b 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4,6 +4,7 @@ import unittest import unittest.mock from ast import literal_eval +from threading import Thread from test import support from test.support import import_helper from test.support import os_helper @@ -2800,6 +2801,28 @@ def test_echo(self): 'Cannot create a client socket with a PROTOCOL_TLS_SERVER context', str(e.exception)) + @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful is GIL is disabled") + def test_ssl_in_multiple_threads(self): + # See GH-124984 + threads = [] + + for func in ( + self.test_echo, + self.test_alpn_protocols, + self.test_getpeercert + ): + for num in range(10): + with self.subTest(func=func, num=num): + threads.append(Thread(target=func)) + + for thread in threads: + with self.subTest(thread=thread): + thread.start() + + for thread in threads: + with self.subTest(thread=thread): + thread.join() + def test_getpeercert(self): if support.verbose: sys.stdout.write("\n") From 28004f1a5f732dbaeff41101706d91314eb431a5 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 23:02:11 -0400 Subject: [PATCH 10/59] Fix deadlock. --- Modules/_ssl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 8436c7cc9945dd..0c17b42c7ea171 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2163,7 +2163,6 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self) Py_RETURN_NONE; } - PySSL_LOCK(self); version = SSL_get_version(self->ssl); PySSL_UNLOCK(self); if (!strcmp(version, "unknown")) From caa205acd6e03bb6d41c1c76077c7a6fc7aabf47 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 23:08:38 -0400 Subject: [PATCH 11/59] Remove useless locks in constructor. --- Modules/_ssl.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 0c17b42c7ea171..4c5a298ccbe1d1 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -890,7 +890,6 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, #undef SID_CTX } - PySSL_LOCK(self); /* bpo43522 and OpenSSL < 1.1.1l: copy hostflags manually */ #if OPENSSL_VERSION < 0x101010cf X509_VERIFY_PARAM *ssl_params = SSL_get0_param(self->ssl); @@ -927,7 +926,6 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, } } #endif - PySSL_UNLOCK(self); if (server_hostname != NULL) { if (_ssl_configure_hostname(self, server_hostname) < 0) { @@ -939,19 +937,15 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, * to non-blocking mode (blocking is the default) */ if (sock && sock->sock_timeout >= 0) { - PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), 1); BIO_set_nbio(SSL_get_wbio(self->ssl), 1); - PySSL_UNLOCK(self); } PySSL_BEGIN_ALLOW_THREADS - PySSL_LOCK(self); if (socket_type == PY_SSL_CLIENT) SSL_set_connect_state(self->ssl); else SSL_set_accept_state(self->ssl); - PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS self->socket_type = socket_type; From 578d40adcb61bfbd10883a2a2020d40912a7bcf3 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 23:41:21 -0400 Subject: [PATCH 12/59] Zero-out locks upon initialization. --- Modules/_ssl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 4c5a298ccbe1d1..6eb20bdf6674e2 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -869,6 +869,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->server_hostname = NULL; self->err = err; self->exc = NULL; + self->lock = (PyMutex) { 0 }; /* Make sure the SSL error state is initialized */ ERR_clear_error(); @@ -1019,8 +1020,8 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) PySSL_BEGIN_ALLOW_THREADS PySSL_LOCK(self); ret = SSL_do_handshake(self->ssl); - err = _PySSL_errno(ret < 1, self->ssl, ret); PySSL_UNLOCK(self); + err = _PySSL_errno(ret < 1, self->ssl, ret); PySSL_END_ALLOW_THREADS self->err = err; @@ -2922,6 +2923,7 @@ PySSL_get_session(PySSLSocket *self, void *closure) { assert(self->ctx); pysess->ctx = (PySSLContext*)Py_NewRef(self->ctx); pysess->session = session; + self->lock = (PyMutex) { 0 }; PyObject_GC_Track(pysess); return (PyObject *)pysess; } @@ -5231,6 +5233,7 @@ _ssl_MemoryBIO_impl(PyTypeObject *type) } self->bio = bio; self->eof_written = 0; + self->lock = (PyMutex) { 0 }; return (PyObject *) self; } From c601906ec0b081bfa7c4ff6e988534ad169a6e16 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 23:44:40 -0400 Subject: [PATCH 13/59] Wrap lock initializations with #ifdef Py_GIL_DISABLED --- Modules/_ssl.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 6eb20bdf6674e2..89aa38c8a95248 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -869,7 +869,9 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->server_hostname = NULL; self->err = err; self->exc = NULL; +#ifdef Py_GIL_DISABLED self->lock = (PyMutex) { 0 }; +#endif /* Make sure the SSL error state is initialized */ ERR_clear_error(); @@ -2923,7 +2925,9 @@ PySSL_get_session(PySSLSocket *self, void *closure) { assert(self->ctx); pysess->ctx = (PySSLContext*)Py_NewRef(self->ctx); pysess->session = session; - self->lock = (PyMutex) { 0 }; +#ifdef Py_GIL_DISABLED + pysess->lock = (PyMutex) { 0 }; +#endif PyObject_GC_Track(pysess); return (PyObject *)pysess; } @@ -3175,6 +3179,9 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) self->psk_client_callback = NULL; self->psk_server_callback = NULL; #endif +#ifdef Py_GIL_DISABLED + self->lock = (PyMutex) { 0 }; +#endif /* Don't check host name by default */ if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { @@ -5233,7 +5240,9 @@ _ssl_MemoryBIO_impl(PyTypeObject *type) } self->bio = bio; self->eof_written = 0; +#ifdef Py_GIL_DISABLED self->lock = (PyMutex) { 0 }; +#endif return (PyObject *) self; } From 014a95ac7414ee9988616eb027509a93d8aadae6 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 4 Oct 2024 23:57:08 -0400 Subject: [PATCH 14/59] Fix lock ordering deadlock. --- Modules/_ssl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 89aa38c8a95248..f360099fdd07c9 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3815,14 +3815,16 @@ set_check_hostname(PySSLContext *self, PyObject *arg, void *c) if (!PyArg_Parse(arg, "p", &check_hostname)) return -1; PySSL_LOCK(self); + int verify_mode = check_hostname ? SSL_CTX_get_verify_mode(self->ctx) : 0; + PySSL_UNLOCK(self); if (check_hostname && - SSL_CTX_get_verify_mode(self->ctx) == SSL_VERIFY_NONE) { + verify_mode == SSL_VERIFY_NONE) { /* check_hostname = True sets verify_mode = CERT_REQUIRED */ if (_set_verify_mode(self, PY_SSL_CERT_REQUIRED) == -1) { - PySSL_UNLOCK(self); return -1; } } + PySSL_LOCK(self); self->check_hostname = check_hostname; PySSL_UNLOCK(self); return 0; From ebb8b4064640decd39fa68377e8ac1c578bc1eee Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 00:21:25 -0400 Subject: [PATCH 15/59] Remove lock for do_handshake() --- Modules/_ssl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f360099fdd07c9..b42f8ca430c9bb 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1020,9 +1020,11 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ do { PySSL_BEGIN_ALLOW_THREADS - PySSL_LOCK(self); + // XXX This isn't thread safe anymore, but locking this can cause a + // deadlock if a callback is active (see bpo-43577). I guess this + // isn't a huge problem because people shouldn't be calling + // do_handshake() across multiple threads anyway. ret = SSL_do_handshake(self->ssl); - PySSL_UNLOCK(self); err = _PySSL_errno(ret < 1, self->ssl, ret); PySSL_END_ALLOW_THREADS self->err = err; From a3ff15451fba564e92edfbb112fde80685a37b99 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 00:28:40 -0400 Subject: [PATCH 16/59] Fix typo. --- Lib/test/test_ssl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 7ce55a59fa178b..52fa0131733467 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2801,7 +2801,7 @@ def test_echo(self): 'Cannot create a client socket with a PROTOCOL_TLS_SERVER context', str(e.exception)) - @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful is GIL is disabled") + @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled") def test_ssl_in_multiple_threads(self): # See GH-124984 threads = [] From 591535fd35ea808e5b46669f2a72916c44da83d6 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 00:33:30 -0400 Subject: [PATCH 17/59] Make tests better. --- Lib/test/test_ssl.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 52fa0131733467..6cd9a214e58750 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2809,7 +2809,20 @@ def test_ssl_in_multiple_threads(self): for func in ( self.test_echo, self.test_alpn_protocols, - self.test_getpeercert + self.test_getpeercert, + self.test_crl_check, + self.test_ecc_cert, + self.test_dual_rsa_ecc, + self.test_check_hostname_idn, + self.test_wrong_cert_tls12, + self.test_wrong_cert_tls13, + self.test_rude_shutdown, + self.test_ssl_cert_verify_error, + self.test_starttls, + self.test_socketserver, + self.test_recv_send, + self.test_recv_zero, + self.test_nonblocking_send ): for num in range(10): with self.subTest(func=func, num=num): From 53e6d598a3f8984f93c9d45ef288b1f1aa26d967 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 00:38:02 -0400 Subject: [PATCH 18/59] Fix tests. --- Lib/test/test_ssl.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 6cd9a214e58750..8fb06d213230c0 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -278,11 +278,19 @@ def test_wrap_socket(sock, *, return context.wrap_socket(sock, **kwargs) +USE_SAME_TEST_CONTEXT = False +_TEST_CONTEXT = None + def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): """Create context client_context, server_context, hostname = testing_context() """ + global _TEST_CONTEXT + if USE_SAME_TEST_CONTEXT: + if _TEST_CONTEXT is not None: + return _TEST_CONTEXT + if server_cert == SIGNED_CERTFILE: hostname = SIGNED_CERTFILE_HOSTNAME elif server_cert == SIGNED_CERTFILE2: @@ -300,6 +308,10 @@ def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True): if server_chain: server_context.load_verify_locations(SIGNING_CA) + if USE_SAME_TEST_CONTEXT: + if _TEST_CONTEXT is not None: + _TEST_CONTEXT = client_context, server_context, hostname + return client_context, server_context, hostname @@ -2806,6 +2818,7 @@ def test_ssl_in_multiple_threads(self): # See GH-124984 threads = [] + USE_SAME_TEST_CONTEXT = True for func in ( self.test_echo, self.test_alpn_protocols, @@ -2836,6 +2849,8 @@ def test_ssl_in_multiple_threads(self): with self.subTest(thread=thread): thread.join() + USE_SAME_TEST_CONTEXT = False + def test_getpeercert(self): if support.verbose: sys.stdout.write("\n") From cd047ba0e43c2ca0e9b94400121fd2e1794ce51f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 10:13:47 -0400 Subject: [PATCH 19/59] Fix missing global. --- Lib/test/test_ssl.py | 60 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 8fb06d213230c0..b5d2e7da752a56 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2818,38 +2818,40 @@ def test_ssl_in_multiple_threads(self): # See GH-124984 threads = [] + global USE_SAME_TEST_CONTEXT USE_SAME_TEST_CONTEXT = True - for func in ( - self.test_echo, - self.test_alpn_protocols, - self.test_getpeercert, - self.test_crl_check, - self.test_ecc_cert, - self.test_dual_rsa_ecc, - self.test_check_hostname_idn, - self.test_wrong_cert_tls12, - self.test_wrong_cert_tls13, - self.test_rude_shutdown, - self.test_ssl_cert_verify_error, - self.test_starttls, - self.test_socketserver, - self.test_recv_send, - self.test_recv_zero, - self.test_nonblocking_send - ): - for num in range(10): - with self.subTest(func=func, num=num): - threads.append(Thread(target=func)) - - for thread in threads: - with self.subTest(thread=thread): - thread.start() + try: + for func in ( + self.test_echo, + self.test_alpn_protocols, + self.test_getpeercert, + self.test_crl_check, + self.test_ecc_cert, + self.test_dual_rsa_ecc, + self.test_check_hostname_idn, + self.test_wrong_cert_tls12, + self.test_wrong_cert_tls13, + self.test_rude_shutdown, + self.test_ssl_cert_verify_error, + self.test_starttls, + self.test_socketserver, + self.test_recv_send, + self.test_recv_zero, + self.test_nonblocking_send + ): + for num in range(10): + with self.subTest(func=func, num=num): + threads.append(Thread(target=func)) - for thread in threads: - with self.subTest(thread=thread): - thread.join() + for thread in threads: + with self.subTest(thread=thread): + thread.start() - USE_SAME_TEST_CONTEXT = False + for thread in threads: + with self.subTest(thread=thread): + thread.join() + finally: + USE_SAME_TEST_CONTEXT = False def test_getpeercert(self): if support.verbose: From 3f3715b3567d612ff71cbedac7df44e7c40e1d79 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 10:15:58 -0400 Subject: [PATCH 20/59] Update comment. --- Modules/_ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index b42f8ca430c9bb..f323b280ced529 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -637,7 +637,7 @@ PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno) _sslmodulestate *state = get_state_sock(sslsock); type = state->PySSLErrorObject; - // XXX Are ERR functions thread-safe? + // ERR functions are thread local, no need to lock them. e = ERR_peek_last_error(); if (sslsock->ssl != NULL) { From d8089327a29be27619fb40e5d023d6197252ba9c Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 10:16:05 -0400 Subject: [PATCH 21/59] Update Modules/_ssl.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Modules/_ssl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index b42f8ca430c9bb..a2800e14d64944 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2161,7 +2161,6 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self) /* handshake not finished */ Py_RETURN_NONE; } - version = SSL_get_version(self->ssl); PySSL_UNLOCK(self); if (!strcmp(version, "unknown")) From df26ffe5874b91eec606689a763e8778cf6577a6 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 10:16:11 -0400 Subject: [PATCH 22/59] Update Modules/_ssl.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Modules/_ssl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a2800e14d64944..bc5aee87a01d1e 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -52,11 +52,11 @@ #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } #ifdef Py_GIL_DISABLED -#define PySSL_LOCK(obj) PyMutex_Lock(&(obj)->lock) -#define PySSL_UNLOCK(obj) PyMutex_Unlock(&(obj)->lock) +# define PySSL_LOCK(OBJ) PyMutex_Lock(&(OBJ)->lock) +# define PySSL_UNLOCK(OBJ) PyMutex_Unlock(&(OBJ)->lock) #else -#define PySSL_LOCK(obj) -#define PySSL_UNLOCK(obj) +# define PySSL_LOCK(OBJ) +# define PySSL_UNLOCK(OBJ) #endif #if defined(HAVE_POLL_H) From c8df918ccaca884559007fbb46667a584579f619 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 10:21:59 -0400 Subject: [PATCH 23/59] Don't lock Py* functions. --- Modules/_ssl.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 8b0bffb137b3b3..19ef6cf3ccf57e 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5271,9 +5271,9 @@ static PyObject * memory_bio_get_pending(PySSLMemoryBIO *self, void *c) { PySSL_LOCK(self); - PyObject *res = PyLong_FromSize_t(BIO_ctrl_pending(self->bio)); + size_t res = BIO_ctrl_pending(self->bio); PySSL_UNLOCK(self); - return res; + return PyLong_FromSize_t(res); } PyDoc_STRVAR(PySSL_memory_bio_pending_doc, @@ -5283,10 +5283,9 @@ static PyObject * memory_bio_get_eof(PySSLMemoryBIO *self, void *c) { PySSL_LOCK(self); - PyObject *res = PyBool_FromLong((BIO_ctrl_pending(self->bio) == 0) - && self->eof_written); + size_t pending = BIO_ctrl_pending(self->bio); PySSL_UNLOCK(self); - return res; + return PyBool_FromLong((pending == 0) && self->eof_written); } PyDoc_STRVAR(PySSL_memory_bio_eof_doc, @@ -5536,13 +5535,17 @@ PySSLSession_clear(PySSLSession *self) static PyObject * PySSLSession_get_time(PySSLSession *self, void *closure) { - PySSL_LOCK(self); #if OPENSSL_VERSION_NUMBER >= 0x30300000L - PyObject *res = _PyLong_FromTime_t(SSL_SESSION_get_time_ex(self->session)); + PySSL_LOCK(self); + time_t time = SSL_SESSION_get_time_ex(self->session); + PySSL_UNLOCK(self); + PyObject *res = _PyLong_FromTime_t(time); #else - PyObject *res = PyLong_FromLong(SSL_SESSION_get_time(self->session)); -#endif + PySSL_LOCK(self); + int time = SSL_SESSION_get_time(self->session); PySSL_UNLOCK(self); + PyObject *res = PyLong_FromLong(time); +#endif return res; } @@ -5553,8 +5556,9 @@ PyDoc_STRVAR(PySSLSession_get_time_doc, static PyObject * PySSLSession_get_timeout(PySSLSession *self, void *closure) { PySSL_LOCK(self); - PyObject *res = PyLong_FromLong(SSL_SESSION_get_timeout(self->session)); + long timeout = SSL_SESSION_get_timeout(self->session); PySSL_UNLOCK(self); + PyObject *res = PyLong_FromLong(timeout); return res; } From 23aa4f9418736ad4ccd0087029346fa264f977bf Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 10:41:11 -0400 Subject: [PATCH 24/59] Clarify comment. --- Modules/_ssl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 19ef6cf3ccf57e..07e02372bd76f4 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3151,7 +3151,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) return NULL; } - // This is the constructor, no need to lock it. + // This is the constructor, no need to lock it, because + // no other thread can be touching this object yet. + // (Technically, we can't even lock if we wanted to, as the + // lock hasn't been initialized yet.) PySSL_BEGIN_ALLOW_THREADS ctx = SSL_CTX_new(method); PySSL_END_ALLOW_THREADS From 92d9525c532423de469dfe8ba403d8278b83f9c9 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 11:30:41 -0400 Subject: [PATCH 25/59] Remove useless functions in threaded tests and lower number of threads. --- Lib/test/test_ssl.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index b5d2e7da752a56..ff4f9c26f9dc21 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2826,8 +2826,6 @@ def test_ssl_in_multiple_threads(self): self.test_alpn_protocols, self.test_getpeercert, self.test_crl_check, - self.test_ecc_cert, - self.test_dual_rsa_ecc, self.test_check_hostname_idn, self.test_wrong_cert_tls12, self.test_wrong_cert_tls13, @@ -2839,7 +2837,7 @@ def test_ssl_in_multiple_threads(self): self.test_recv_zero, self.test_nonblocking_send ): - for num in range(10): + for num in range(5): with self.subTest(func=func, num=num): threads.append(Thread(target=func)) From eff01db7028773ddd1e8c0ebe325e8d8a6d008e2 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 11:32:17 -0400 Subject: [PATCH 26/59] Remove more useless functions. --- Lib/test/test_ssl.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index ff4f9c26f9dc21..8283a247ec4f92 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2829,13 +2829,6 @@ def test_ssl_in_multiple_threads(self): self.test_check_hostname_idn, self.test_wrong_cert_tls12, self.test_wrong_cert_tls13, - self.test_rude_shutdown, - self.test_ssl_cert_verify_error, - self.test_starttls, - self.test_socketserver, - self.test_recv_send, - self.test_recv_zero, - self.test_nonblocking_send ): for num in range(5): with self.subTest(func=func, num=num): From f678df136940727a1b9e7948b03c677fc9ee0bdf Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 5 Oct 2024 16:12:22 -0400 Subject: [PATCH 27/59] Add note about thread count --- Lib/test/test_ssl.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 8283a247ec4f92..3453ccde0d414d 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2830,6 +2830,8 @@ def test_ssl_in_multiple_threads(self): self.test_wrong_cert_tls12, self.test_wrong_cert_tls13, ): + # Be careful with the number of threads here. + # Too many can result in failing tests. for num in range(5): with self.subTest(func=func, num=num): threads.append(Thread(target=func)) From e96bf314163c885b89b418c7867eabff0361cfa3 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sun, 6 Oct 2024 20:34:20 -0400 Subject: [PATCH 28/59] Clarify news entry. --- .../next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst b/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst index 36d45cedb36477..dd0a55a6854c25 100644 --- a/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst +++ b/Misc/NEWS.d/next/Library/2024-10-04-22-43-48.gh-issue-124984.xjMv9b.rst @@ -1 +1 @@ -Fixed thread safety in :mod:`ssl`. +Fixed thread safety in :mod:`ssl` in the free-threaded build. OpenSSL operations are now protected by a per-object lock. From 028bb6a5f9cb1f48eea997ef345f6d6284ce56ea Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 7 Oct 2024 18:03:33 -0400 Subject: [PATCH 29/59] Remove lock for deallocator. --- Modules/_ssl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 07e02372bd76f4..6e6acd56d12066 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2327,10 +2327,8 @@ PySSL_dealloc(PySSLSocket *self) // // See elaborate explanation at // https://github.com/python/cpython/pull/123249#discussion_r1766164530 - PySSL_LOCK(self); SSL_set_shutdown(self->ssl, SSL_SENT_SHUTDOWN | SSL_get_shutdown(self->ssl)); SSL_free(self->ssl); - PySSL_UNLOCK(self); } Py_XDECREF(self->Socket); Py_XDECREF(self->ctx); From f578c8e72637732c1d050326eca59fd2f608fbaf Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:12:59 -0400 Subject: [PATCH 30/59] Remove PySSL_LOCK() and PySSL_UNLOCK() --- Modules/_ssl.c | 252 ------------------------------------------------- 1 file changed, 252 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 6e6acd56d12066..b0469276f11c78 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -51,14 +51,6 @@ PySSL_BEGIN_ALLOW_THREADS_S(_save); #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } -#ifdef Py_GIL_DISABLED -# define PySSL_LOCK(OBJ) PyMutex_Lock(&(OBJ)->lock) -# define PySSL_UNLOCK(OBJ) PyMutex_Unlock(&(OBJ)->lock) -#else -# define PySSL_LOCK(OBJ) -# define PySSL_UNLOCK(OBJ) -#endif - #if defined(HAVE_POLL_H) #include #elif defined(HAVE_SYS_POLL_H) @@ -317,9 +309,6 @@ typedef struct { PyObject *psk_client_callback; PyObject *psk_server_callback; #endif -#ifdef Py_GIL_DISABLED - PyMutex lock; -#endif } PySSLContext; typedef struct { @@ -345,27 +334,18 @@ typedef struct { * and shutdown methods check for chained exceptions. */ PyObject *exc; -#ifdef Py_GIL_DISABLED - PyMutex lock; -#endif } PySSLSocket; typedef struct { PyObject_HEAD BIO *bio; int eof_written; -#ifdef Py_GIL_DISABLED - PyMutex lock; -#endif } PySSLMemoryBIO; typedef struct { PyObject_HEAD SSL_SESSION *session; PySSLContext *ctx; -#ifdef Py_GIL_DISABLED - PyMutex lock; -#endif } PySSLSession; static inline _PySSLError _PySSL_errno(int failed, const SSL *ssl, int retcode) @@ -528,9 +508,7 @@ fill_and_set_sslerror(_sslmodulestate *state, const char *verify_str = NULL; long verify_code; - PySSL_LOCK(sslsock); verify_code = SSL_get_verify_result(sslsock->ssl); - PySSL_UNLOCK(sslsock); verify_code_obj = PyLong_FromLong(verify_code); if (verify_code_obj == NULL) { goto fail; @@ -788,39 +766,30 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) if (hostname == NULL) { goto error; } - PySSL_LOCK(self); self->server_hostname = hostname; - PySSL_UNLOCK(self); /* Only send SNI extension for non-IP hostnames */ if (ip == NULL) { - PySSL_LOCK(self); if (!SSL_set_tlsext_host_name(self->ssl, server_hostname)) { - PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } - PySSL_UNLOCK(self); } if (self->ctx->check_hostname) { - PySSL_LOCK(self); X509_VERIFY_PARAM *param = SSL_get0_param(self->ssl); if (ip == NULL) { if (!X509_VERIFY_PARAM_set1_host(param, server_hostname, strlen(server_hostname))) { - PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } } else { if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), ASN1_STRING_length(ip))) { - PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); goto error; } } - PySSL_UNLOCK(self); } retval = 0; error: @@ -869,9 +838,6 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->server_hostname = NULL; self->err = err; self->exc = NULL; -#ifdef Py_GIL_DISABLED - self->lock = (PyMutex) { 0 }; -#endif /* Make sure the SSL error state is initialized */ ERR_clear_error(); @@ -1004,10 +970,8 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); - PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -1883,15 +1847,12 @@ _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) X509 *peer_cert; PyObject *result; - PySSL_LOCK(self); if (!SSL_is_init_finished(self->ssl)) { - PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "handshake not done yet"); return NULL; } peer_cert = SSL_get_peer_certificate(self->ssl); - PySSL_UNLOCK(self); if (peer_cert == NULL) Py_RETURN_NONE; @@ -1899,9 +1860,7 @@ _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) /* return cert in DER-encoded format */ result = _certificate_to_der(get_state_sock(self), peer_cert); } else { - PySSL_LOCK(self); verification = SSL_CTX_get_verify_mode(SSL_get_SSL_CTX(self->ssl)); - PySSL_UNLOCK(self); if ((verification & SSL_VERIFY_PEER) == 0) result = PyDict_New(); else @@ -1921,9 +1880,7 @@ _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self) /*[clinic end generated code: output=802421163cdc3110 input=5fb0714f77e2bd51]*/ { /* borrowed reference */ - PySSL_LOCK(self); STACK_OF(X509) *chain = SSL_get0_verified_chain(self->ssl); - PySSL_UNLOCK(self); if (chain == NULL) { Py_RETURN_NONE; } @@ -1942,9 +1899,7 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) PyObject *retval; /* borrowed reference */ /* TODO: include SSL_get_peer_certificate() for server-side sockets */ - PySSL_LOCK(self); STACK_OF(X509) *chain = SSL_get_peer_cert_chain(self->ssl); - PySSL_UNLOCK(self); if (chain == NULL) { Py_RETURN_NONE; } @@ -1955,9 +1910,7 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) /* OpenSSL does not include peer cert for server side connections */ if (self->socket_type == PY_SSL_SERVER) { PyObject *peerobj = NULL; - PySSL_LOCK(self); X509 *peer = SSL_get_peer_certificate(self->ssl); - PySSL_UNLOCK(self); if (peer == NULL) { peerobj = Py_NewRef(Py_None); @@ -2092,14 +2045,10 @@ _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) done so, if the buffer is too small. */ - PySSL_LOCK(self); server_ciphers = SSL_get_ciphers(self->ssl); - PySSL_UNLOCK(self); if (!server_ciphers) Py_RETURN_NONE; - PySSL_LOCK(self); client_ciphers = SSL_get_client_ciphers(self->ssl); - PySSL_UNLOCK(self); if (!client_ciphers) Py_RETURN_NONE; @@ -2135,9 +2084,7 @@ _ssl__SSLSocket_cipher_impl(PySSLSocket *self) if (self->ssl == NULL) Py_RETURN_NONE; - PySSL_LOCK(self); current = SSL_get_current_cipher(self->ssl); - PySSL_UNLOCK(self); if (current == NULL) Py_RETURN_NONE; return cipher_to_tuple(current); @@ -2155,14 +2102,11 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self) if (self->ssl == NULL) Py_RETURN_NONE; - PySSL_LOCK(self); if (!SSL_is_init_finished(self->ssl)) { - PySSL_UNLOCK(self); /* handshake not finished */ Py_RETURN_NONE; } version = SSL_get_version(self->ssl); - PySSL_UNLOCK(self); if (!strcmp(version, "unknown")) Py_RETURN_NONE; return PyUnicode_FromString(version); @@ -2179,9 +2123,7 @@ _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self) const unsigned char *out; unsigned int outlen; - PySSL_LOCK(self); SSL_get0_alpn_selected(self->ssl, &out, &outlen); - PySSL_UNLOCK(self); if (out == NULL) Py_RETURN_NONE; @@ -2204,9 +2146,7 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self) if (self->ssl == NULL) Py_RETURN_NONE; - PySSL_LOCK(self); comp_method = SSL_get_current_compression(self->ssl); - PySSL_UNLOCK(self); if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef) Py_RETURN_NONE; short_name = OBJ_nid2sn(COMP_get_type(comp_method)); @@ -2225,14 +2165,12 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value, if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) { Py_SETREF(self->ctx, (PySSLContext *)Py_NewRef(value)); - PySSL_LOCK(self); SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); /* Set SSL* internal msg_callback to state of new context's state */ SSL_set_msg_callback( self->ssl, self->ctx->msg_cb ? _PySSL_msg_callback : NULL ); - PySSL_UNLOCK(self); } else { PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext"); return -1; @@ -2444,10 +2382,8 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) if (sock != NULL) { /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); - PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -2473,14 +2409,10 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) do { PySSL_BEGIN_ALLOW_THREADS - PySSL_LOCK(self); retval = SSL_write_ex(self->ssl, b->buf, (size_t)b->len, &count); - PySSL_UNLOCK(self); err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS - PySSL_LOCK(self); self->err = err; - PySSL_UNLOCK(self); if (PyErr_CheckSignals()) goto error; @@ -2537,14 +2469,10 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) _PySSLError err; PySSL_BEGIN_ALLOW_THREADS - PySSL_LOCK(self); count = SSL_pending(self->ssl); - PySSL_UNLOCK(self); err = _PySSL_errno(count < 0, self->ssl, count); PySSL_END_ALLOW_THREADS - PySSL_LOCK(self); self->err = err; - PySSL_UNLOCK(self); if (count < 0) return PySSL_SetError(self, __FILE__, __LINE__); @@ -2623,10 +2551,8 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, if (sock != NULL) { /* just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); - PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -2636,14 +2562,10 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, do { PySSL_BEGIN_ALLOW_THREADS - PySSL_LOCK(self); retval = SSL_read_ex(self->ssl, mem, (size_t)len, &count); - PySSL_UNLOCK(self); err = _PySSL_errno(retval == 0, self->ssl, retval); PySSL_END_ALLOW_THREADS - PySSL_LOCK(self); self->err = err; - PySSL_UNLOCK(self); if (PyErr_CheckSignals()) goto error; @@ -2729,10 +2651,8 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) /* Just in case the blocking state of the socket has been changed */ nonblocking = (sock->sock_timeout >= 0); - PySSL_LOCK(self); BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); - PySSL_UNLOCK(self); } timeout = GET_SOCKET_TIMEOUT(sock); @@ -2751,16 +2671,12 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) * function is used and the shutdown_seen_zero != 0 * condition is met. */ - PySSL_LOCK(self); if (self->shutdown_seen_zero) SSL_set_read_ahead(self->ssl, 0); ret = SSL_shutdown(self->ssl); - PySSL_UNLOCK(self); err = _PySSL_errno(ret < 0, self->ssl, ret); PySSL_END_ALLOW_THREADS - PySSL_LOCK(self); self->err = err; - PySSL_UNLOCK(self); /* If err == 1, a secure shutdown with SSL_shutdown() is complete */ if (ret > 0) @@ -2772,9 +2688,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) if (++zeros > 1) break; /* Shutdown was sent, now try receiving */ - PySSL_LOCK(self); self->shutdown_seen_zero = 1; - PySSL_UNLOCK(self); continue; } @@ -2847,7 +2761,6 @@ _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, size_t len; if (strcmp(cb_type, "tls-unique") == 0) { - PySSL_LOCK(self); if (SSL_session_reused(self->ssl) ^ !self->socket_type) { /* if session is resumed XOR we are the client */ len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN); @@ -2856,7 +2769,6 @@ _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, /* if a new session XOR we are the server */ len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN); } - PySSL_UNLOCK(self); } else { PyErr_Format( @@ -2885,9 +2797,7 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) /*[clinic end generated code: output=532147f3b1341425 input=6bfa874810a3d889]*/ { #if defined(PySSL_HAVE_POST_HS_AUTH) - PySSL_LOCK(self); int err = SSL_verify_client_post_handshake(self->ssl); - PySSL_UNLOCK(self); if (err == 0) return _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); else @@ -2907,9 +2817,7 @@ PySSL_get_session(PySSLSocket *self, void *closure) { PySSLSession *pysess; SSL_SESSION *session; - PySSL_LOCK(self); session = SSL_get1_session(self->ssl); - PySSL_UNLOCK(self); if (session == NULL) { Py_RETURN_NONE; } @@ -2924,9 +2832,6 @@ PySSL_get_session(PySSLSocket *self, void *closure) { assert(self->ctx); pysess->ctx = (PySSLContext*)Py_NewRef(self->ctx); pysess->session = session; -#ifdef Py_GIL_DISABLED - pysess->lock = (PyMutex) { 0 }; -#endif PyObject_GC_Track(pysess); return (PyObject *)pysess; } @@ -2951,20 +2856,16 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, "Cannot set session for server-side SSLSocket."); return -1; } - PySSL_LOCK(self); if (SSL_is_init_finished(self->ssl)) { - PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "Cannot set session after handshake."); return -1; } if (SSL_set_session(self->ssl, pysess->session) == 0) { - PySSL_UNLOCK(self); _setSSLError(get_state_sock(self), NULL, 0, __FILE__, __LINE__); return -1; } - PySSL_UNLOCK(self); return 0; } @@ -2975,9 +2876,7 @@ Get / set SSLSession."); static PyObject * PySSL_get_session_reused(PySSLSocket *self, void *closure) { - PySSL_LOCK(self); int res = SSL_session_reused(self->ssl); - PySSL_UNLOCK(self); return res ? Py_True : Py_False; } @@ -3064,9 +2963,7 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n) /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for * server sockets and SSL_set_post_handshake_auth() for client. */ - PySSL_LOCK(self); SSL_CTX_set_verify(self->ctx, mode, NULL); - PySSL_UNLOCK(self); return 0; } @@ -3181,9 +3078,6 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) self->psk_client_callback = NULL; self->psk_server_callback = NULL; #endif -#ifdef Py_GIL_DISABLED - self->lock = (PyMutex) { 0 }; -#endif /* Don't check host name by default */ if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { @@ -3331,9 +3225,7 @@ static PyObject * _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) /*[clinic end generated code: output=3a3162f3557c0f3f input=a7ac931b9f3ca7fc]*/ { - PySSL_LOCK(self); int ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); - PySSL_UNLOCK(self); if (ret == 0) { /* Clearing the error queue is necessary on some OpenSSL versions, otherwise the error will be reported again when another SSL call @@ -3360,16 +3252,12 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self) int i=0; PyObject *result = NULL, *dct; - PySSL_LOCK(self); ssl = SSL_new(self->ctx); - PySSL_UNLOCK(self); if (ssl == NULL) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); goto exit; } - PySSL_LOCK(self); sk = SSL_get_ciphers(ssl); - PySSL_UNLOCK(self); result = PyList_New(sk_SSL_CIPHER_num(sk)); if (result == NULL) { @@ -3447,21 +3335,17 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, return NULL; } - PySSL_LOCK(self); PyMem_Free(self->alpn_protocols); self->alpn_protocols = PyMem_Malloc(protos->len); if (!self->alpn_protocols) { - PySSL_UNLOCK(self); return PyErr_NoMemory(); } memcpy(self->alpn_protocols, protos->buf, protos->len); self->alpn_protocols_len = (unsigned int)protos->len; if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) { - PySSL_UNLOCK(self); return PyErr_NoMemory(); } SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); - PySSL_UNLOCK(self); Py_RETURN_NONE; } @@ -3472,9 +3356,7 @@ get_verify_mode(PySSLContext *self, void *c) /* ignore SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_POST_HANDSHAKE */ int mask = (SSL_VERIFY_NONE | SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); - PySSL_LOCK(self); int verify_mode = SSL_CTX_get_verify_mode(self->ctx); - PySSL_UNLOCK(self); switch (verify_mode & mask) { case SSL_VERIFY_NONE: return PyLong_FromLong(PY_SSL_CERT_NONE); @@ -3509,10 +3391,8 @@ get_verify_flags(PySSLContext *self, void *c) X509_VERIFY_PARAM *param; unsigned long flags; - PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); flags = X509_VERIFY_PARAM_get_flags(param); - PySSL_UNLOCK(self); return PyLong_FromUnsignedLong(flags); } @@ -3524,29 +3404,21 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) if (!PyArg_Parse(arg, "k", &new_flags)) return -1; - PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); flags = X509_VERIFY_PARAM_get_flags(param); - PySSL_UNLOCK(self); clear = flags & ~new_flags; set = ~flags & new_flags; if (clear) { - PySSL_LOCK(self); if (!X509_VERIFY_PARAM_clear_flags(param, clear)) { - PySSL_UNLOCK(self); _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return -1; } - PySSL_UNLOCK(self); } if (set) { - PySSL_LOCK(self); if (!X509_VERIFY_PARAM_set_flags(param, set)) { - PySSL_UNLOCK(self); _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return -1; } - PySSL_UNLOCK(self); } return 0; } @@ -3614,9 +3486,7 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) default: break; } - PySSL_LOCK(self); result = SSL_CTX_set_min_proto_version(self->ctx, v); - PySSL_UNLOCK(self); } else { switch(v) { @@ -3630,9 +3500,7 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) default: break; } - PySSL_LOCK(self); result = SSL_CTX_set_max_proto_version(self->ctx, v); - PySSL_UNLOCK(self); } if (result == 0) { PyErr_Format(PyExc_ValueError, @@ -3645,9 +3513,7 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) static PyObject * get_minimum_version(PySSLContext *self, void *c) { - PySSL_LOCK(self); int v = SSL_CTX_get_min_proto_version(self->ctx); - PySSL_UNLOCK(self); if (v == 0) { v = PY_PROTO_MINIMUM_SUPPORTED; } @@ -3663,9 +3529,7 @@ set_minimum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_maximum_version(PySSLContext *self, void *c) { - PySSL_LOCK(self); int v = SSL_CTX_get_max_proto_version(self->ctx); - PySSL_UNLOCK(self); if (v == 0) { v = PY_PROTO_MAXIMUM_SUPPORTED; } @@ -3682,9 +3546,7 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_num_tickets(PySSLContext *self, void *c) { - PySSL_LOCK(self); PyObject *res = PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); - PySSL_UNLOCK(self); return res; } @@ -3703,13 +3565,10 @@ set_num_tickets(PySSLContext *self, PyObject *arg, void *c) "SSLContext is not a server context."); return -1; } - PySSL_LOCK(self); if (SSL_CTX_set_num_tickets(self->ctx, num) != 1) { - PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "failed to set num tickets."); return -1; } - PySSL_UNLOCK(self); return 0; } @@ -3720,9 +3579,7 @@ PyDoc_STRVAR(PySSLContext_num_tickets_doc, static PyObject * get_security_level(PySSLContext *self, void *c) { - PySSL_LOCK(self); PyObject *res = PyLong_FromLong(SSL_CTX_get_security_level(self->ctx)); - PySSL_UNLOCK(self); return res; } PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); @@ -3730,9 +3587,7 @@ PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); static PyObject * get_options(PySSLContext *self, void *c) { - PySSL_LOCK(self); uint64_t options = SSL_CTX_get_options(self->ctx); - PySSL_UNLOCK(self); Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(options)); return PyLong_FromUnsignedLongLong(options); } @@ -3758,9 +3613,7 @@ set_options(PySSLContext *self, PyObject *arg, void *c) Py_BUILD_ASSERT(sizeof(new_opts) >= sizeof(new_opts_arg)); new_opts = (uint64_t)new_opts_arg; - PySSL_LOCK(self); opts = SSL_CTX_get_options(self->ctx); - PySSL_UNLOCK(self); clear = opts & ~new_opts; set = ~opts & new_opts; @@ -3770,14 +3623,12 @@ set_options(PySSLContext *self, PyObject *arg, void *c) return -1; } } - PySSL_LOCK(self); if (clear) { SSL_CTX_clear_options(self->ctx, clear); } if (set) { SSL_CTX_set_options(self->ctx, set); } - PySSL_UNLOCK(self); return 0; } @@ -3796,11 +3647,9 @@ set_host_flags(PySSLContext *self, PyObject *arg, void *c) if (!PyArg_Parse(arg, "I", &new_flags)) return -1; - PySSL_LOCK(self); param = SSL_CTX_get0_param(self->ctx); self->hostflags = new_flags; X509_VERIFY_PARAM_set_hostflags(param, new_flags); - PySSL_UNLOCK(self); return 0; } @@ -3816,9 +3665,7 @@ set_check_hostname(PySSLContext *self, PyObject *arg, void *c) int check_hostname; if (!PyArg_Parse(arg, "p", &check_hostname)) return -1; - PySSL_LOCK(self); int verify_mode = check_hostname ? SSL_CTX_get_verify_mode(self->ctx) : 0; - PySSL_UNLOCK(self); if (check_hostname && verify_mode == SSL_VERIFY_NONE) { /* check_hostname = True sets verify_mode = CERT_REQUIRED */ @@ -3826,9 +3673,7 @@ set_check_hostname(PySSLContext *self, PyObject *arg, void *c) return -1; } } - PySSL_LOCK(self); self->check_hostname = check_hostname; - PySSL_UNLOCK(self); return 0; } @@ -3990,10 +3835,8 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, /*[clinic end generated code: output=9480bc1c380e2095 input=30bc7e967ea01a58]*/ { PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; - PySSL_LOCK(self); pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx); - PySSL_UNLOCK(self); _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; int r; @@ -4022,16 +3865,12 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, "password should be a string or callable")) { goto error; } - PySSL_LOCK(self); SSL_CTX_set_default_passwd_cb(self->ctx, _password_callback); SSL_CTX_set_default_passwd_cb_userdata(self->ctx, &pw_info); - PySSL_UNLOCK(self); } PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); - PySSL_LOCK(self); r = SSL_CTX_use_certificate_chain_file(self->ctx, PyBytes_AS_STRING(certfile_bytes)); - PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); if (r != 1) { if (pw_info.error) { @@ -4048,11 +3887,9 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, goto error; } PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); - PySSL_LOCK(self); r = SSL_CTX_use_PrivateKey_file(self->ctx, PyBytes_AS_STRING(keyfile ? keyfile_bytes : certfile_bytes), SSL_FILETYPE_PEM); - PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); Py_CLEAR(keyfile_bytes); Py_CLEAR(certfile_bytes); @@ -4071,26 +3908,20 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, goto error; } PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); - PySSL_LOCK(self); r = SSL_CTX_check_private_key(self->ctx); - PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); if (r != 1) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); goto error; } - PySSL_LOCK(self); SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); - PySSL_UNLOCK(self); PyMem_Free(pw_info.password); Py_RETURN_NONE; error: - PySSL_LOCK(self); SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); - PySSL_UNLOCK(self); PyMem_Free(pw_info.password); Py_XDECREF(keyfile_bytes); Py_XDECREF(certfile_bytes); @@ -4125,9 +3956,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, return -1; } - PySSL_LOCK(self); store = SSL_CTX_get_cert_store(self->ctx); - PySSL_UNLOCK(self); assert(store != NULL); while (1) { @@ -4141,19 +3970,15 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, } cert = d2i_X509_bio(biobuf, NULL); } else { - PySSL_LOCK(self); cert = PEM_read_bio_X509(biobuf, NULL, SSL_CTX_get_default_passwd_cb(self->ctx), SSL_CTX_get_default_passwd_cb_userdata(self->ctx) ); - PySSL_UNLOCK(self); } if (cert == NULL) { break; } - PySSL_LOCK(self); r = X509_STORE_add_cert(store, cert); - PySSL_UNLOCK(self); X509_free(cert); if (!r) { err = ERR_peek_last_error(); @@ -4301,9 +4126,7 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, if (capath) capath_buf = PyBytes_AS_STRING(capath_bytes); PySSL_BEGIN_ALLOW_THREADS - PySSL_LOCK(self); r = SSL_CTX_load_verify_locations(self->ctx, cafile_buf, capath_buf); - PySSL_UNLOCK(self); PySSL_END_ALLOW_THREADS if (r != 1) { if (errno != 0) { @@ -4363,13 +4186,10 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) } return NULL; } - PySSL_LOCK(self); if (!SSL_CTX_set_tmp_dh(self->ctx, dh)) { - PySSL_UNLOCK(self); DH_free(dh); return _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); } - PySSL_UNLOCK(self); DH_free(dh); Py_RETURN_NONE; } @@ -4469,7 +4289,6 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self) if (r < 0) \ goto error; - PySSL_LOCK(self); ADD_STATS(number, "number"); ADD_STATS(connect, "connect"); ADD_STATS(connect_good, "connect_good"); @@ -4482,7 +4301,6 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self) ADD_STATS(misses, "misses"); ADD_STATS(timeouts, "timeouts"); ADD_STATS(cache_full, "cache_full"); - PySSL_UNLOCK(self); #undef ADD_STATS @@ -4503,9 +4321,7 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) { int rc; Py_BEGIN_ALLOW_THREADS - PySSL_LOCK(self); rc = SSL_CTX_set_default_verify_paths(self->ctx); - PySSL_UNLOCK(self); Py_END_ALLOW_THREADS if (!rc) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -4543,18 +4359,13 @@ _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } - PySSL_LOCK(self); SSL_CTX_set_tmp_ecdh(self->ctx, key); - PySSL_UNLOCK(self); EC_KEY_free(key); #else - PySSL_LOCK(self); if (!SSL_CTX_set1_groups(self->ctx, &nid, 1)) { - PySSL_UNLOCK(self); _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } - PySSL_UNLOCK(self); #endif Py_RETURN_NONE; } @@ -4682,24 +4493,18 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) } Py_CLEAR(self->set_sni_cb); if (arg == Py_None) { - PySSL_LOCK(self); SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); - PySSL_UNLOCK(self); } else { if (!PyCallable_Check(arg)) { - PySSL_LOCK(self); SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); - PySSL_UNLOCK(self); PyErr_SetString(PyExc_TypeError, "not a callable object"); return -1; } - PySSL_LOCK(self); self->set_sni_cb = Py_NewRef(arg); SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); SSL_CTX_set_tlsext_servername_arg(self->ctx, self); - PySSL_UNLOCK(self); } return 0; } @@ -4776,17 +4581,14 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) X509_OBJECT *obj; int x509 = 0, crl = 0, ca = 0, i; - PySSL_LOCK(self); store = SSL_CTX_get_cert_store(self->ctx); objs = X509_STORE_get1_objects(store); - PySSL_UNLOCK(self); if (objs == NULL) { PyErr_SetString(PyExc_MemoryError, "failed to query cert store"); return NULL; } for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { - PySSL_LOCK(self); obj = sk_X509_OBJECT_value(objs, i); switch (X509_OBJECT_get_type(obj)) { case X509_LU_X509: @@ -4802,11 +4604,8 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) /* Ignore unrecognized types. */ break; } - PySSL_UNLOCK(self); } - PySSL_LOCK(self); sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free); - PySSL_UNLOCK(self); return Py_BuildValue("{sisisi}", "x509", x509, "crl", crl, "x509_ca", ca); } @@ -4837,10 +4636,8 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) return NULL; } - PySSL_LOCK(self); store = SSL_CTX_get_cert_store(self->ctx); objs = X509_STORE_get1_objects(store); - PySSL_UNLOCK(self); if (objs == NULL) { PyErr_SetString(PyExc_MemoryError, "failed to query cert store"); goto error; @@ -4850,20 +4647,16 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) X509_OBJECT *obj; X509 *cert; - PySSL_LOCK(self); obj = sk_X509_OBJECT_value(objs, i); if (X509_OBJECT_get_type(obj) != X509_LU_X509) { /* not a x509 cert */ - PySSL_UNLOCK(self); continue; } /* CA for any purpose */ cert = X509_OBJECT_get0_X509(obj); if (!X509_check_ca(cert)) { - PySSL_UNLOCK(self); continue; } - PySSL_UNLOCK(self); if (binary_form) { ci = _certificate_to_der(get_state_ctx(self), cert); } else { @@ -4877,15 +4670,11 @@ _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) } Py_CLEAR(ci); } - PySSL_LOCK(self); sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free); - PySSL_UNLOCK(self); return rlist; error: - PySSL_LOCK(self); sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free); - PySSL_UNLOCK(self); Py_XDECREF(ci); Py_XDECREF(rlist); return NULL; @@ -4996,10 +4785,8 @@ _ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self, Py_XDECREF(self->psk_client_callback); Py_XINCREF(callback); - PySSL_LOCK(self); self->psk_client_callback = callback; SSL_CTX_set_psk_client_callback(self->ctx, ssl_callback); - PySSL_UNLOCK(self); Py_RETURN_NONE; #else @@ -5106,21 +4893,16 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, ssl_callback = psk_server_callback; } - PySSL_LOCK(self); if (SSL_CTX_use_psk_identity_hint(self->ctx, identity_hint) != 1) { - PySSL_UNLOCK(self); PyErr_SetString(PyExc_ValueError, "failed to set identity hint"); return NULL; } - PySSL_UNLOCK(self); Py_XDECREF(self->psk_server_callback); Py_XINCREF(callback); - PySSL_LOCK(self); self->psk_server_callback = callback; SSL_CTX_set_psk_server_callback(self->ctx, ssl_callback); - PySSL_UNLOCK(self); Py_RETURN_NONE; #else @@ -5244,9 +5026,6 @@ _ssl_MemoryBIO_impl(PyTypeObject *type) } self->bio = bio; self->eof_written = 0; -#ifdef Py_GIL_DISABLED - self->lock = (PyMutex) { 0 }; -#endif return (PyObject *) self; } @@ -5271,9 +5050,7 @@ memory_bio_dealloc(PySSLMemoryBIO *self) static PyObject * memory_bio_get_pending(PySSLMemoryBIO *self, void *c) { - PySSL_LOCK(self); size_t res = BIO_ctrl_pending(self->bio); - PySSL_UNLOCK(self); return PyLong_FromSize_t(res); } @@ -5283,9 +5060,7 @@ PyDoc_STRVAR(PySSL_memory_bio_pending_doc, static PyObject * memory_bio_get_eof(PySSLMemoryBIO *self, void *c) { - PySSL_LOCK(self); size_t pending = BIO_ctrl_pending(self->bio); - PySSL_UNLOCK(self); return PyBool_FromLong((pending == 0) && self->eof_written); } @@ -5312,9 +5087,7 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) int avail, nbytes; PyObject *result; - PySSL_LOCK(self); avail = (int)Py_MIN(BIO_ctrl_pending(self->bio), INT_MAX); - PySSL_UNLOCK(self); if ((len < 0) || (len > avail)) len = avail; @@ -5322,9 +5095,7 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) if ((result == NULL) || (len == 0)) return result; - PySSL_LOCK(self); nbytes = BIO_read(self->bio, PyBytes_AS_STRING(result), len); - PySSL_UNLOCK(self); if (nbytes < 0) { _sslmodulestate *state = get_state_mbio(self); Py_DECREF(result); @@ -5371,9 +5142,7 @@ _ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) return NULL; } - PySSL_LOCK(self); nbytes = BIO_write(self->bio, b->buf, (int)b->len); - PySSL_UNLOCK(self); if (nbytes < 0) { _sslmodulestate *state = get_state_mbio(self); _setSSLError(state, NULL, 0, __FILE__, __LINE__); @@ -5395,13 +5164,11 @@ static PyObject * _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) /*[clinic end generated code: output=d4106276ccd1ed34 input=56a945f1d29e8bd6]*/ { - PySSL_LOCK(self); self->eof_written = 1; /* After an EOF is written, a zero return from read() should be a real EOF * i.e. it should not be retried. Clear the SHOULD_RETRY flag. */ BIO_clear_retry_flags(self->bio); BIO_set_mem_eof_return(self->bio, 0); - PySSL_UNLOCK(self); Py_RETURN_NONE; } @@ -5476,14 +5243,10 @@ PySSLSession_richcompare(PyObject *left, PyObject *right, int op) } else { const unsigned char *left_id, *right_id; unsigned int left_len, right_len; - PySSL_LOCK((PySSLSession *)left); left_id = SSL_SESSION_get_id(((PySSLSession *)left)->session, &left_len); - PySSL_UNLOCK((PySSLSession *)left); - PySSL_LOCK((PySSLSession *)right); right_id = SSL_SESSION_get_id(((PySSLSession *)right)->session, &right_len); - PySSL_UNLOCK((PySSLSession *)right); if (left_len == right_len) { result = memcmp(left_id, right_id, left_len); } else { @@ -5537,14 +5300,7 @@ PySSLSession_clear(PySSLSession *self) static PyObject * PySSLSession_get_time(PySSLSession *self, void *closure) { #if OPENSSL_VERSION_NUMBER >= 0x30300000L - PySSL_LOCK(self); - time_t time = SSL_SESSION_get_time_ex(self->session); - PySSL_UNLOCK(self); - PyObject *res = _PyLong_FromTime_t(time); -#else - PySSL_LOCK(self); int time = SSL_SESSION_get_time(self->session); - PySSL_UNLOCK(self); PyObject *res = PyLong_FromLong(time); #endif return res; @@ -5556,9 +5312,7 @@ PyDoc_STRVAR(PySSLSession_get_time_doc, static PyObject * PySSLSession_get_timeout(PySSLSession *self, void *closure) { - PySSL_LOCK(self); long timeout = SSL_SESSION_get_timeout(self->session); - PySSL_UNLOCK(self); PyObject *res = PyLong_FromLong(timeout); return res; } @@ -5569,9 +5323,7 @@ PyDoc_STRVAR(PySSLSession_get_timeout_doc, static PyObject * PySSLSession_get_ticket_lifetime_hint(PySSLSession *self, void *closure) { - PySSL_LOCK(self); unsigned long hint = SSL_SESSION_get_ticket_lifetime_hint(self->session); - PySSL_UNLOCK(self); return PyLong_FromUnsignedLong(hint); } @@ -5583,9 +5335,7 @@ static PyObject * PySSLSession_get_session_id(PySSLSession *self, void *closure) { const unsigned char *id; unsigned int len; - PySSL_LOCK(self); id = SSL_SESSION_get_id(self->session, &len); - PySSL_UNLOCK(self); return PyBytes_FromStringAndSize((const char *)id, len); } @@ -5595,9 +5345,7 @@ PyDoc_STRVAR(PySSLSession_get_session_id_doc, static PyObject * PySSLSession_get_has_ticket(PySSLSession *self, void *closure) { - PySSL_LOCK(self); int res = SSL_SESSION_has_ticket(self->session); - PySSL_UNLOCK(self); return res ? Py_True : Py_False; } From 80aea326b059bb26be07bc6f5ae5db3993885fc2 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:21:35 -0400 Subject: [PATCH 31/59] Use argument clinic for critical sections. --- Modules/_ssl.c | 140 ++++++++++++++++---------- Modules/clinic/_ssl.c.h | 215 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 286 insertions(+), 69 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index b0469276f11c78..a93f909bd50f34 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -945,12 +945,13 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, /* SSL object methods */ /*[clinic input] +@critical_section _ssl._SSLSocket.do_handshake [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) -/*[clinic end generated code: output=6c0898a8936548f6 input=d2d737de3df018c8]*/ +/*[clinic end generated code: output=6c0898a8936548f6 input=65619a7a4bea3176]*/ { int ret; _PySSLError err; @@ -984,10 +985,6 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ do { PySSL_BEGIN_ALLOW_THREADS - // XXX This isn't thread safe anymore, but locking this can cause a - // deadlock if a callback is active (see bpo-43577). I guess this - // isn't a huge problem because people shouldn't be calling - // do_handshake() across multiple threads anyway. ret = SSL_do_handshake(self->ssl); err = _PySSL_errno(ret < 1, self->ssl, ret); PySSL_END_ALLOW_THREADS @@ -1824,6 +1821,7 @@ _ssl__test_decode_cert_impl(PyObject *module, PyObject *path) /*[clinic input] +@critical_section _ssl._SSLSocket.getpeercert der as binary_mode: bool = False / @@ -1841,7 +1839,7 @@ return the certificate even if it wasn't validated. static PyObject * _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) -/*[clinic end generated code: output=1f0ab66dfb693c88 input=c0fbe802e57629b7]*/ +/*[clinic end generated code: output=1f0ab66dfb693c88 input=e35af55fa5f9bab8]*/ { int verification; X509 *peer_cert; @@ -1871,13 +1869,14 @@ _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode) } /*[clinic input] +@critical_section _ssl._SSLSocket.get_verified_chain [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self) -/*[clinic end generated code: output=802421163cdc3110 input=5fb0714f77e2bd51]*/ +/*[clinic end generated code: output=802421163cdc3110 input=83035fe238ec057b]*/ { /* borrowed reference */ STACK_OF(X509) *chain = SSL_get0_verified_chain(self->ssl); @@ -1888,13 +1887,14 @@ _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.get_unverified_chain [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) -/*[clinic end generated code: output=5acdae414e13f913 input=78c33c360c635cb5]*/ +/*[clinic end generated code: output=5acdae414e13f913 input=079f8ff5c205cb3b]*/ { PyObject *retval; /* borrowed reference */ @@ -2024,12 +2024,13 @@ cipher_to_dict(const SSL_CIPHER *cipher) } /*[clinic input] +@critical_section _ssl._SSLSocket.shared_ciphers [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) -/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/ +/*[clinic end generated code: output=3d174ead2e42c4fd input=869645271e3bc6d0]*/ { STACK_OF(SSL_CIPHER) *server_ciphers; STACK_OF(SSL_CIPHER) *client_ciphers; @@ -2073,12 +2074,13 @@ _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.cipher [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_cipher_impl(PySSLSocket *self) -/*[clinic end generated code: output=376417c16d0e5815 input=548fb0e27243796d]*/ +/*[clinic end generated code: output=376417c16d0e5815 input=39e180269a36f486]*/ { const SSL_CIPHER *current; @@ -2091,12 +2093,13 @@ _ssl__SSLSocket_cipher_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.version [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_version_impl(PySSLSocket *self) -/*[clinic end generated code: output=178aed33193b2cdb input=900186a503436fd6]*/ +/*[clinic end generated code: output=178aed33193b2cdb input=2732bc3f7f597d09]*/ { const char *version; @@ -2113,12 +2116,13 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.selected_alpn_protocol [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self) -/*[clinic end generated code: output=ec33688b303d250f input=442de30e35bc2913]*/ +/*[clinic end generated code: output=ec33688b303d250f input=f0b53506c9acdf8c]*/ { const unsigned char *out; unsigned int outlen; @@ -2347,6 +2351,7 @@ PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout) } /*[clinic input] +@critical_section _ssl._SSLSocket.write b: Py_buffer / @@ -2358,7 +2363,7 @@ Returns the number of bytes written. static PyObject * _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) -/*[clinic end generated code: output=aa7a6be5527358d8 input=77262d994fe5100a]*/ +/*[clinic end generated code: output=aa7a6be5527358d8 input=967b5feeae641a26]*/ { size_t count = 0; int retval; @@ -2456,6 +2461,7 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) } /*[clinic input] +@critical_section _ssl._SSLSocket.pending Returns the number of already decrypted bytes available for read, pending on the connection. @@ -2463,7 +2469,7 @@ Returns the number of already decrypted bytes available for read, pending on the static PyObject * _ssl__SSLSocket_pending_impl(PySSLSocket *self) -/*[clinic end generated code: output=983d9fecdc308a83 input=2b77487d6dfd597f]*/ +/*[clinic end generated code: output=983d9fecdc308a83 input=32ab982a254e8866]*/ { int count = 0; _PySSLError err; @@ -2481,6 +2487,7 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.read size as len: Py_ssize_t [ @@ -2494,7 +2501,7 @@ Read up to size bytes from the SSL socket. static PyObject * _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, int group_right_1, Py_buffer *buffer) -/*[clinic end generated code: output=49b16e6406023734 input=ec48bf622be1c4a1]*/ +/*[clinic end generated code: output=49b16e6406023734 input=80ed30436df01a71]*/ { PyObject *dest = NULL; char *mem; @@ -2623,6 +2630,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, } /*[clinic input] +@critical_section _ssl._SSLSocket.shutdown Does the SSL shutdown handshake with the remote end. @@ -2630,7 +2638,7 @@ Does the SSL shutdown handshake with the remote end. static PyObject * _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) -/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=11d39e69b0a2bf4a]*/ +/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=98d9635cd4e16514]*/ { _PySSLError err; int sockstate, nonblocking, ret; @@ -2742,6 +2750,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) } /*[clinic input] +@critical_section _ssl._SSLSocket.get_channel_binding cb_type: str = "tls-unique" @@ -2755,7 +2764,7 @@ Only 'tls-unique' channel binding data from RFC 5929 is supported. static PyObject * _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, const char *cb_type) -/*[clinic end generated code: output=34bac9acb6a61d31 input=08b7e43b99c17d41]*/ +/*[clinic end generated code: output=34bac9acb6a61d31 input=e008004fc08744db]*/ { char buf[PySSL_CB_MAXLEN]; size_t len; @@ -2787,6 +2796,7 @@ _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, } /*[clinic input] +@critical_section _ssl._SSLSocket.verify_client_post_handshake Initiate TLS 1.3 post-handshake authentication @@ -2794,7 +2804,7 @@ Initiate TLS 1.3 post-handshake authentication static PyObject * _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) -/*[clinic end generated code: output=532147f3b1341425 input=6bfa874810a3d889]*/ +/*[clinic end generated code: output=532147f3b1341425 input=42b5bb1f0981eda1]*/ { #if defined(PySSL_HAVE_POST_HS_AUTH) int err = SSL_verify_client_post_handshake(self->ssl); @@ -2968,6 +2978,7 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n) } /*[clinic input] +@critical_section @classmethod _ssl._SSLContext.__new__ protocol as proto_version: int @@ -2976,7 +2987,7 @@ _ssl._SSLContext.__new__ static PyObject * _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) -/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=8d58a805b95fc534]*/ +/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=6fc79e62ae9d143c]*/ { PySSLContext *self; uint64_t options; @@ -3216,6 +3227,7 @@ context_dealloc(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.set_ciphers cipherlist: str / @@ -3223,7 +3235,7 @@ _ssl._SSLContext.set_ciphers static PyObject * _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) -/*[clinic end generated code: output=3a3162f3557c0f3f input=a7ac931b9f3ca7fc]*/ +/*[clinic end generated code: output=3a3162f3557c0f3f input=40b583cded5c6ff9]*/ { int ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); if (ret == 0) { @@ -3239,12 +3251,13 @@ _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) } /*[clinic input] +@critical_section _ssl._SSLContext.get_ciphers [clinic start generated code]*/ static PyObject * _ssl__SSLContext_get_ciphers_impl(PySSLContext *self) -/*[clinic end generated code: output=a56e4d68a406dfc4 input=a2aadc9af89b79c5]*/ +/*[clinic end generated code: output=a56e4d68a406dfc4 input=d7fff51631a260ae]*/ { SSL *ssl = NULL; STACK_OF(SSL_CIPHER) *sk = NULL; @@ -3319,6 +3332,7 @@ _selectALPN_cb(SSL *s, } /*[clinic input] +@critical_section _ssl._SSLContext._set_alpn_protocols protos: Py_buffer / @@ -3327,7 +3341,7 @@ _ssl._SSLContext._set_alpn_protocols static PyObject * _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, Py_buffer *protos) -/*[clinic end generated code: output=87599a7f76651a9b input=9bba964595d519be]*/ +/*[clinic end generated code: output=87599a7f76651a9b input=b5096b186e49287d]*/ { if ((size_t)protos->len > UINT_MAX) { PyErr_Format(PyExc_OverflowError, @@ -3822,6 +3836,7 @@ _password_callback(char *buf, int size, int rwflag, void *userdata) } /*[clinic input] +@critical_section _ssl._SSLContext.load_cert_chain certfile: object keyfile: object = None @@ -3832,7 +3847,7 @@ _ssl._SSLContext.load_cert_chain static PyObject * _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, PyObject *keyfile, PyObject *password) -/*[clinic end generated code: output=9480bc1c380e2095 input=30bc7e967ea01a58]*/ +/*[clinic end generated code: output=9480bc1c380e2095 input=6c7c5e8b73e4264b]*/ { PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); @@ -4026,6 +4041,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, /*[clinic input] +@critical_section _ssl._SSLContext.load_verify_locations cafile: object = None capath: object = None @@ -4038,7 +4054,7 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, PyObject *cafile, PyObject *capath, PyObject *cadata) -/*[clinic end generated code: output=454c7e41230ca551 input=42ecfe258233e194]*/ +/*[clinic end generated code: output=454c7e41230ca551 input=b178852b41618414]*/ { PyObject *cafile_bytes = NULL, *capath_bytes = NULL; const char *cafile_buf = NULL, *capath_buf = NULL; @@ -4154,6 +4170,7 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, } /*[clinic input] +@critical_section _ssl._SSLContext.load_dh_params path as filepath: object / @@ -4161,8 +4178,8 @@ _ssl._SSLContext.load_dh_params [clinic start generated code]*/ static PyObject * -_ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) -/*[clinic end generated code: output=1c8e57a38e055af0 input=c8871f3c796ae1d6]*/ +_ssl__SSLContext_load_dh_params_impl(PySSLContext *self, PyObject *filepath) +/*[clinic end generated code: output=dd74b3c524dd2723 input=832769a0734b8c4d]*/ { FILE *f; DH *dh; @@ -4195,6 +4212,7 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) } /*[clinic input] +@critical_section _ssl._SSLContext._wrap_socket sock: object(subclass_of="get_state_ctx(self)->Sock_Type") server_side: bool @@ -4209,7 +4227,7 @@ static PyObject * _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, int server_side, PyObject *hostname_obj, PyObject *owner, PyObject *session) -/*[clinic end generated code: output=f103f238633940b4 input=700ca8fedff53994]*/ +/*[clinic end generated code: output=f103f238633940b4 input=eceadcee4434a06f]*/ { char *hostname = NULL; PyObject *res; @@ -4231,6 +4249,7 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, } /*[clinic input] +@critical_section _ssl._SSLContext._wrap_bio incoming: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") outgoing: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") @@ -4247,7 +4266,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=a9205d097fd45a82]*/ +/*[clinic end generated code: output=5c5d6d9b41f99332 input=58277fc962a60182]*/ { char *hostname = NULL; PyObject *res; @@ -4268,12 +4287,13 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, } /*[clinic input] +@critical_section _ssl._SSLContext.session_stats [clinic start generated code]*/ static PyObject * _ssl__SSLContext_session_stats_impl(PySSLContext *self) -/*[clinic end generated code: output=0d96411c42893bfb input=7e0a81fb11102c8b]*/ +/*[clinic end generated code: output=0d96411c42893bfb input=db62af53004127a4]*/ { int r; PyObject *value, *stats = PyDict_New(); @@ -4312,12 +4332,13 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.set_default_verify_paths [clinic start generated code]*/ static PyObject * _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) -/*[clinic end generated code: output=0bee74e6e09deaaa input=35f3408021463d74]*/ +/*[clinic end generated code: output=0bee74e6e09deaaa input=939a88e78f634119]*/ { int rc; Py_BEGIN_ALLOW_THREADS @@ -4331,6 +4352,7 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.set_ecdh_curve name: object / @@ -4338,8 +4360,8 @@ _ssl._SSLContext.set_ecdh_curve [clinic start generated code]*/ static PyObject * -_ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) -/*[clinic end generated code: output=23022c196e40d7d2 input=c2bafb6f6e34726b]*/ +_ssl__SSLContext_set_ecdh_curve_impl(PySSLContext *self, PyObject *name) +/*[clinic end generated code: output=01081151ce0ecc45 input=039df032e666870e]*/ { PyObject *name_bytes; int nid; @@ -4561,6 +4583,7 @@ with the SSLSocket, the server name as a string, and the SSLContext object.\n\ See RFC 6066 for details of the SNI extension."); /*[clinic input] +@critical_section _ssl._SSLContext.cert_store_stats Returns quantities of loaded X.509 certificates. @@ -4574,7 +4597,7 @@ been used at least once. static PyObject * _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) -/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/ +/*[clinic end generated code: output=5f356f4d9cca874d input=d13c6e3f2b48539b]*/ { X509_STORE *store; STACK_OF(X509_OBJECT) *objs; @@ -4611,6 +4634,7 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) } /*[clinic input] +@critical_section _ssl._SSLContext.get_ca_certs binary_form: bool = False @@ -4625,7 +4649,7 @@ been used at least once. static PyObject * _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) -/*[clinic end generated code: output=0d58f148f37e2938 input=6887b5a09b7f9076]*/ +/*[clinic end generated code: output=0d58f148f37e2938 input=eb0592909c9ad6e7]*/ { X509_STORE *store; STACK_OF(X509_OBJECT) *objs; @@ -4751,6 +4775,7 @@ static unsigned int psk_client_callback(SSL *s, #endif /*[clinic input] +@critical_section _ssl._SSLContext.set_psk_client_callback callback: object @@ -4759,7 +4784,7 @@ _ssl._SSLContext.set_psk_client_callback static PyObject * _ssl__SSLContext_set_psk_client_callback_impl(PySSLContext *self, PyObject *callback) -/*[clinic end generated code: output=0aba86f6ed75119e input=7627bae0e5ee7635]*/ +/*[clinic end generated code: output=0aba86f6ed75119e input=1e436eea625cfc35]*/ { #ifndef OPENSSL_NO_PSK if (self->protocol == PY_SSL_VERSION_TLS_SERVER) { @@ -4859,6 +4884,7 @@ static unsigned int psk_server_callback(SSL *s, #endif /*[clinic input] +@critical_section _ssl._SSLContext.set_psk_server_callback callback: object identity_hint: str(accept={str, NoneType}) = None @@ -4869,7 +4895,7 @@ static PyObject * _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, PyObject *callback, const char *identity_hint) -/*[clinic end generated code: output=1f4d6a4e09a92b03 input=65d4b6022aa85ea3]*/ +/*[clinic end generated code: output=1f4d6a4e09a92b03 input=5f79d932458284a7]*/ { #ifndef OPENSSL_NO_PSK if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) { @@ -4995,6 +5021,7 @@ static PyType_Spec PySSLContext_spec = { */ /*[clinic input] +@critical_section @classmethod _ssl.MemoryBIO.__new__ @@ -5002,7 +5029,7 @@ _ssl.MemoryBIO.__new__ static PyObject * _ssl_MemoryBIO_impl(PyTypeObject *type) -/*[clinic end generated code: output=8820a58db78330ac input=26d22e4909ecb1b5]*/ +/*[clinic end generated code: output=8820a58db78330ac input=87f146cf30af454e]*/ { BIO *bio; PySSLMemoryBIO *self; @@ -5068,6 +5095,7 @@ PyDoc_STRVAR(PySSL_memory_bio_eof_doc, "Whether the memory BIO is at EOF."); /*[clinic input] +@critical_section _ssl.MemoryBIO.read size as len: int = -1 / @@ -5082,7 +5110,7 @@ distinguish between the two. static PyObject * _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) -/*[clinic end generated code: output=a657aa1e79cd01b3 input=574d7be06a902366]*/ +/*[clinic end generated code: output=a657aa1e79cd01b3 input=21046f2d7dac3a90]*/ { int avail, nbytes; PyObject *result; @@ -5112,6 +5140,7 @@ _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len) } /*[clinic input] +@critical_section _ssl.MemoryBIO.write b: Py_buffer / @@ -5123,7 +5152,7 @@ Returns the number of bytes written. static PyObject * _ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) -/*[clinic end generated code: output=156ec59110d75935 input=e45757b3e17c4808]*/ +/*[clinic end generated code: output=156ec59110d75935 input=107da3f5fba26b37]*/ { int nbytes; @@ -5153,6 +5182,7 @@ _ssl_MemoryBIO_write_impl(PySSLMemoryBIO *self, Py_buffer *b) } /*[clinic input] +@critical_section _ssl.MemoryBIO.write_eof Write an EOF marker to the memory BIO. @@ -5162,7 +5192,7 @@ When all data has been read, the "eof" property will be True. static PyObject * _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) -/*[clinic end generated code: output=d4106276ccd1ed34 input=56a945f1d29e8bd6]*/ +/*[clinic end generated code: output=d4106276ccd1ed34 input=1e914231b1c5900a]*/ { self->eof_written = 1; /* After an EOF is written, a zero return from read() should be a real EOF @@ -5300,10 +5330,10 @@ PySSLSession_clear(PySSLSession *self) static PyObject * PySSLSession_get_time(PySSLSession *self, void *closure) { #if OPENSSL_VERSION_NUMBER >= 0x30300000L - int time = SSL_SESSION_get_time(self->session); - PyObject *res = PyLong_FromLong(time); + return _PyLong_FromTime_t(SSL_SESSION_get_time_ex(self->session)); +#else + return PyLong_FromLong(SSL_SESSION_get_time(self->session)); #endif - return res; } PyDoc_STRVAR(PySSLSession_get_time_doc, @@ -5388,6 +5418,7 @@ static PyType_Spec PySSLSession_spec = { /* helper routines for seeding the SSL PRNG */ /*[clinic input] +@critical_section _ssl.RAND_add string as view: Py_buffer(accept={str, buffer}) entropy: double @@ -5401,7 +5432,7 @@ string. See RFC 4086. static PyObject * _ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy) -/*[clinic end generated code: output=e6dd48df9c9024e9 input=5c33017422828f5c]*/ +/*[clinic end generated code: output=e6dd48df9c9024e9 input=313cb73b34db31d5]*/ { const char *buf; Py_ssize_t len, written; @@ -5457,6 +5488,7 @@ PySSL_RAND(PyObject *module, int len, int pseudo) } /*[clinic input] +@critical_section _ssl.RAND_bytes n: int / @@ -5466,13 +5498,14 @@ Generate n cryptographically strong pseudo-random bytes. static PyObject * _ssl_RAND_bytes_impl(PyObject *module, int n) -/*[clinic end generated code: output=977da635e4838bc7 input=678ddf2872dfebfc]*/ +/*[clinic end generated code: output=977da635e4838bc7 input=2e78ce1e86336776]*/ { return PySSL_RAND(module, n, 0); } /*[clinic input] +@critical_section _ssl.RAND_status Returns True if the OpenSSL PRNG has been seeded with enough data and False if not. @@ -5483,12 +5516,13 @@ using the ssl() function. static PyObject * _ssl_RAND_status_impl(PyObject *module) -/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=d5ae5aea52f36e01]*/ +/*[clinic end generated code: output=7e0aaa2d39fdc1ad input=636fb5659ea2e727]*/ { return PyBool_FromLong(RAND_status()); } /*[clinic input] +@critical_section _ssl.get_default_verify_paths Return search paths and environment vars that are used by SSLContext's set_default_verify_paths() to load default CAs. @@ -5498,7 +5532,7 @@ The values are 'cert_file_env', 'cert_file', 'cert_dir_env', 'cert_dir'. static PyObject * _ssl_get_default_verify_paths_impl(PyObject *module) -/*[clinic end generated code: output=e5b62a466271928b input=5210c953d98c3eb5]*/ +/*[clinic end generated code: output=e5b62a466271928b input=c6ae00bc04eb2b6e]*/ { PyObject *ofile_env = NULL; PyObject *ofile = NULL; @@ -5547,6 +5581,7 @@ asn1obj2py(_sslmodulestate *state, ASN1_OBJECT *obj) } /*[clinic input] +@critical_section _ssl.txt2obj txt: str name: bool = False @@ -5559,7 +5594,7 @@ long name are also matched. static PyObject * _ssl_txt2obj_impl(PyObject *module, const char *txt, int name) -/*[clinic end generated code: output=c38e3991347079c1 input=1c1e7d0aa7c48602]*/ +/*[clinic end generated code: output=c38e3991347079c1 input=c99b134d70173c5e]*/ { PyObject *result = NULL; ASN1_OBJECT *obj; @@ -5575,6 +5610,7 @@ _ssl_txt2obj_impl(PyObject *module, const char *txt, int name) } /*[clinic input] +@critical_section _ssl.nid2obj nid: int / @@ -5584,7 +5620,7 @@ Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID. static PyObject * _ssl_nid2obj_impl(PyObject *module, int nid) -/*[clinic end generated code: output=4a98ab691cd4f84a input=51787a3bee7d8f98]*/ +/*[clinic end generated code: output=4a98ab691cd4f84a input=1b1170506fa83a53]*/ { PyObject *result = NULL; ASN1_OBJECT *obj; @@ -5736,6 +5772,7 @@ ssl_collect_certificates(const char *store_name) } /*[clinic input] +@critical_section _ssl.enum_certificates store_name: str @@ -5750,7 +5787,7 @@ a set of OIDs or the boolean True. static PyObject * _ssl_enum_certificates_impl(PyObject *module, const char *store_name) -/*[clinic end generated code: output=5134dc8bb3a3c893 input=915f60d70461ea4e]*/ +/*[clinic end generated code: output=5134dc8bb3a3c893 input=263c22e6c6988cf3]*/ { HCERTSTORE hCollectionStore = NULL; PCCERT_CONTEXT pCertCtx = NULL; @@ -5835,6 +5872,7 @@ _ssl_enum_certificates_impl(PyObject *module, const char *store_name) } /*[clinic input] +@critical_section _ssl.enum_crls store_name: str @@ -5848,7 +5886,7 @@ X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. static PyObject * _ssl_enum_crls_impl(PyObject *module, const char *store_name) -/*[clinic end generated code: output=bce467f60ccd03b6 input=a1f1d7629f1c5d3d]*/ +/*[clinic end generated code: output=bce467f60ccd03b6 input=51a1b1059e55ce43]*/ { HCERTSTORE hCollectionStore = NULL; PCCRL_CONTEXT pCrlCtx = NULL; diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index e8d1342ed35e66..aa1253aeccdace 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -6,6 +6,7 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION() #include "pycore_modsupport.h" // _PyArg_CheckPositional() PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, @@ -22,7 +23,13 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_do_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_do_handshake_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_do_handshake_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__test_decode_cert__doc__, @@ -88,7 +95,9 @@ _ssl__SSLSocket_getpeercert(PySSLSocket *self, PyObject *const *args, Py_ssize_t goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_getpeercert_impl(self, binary_mode); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -108,7 +117,13 @@ _ssl__SSLSocket_get_verified_chain_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_get_verified_chain(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_get_verified_chain_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_get_verified_chain_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_get_unverified_chain__doc__, @@ -125,7 +140,13 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_get_unverified_chain(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_get_unverified_chain_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_get_unverified_chain_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_shared_ciphers__doc__, @@ -142,7 +163,13 @@ _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_shared_ciphers(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_shared_ciphers_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_shared_ciphers_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_cipher__doc__, @@ -159,7 +186,13 @@ _ssl__SSLSocket_cipher_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_cipher(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_cipher_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_cipher_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_version__doc__, @@ -176,7 +209,13 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_version(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_version_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_version_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_selected_alpn_protocol__doc__, @@ -193,7 +232,13 @@ _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_selected_alpn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_selected_alpn_protocol_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_selected_alpn_protocol_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__, @@ -236,7 +281,9 @@ _ssl__SSLSocket_write(PySSLSocket *self, PyObject *arg) if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_write_impl(self, &b); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for b */ @@ -262,7 +309,13 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_pending(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_pending_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_pending_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_read__doc__, @@ -300,7 +353,9 @@ _ssl__SSLSocket_read(PySSLSocket *self, PyObject *args) PyErr_SetString(PyExc_TypeError, "_ssl._SSLSocket.read requires 1 to 2 arguments"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_read_impl(self, len, group_right_1, &buffer); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for buffer */ @@ -326,7 +381,13 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_shutdown(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_shutdown_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_shutdown_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__, @@ -400,7 +461,9 @@ _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_get_channel_binding_impl(self, cb_type); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -421,7 +484,13 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self); static PyObject * _ssl__SSLSocket_verify_client_post_handshake(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLSocket_verify_client_post_handshake_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_verify_client_post_handshake_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } static PyObject * @@ -445,7 +514,9 @@ _ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (proto_version == -1 && PyErr_Occurred()) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(type); return_value = _ssl__SSLContext_impl(type, proto_version); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -481,7 +552,9 @@ _ssl__SSLContext_set_ciphers(PySSLContext *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_set_ciphers_impl(self, cipherlist); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -501,7 +574,13 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLContext_get_ciphers_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_get_ciphers_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, @@ -525,7 +604,9 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext__set_alpn_protocols_impl(self, &protos); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for protos */ @@ -599,7 +680,9 @@ _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_s } password = args[2]; skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_load_cert_chain_impl(self, certfile, keyfile, password); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -675,7 +758,9 @@ _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args } cadata = args[2]; skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_load_verify_locations_impl(self, cafile, capath, cadata); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -689,6 +774,21 @@ PyDoc_STRVAR(_ssl__SSLContext_load_dh_params__doc__, #define _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF \ {"load_dh_params", (PyCFunction)_ssl__SSLContext_load_dh_params, METH_O, _ssl__SSLContext_load_dh_params__doc__}, +static PyObject * +_ssl__SSLContext_load_dh_params_impl(PySSLContext *self, PyObject *filepath); + +static PyObject * +_ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_load_dh_params_impl(self, filepath); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__, "_wrap_socket($self, /, sock, server_side, server_hostname=None, *,\n" " owner=None, session=None)\n" @@ -774,7 +874,9 @@ _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssiz } session = args[4]; skip_optional_kwonly: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj, owner, session); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -872,7 +974,9 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t } session = args[5]; skip_optional_kwonly: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj, owner, session); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -892,7 +996,13 @@ _ssl__SSLContext_session_stats_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_session_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLContext_session_stats_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_session_stats_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLContext_set_default_verify_paths__doc__, @@ -909,7 +1019,13 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_set_default_verify_paths(PySSLContext *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLContext_set_default_verify_paths_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_set_default_verify_paths_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, @@ -920,6 +1036,21 @@ PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF \ {"set_ecdh_curve", (PyCFunction)_ssl__SSLContext_set_ecdh_curve, METH_O, _ssl__SSLContext_set_ecdh_curve__doc__}, +static PyObject * +_ssl__SSLContext_set_ecdh_curve_impl(PySSLContext *self, PyObject *name); + +static PyObject * +_ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_set_ecdh_curve_impl(self, name); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, "cert_store_stats($self, /)\n" "--\n" @@ -941,7 +1072,13 @@ _ssl__SSLContext_cert_store_stats_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_cert_store_stats(PySSLContext *self, PyObject *Py_UNUSED(ignored)) { - return _ssl__SSLContext_cert_store_stats_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_cert_store_stats_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl__SSLContext_get_ca_certs__doc__, @@ -1007,7 +1144,9 @@ _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssiz goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_get_ca_certs_impl(self, binary_form); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1062,7 +1201,9 @@ _ssl__SSLContext_set_psk_client_callback(PySSLContext *self, PyObject *const *ar goto exit; } callback = args[0]; + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_set_psk_client_callback_impl(self, callback); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1142,7 +1283,9 @@ _ssl__SSLContext_set_psk_server_callback(PySSLContext *self, PyObject *const *ar goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_set_psk_server_callback_impl(self, callback, identity_hint); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1165,7 +1308,9 @@ _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) !_PyArg_NoKeywords("MemoryBIO", kwargs)) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(type); return_value = _ssl_MemoryBIO_impl(type); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1205,7 +1350,9 @@ _ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *const *args, Py_ssize_t narg goto exit; } skip_optional: + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl_MemoryBIO_read_impl(self, len); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1234,7 +1381,9 @@ _ssl_MemoryBIO_write(PySSLMemoryBIO *self, PyObject *arg) if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl_MemoryBIO_write_impl(self, &b); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for b */ @@ -1262,7 +1411,13 @@ _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self); static PyObject * _ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) { - return _ssl_MemoryBIO_write_eof_impl(self); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_MemoryBIO_write_eof_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl_RAND_add__doc__, @@ -1315,7 +1470,9 @@ _ssl_RAND_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_RAND_add_impl(module, &view, entropy); + Py_END_CRITICAL_SECTION(); exit: /* Cleanup for view */ @@ -1348,7 +1505,9 @@ _ssl_RAND_bytes(PyObject *module, PyObject *arg) if (n == -1 && PyErr_Occurred()) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_RAND_bytes_impl(module, n); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1372,7 +1531,13 @@ _ssl_RAND_status_impl(PyObject *module); static PyObject * _ssl_RAND_status(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return _ssl_RAND_status_impl(module); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(module); + return_value = _ssl_RAND_status_impl(module); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl_get_default_verify_paths__doc__, @@ -1392,7 +1557,13 @@ _ssl_get_default_verify_paths_impl(PyObject *module); static PyObject * _ssl_get_default_verify_paths(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return _ssl_get_default_verify_paths_impl(module); + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(module); + return_value = _ssl_get_default_verify_paths_impl(module); + Py_END_CRITICAL_SECTION(); + + return return_value; } PyDoc_STRVAR(_ssl_txt2obj__doc__, @@ -1469,7 +1640,9 @@ _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto exit; } skip_optional_pos: + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_txt2obj_impl(module, txt, name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1497,7 +1670,9 @@ _ssl_nid2obj(PyObject *module, PyObject *arg) if (nid == -1 && PyErr_Occurred()) { goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_nid2obj_impl(module, nid); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1572,7 +1747,9 @@ _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_enum_certificates_impl(module, store_name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1648,7 +1825,9 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } + Py_BEGIN_CRITICAL_SECTION(module); return_value = _ssl_enum_crls_impl(module, store_name); + Py_END_CRITICAL_SECTION(); exit: return return_value; @@ -1663,4 +1842,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=28a22f2b09d631cb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=930f7b2ce6d07704 input=a9049054013a1b77]*/ From 7d76621e22dceab5fd073e18e02c9b49bdec1e35 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:35:01 -0400 Subject: [PATCH 32/59] Switch reused_session to clinic --- Modules/_ssl.c | 14 +++++++++++--- Modules/clinic/_ssl.c.h | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a93f909bd50f34..33f22ec18379d6 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2884,8 +2884,17 @@ PyDoc_STRVAR(PySSL_set_session_doc, \ Get / set SSLSession."); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.session_reused + +Was the client session reused during handshake? +[clinic start generated code]*/ + static PyObject * -PySSL_get_session_reused(PySSLSocket *self, void *closure) { +_ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self) { +/*[clinic end generated code: output=c8916909bcb80893 input=cec8bfec73a4461e]*/ int res = SSL_session_reused(self->ssl); return res ? Py_True : Py_False; } @@ -2904,8 +2913,7 @@ static PyGetSetDef ssl_getsetlist[] = { PySSL_get_owner_doc}, {"session", (getter) PySSL_get_session, (setter) PySSL_set_session, PySSL_set_session_doc}, - {"session_reused", (getter) PySSL_get_session_reused, NULL, - PySSL_get_session_reused_doc}, + _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {NULL}, /* sentinel */ }; diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index aa1253aeccdace..701d0e8b34026f 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -493,6 +493,37 @@ _ssl__SSLSocket_verify_client_post_handshake(PySSLSocket *self, PyObject *Py_UNU return return_value; } +PyDoc_STRVAR(_ssl__SSLSocket_session_reused__doc__, +"Was the client session reused during handshake?"); +#define _ssl__SSLSocket_session_reused_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_session_reused_HAS_DOCSTR) +# define _ssl__SSLSocket_session_reused_DOCSTR _ssl__SSLSocket_session_reused__doc__ +#else +# define _ssl__SSLSocket_session_reused_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF) +# undef _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF +# define _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {"session_reused", (getter)_ssl__SSLSocket_session_reused_get, (setter)_ssl__SSLSocket_session_reused_set, _ssl__SSLSocket_session_reused_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {"session_reused", (getter)_ssl__SSLSocket_session_reused_get, NULL, _ssl__SSLSocket_session_reused_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_session_reused_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_session_reused_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + static PyObject * _ssl__SSLContext_impl(PyTypeObject *type, int proto_version); @@ -1842,4 +1873,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=930f7b2ce6d07704 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=79aaaf0e264304c7 input=a9049054013a1b77]*/ From 44a8c48ce6a3b8ee9a610d11a47aa8bf643371af Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:41:54 -0400 Subject: [PATCH 33/59] Switch session to argument clinic. --- Modules/_ssl.c | 41 +++++++++++++++++----------- Modules/clinic/_ssl.c.h | 60 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 17 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 33f22ec18379d6..ef1c98db8a9825 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -376,7 +376,6 @@ class _ssl.SSLSession "PySSLSession *" "get_state_type(type)->PySSLSession_Type" 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 *); typedef enum { SOCKET_IS_NONBLOCKING, @@ -932,7 +931,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, } } if (session && session != Py_None) { - if (PySSL_set_session(self, session, NULL) == -1) { + if (_ssl__SSLSocket_session_set_impl(self, session) == -1) { Py_DECREF(self); return NULL; } @@ -2820,8 +2819,18 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) #endif } +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.session + +Get / set SSLSession. +[clinic start generated code]*/ + static PyObject * -PySSL_get_session(PySSLSocket *self, void *closure) { +_ssl__SSLSocket_session_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=a5cd5755b35da670 input=be77165ad3547c3d]*/ +{ /* get_session can return sessions from a server-side connection, * it does not check for handshake done or client socket. */ PySSLSession *pysess; @@ -2846,8 +2855,16 @@ PySSL_get_session(PySSLSocket *self, void *closure) { return (PyObject *)pysess; } -static int PySSL_set_session(PySSLSocket *self, PyObject *value, - void *closure) { +/*[clinic input] +@critical_section +@setter +_ssl._SSLSocket.session +[clinic start generated code]*/ + +static int +_ssl__SSLSocket_session_set_impl(PySSLSocket *self, PyObject *value) +/*[clinic end generated code: output=a3fa2ddd7c2d54a2 input=5fa5f921640db98b]*/ +{ PySSLSession *pysess; if (!Py_IS_TYPE(value, get_state_sock(self)->PySSLSession_Type)) { @@ -2879,11 +2896,6 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value, return 0; } -PyDoc_STRVAR(PySSL_set_session_doc, -"_setter_session(session)\n\ -\ -Get / set SSLSession."); - /*[clinic input] @critical_section @getter @@ -2893,15 +2905,13 @@ Was the client session reused during handshake? [clinic start generated code]*/ static PyObject * -_ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self) { +_ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self) /*[clinic end generated code: output=c8916909bcb80893 input=cec8bfec73a4461e]*/ +{ int res = SSL_session_reused(self->ssl); return res ? Py_True : Py_False; } -PyDoc_STRVAR(PySSL_get_session_reused_doc, -"Was the client session reused during handshake?"); - static PyGetSetDef ssl_getsetlist[] = { {"context", (getter) PySSL_get_context, (setter) PySSL_set_context, PySSL_set_context_doc}, @@ -2911,8 +2921,7 @@ static PyGetSetDef ssl_getsetlist[] = { PySSL_get_server_hostname_doc}, {"owner", (getter) PySSL_get_owner, (setter) PySSL_set_owner, PySSL_get_owner_doc}, - {"session", (getter) PySSL_get_session, - (setter) PySSL_set_session, PySSL_set_session_doc}, + _SSL__SSLSOCKET_SESSION_GETSETDEF _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {NULL}, /* sentinel */ }; diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 701d0e8b34026f..47cb4bdd8067ff 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -493,6 +493,64 @@ _ssl__SSLSocket_verify_client_post_handshake(PySSLSocket *self, PyObject *Py_UNU return return_value; } +PyDoc_STRVAR(_ssl__SSLSocket_session__doc__, +"Get / set SSLSession."); +#define _ssl__SSLSocket_session_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_session_HAS_DOCSTR) +# define _ssl__SSLSocket_session_DOCSTR _ssl__SSLSocket_session__doc__ +#else +# define _ssl__SSLSocket_session_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SESSION_GETSETDEF) +# undef _SSL__SSLSOCKET_SESSION_GETSETDEF +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, (setter)_ssl__SSLSocket_session_set, _ssl__SSLSocket_session_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, NULL, _ssl__SSLSocket_session_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_session_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_session_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_session_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLSOCKET_SESSION_HAS_DOCSTR) +# define _ssl__SSLSocket_session_DOCSTR _ssl__SSLSocket_session__doc__ +#else +# define _ssl__SSLSocket_session_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SESSION_GETSETDEF) +# undef _SSL__SSLSOCKET_SESSION_GETSETDEF +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, (setter)_ssl__SSLSocket_session_set, _ssl__SSLSocket_session_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", NULL, (setter)_ssl__SSLSocket_session_set, NULL}, +#endif + +static int +_ssl__SSLSocket_session_set_impl(PySSLSocket *self, PyObject *value); + +static int +_ssl__SSLSocket_session_set(PySSLSocket *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_session_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLSocket_session_reused__doc__, "Was the client session reused during handshake?"); #define _ssl__SSLSocket_session_reused_HAS_DOCSTR @@ -1873,4 +1931,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=79aaaf0e264304c7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4e7e2b7a652aa50a input=a9049054013a1b77]*/ From 6e13fed539ca620782463417ead4bf4456bf4605 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:46:46 -0400 Subject: [PATCH 34/59] Switch owner to argument clinic. --- Modules/_ssl.c | 33 ++++++++++++++--------- Modules/clinic/_ssl.c.h | 60 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index ef1c98db8a9825..1f39549ea271ee 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -375,8 +375,6 @@ class _ssl.SSLSession "PySSLSession *" "get_state_type(type)->PySSLSession_Type" static int PySSL_select(PySocketSockObject *s, int writing, PyTime_t timeout); -static int PySSL_set_owner(PySSLSocket *, PyObject *, void *); - typedef enum { SOCKET_IS_NONBLOCKING, SOCKET_IS_BLOCKING, @@ -925,13 +923,13 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, } } if (owner && owner != Py_None) { - if (PySSL_set_owner(self, owner, NULL) == -1) { + if (_ssl__SSLSocket_owner_set(self, owner, NULL) == -1) { Py_DECREF(self); return NULL; } } if (session && session != Py_None) { - if (_ssl__SSLSocket_session_set_impl(self, session) == -1) { + if (_ssl__SSLSocket_session_set(self, session, NULL) == -1) { Py_DECREF(self); return NULL; } @@ -2211,8 +2209,17 @@ PySSL_get_server_hostname(PySSLSocket *self, void *c) PyDoc_STRVAR(PySSL_get_server_hostname_doc, "The currently set server hostname (for SNI)."); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.owner + +The Python-level owner of this object. Passed as "self" in servername callback. +[clinic start generated code]*/ + static PyObject * -PySSL_get_owner(PySSLSocket *self, void *c) +_ssl__SSLSocket_owner_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=1f278cb930382927 input=57fd0d5f2644757a]*/ { if (self->owner == NULL) { Py_RETURN_NONE; @@ -2224,8 +2231,15 @@ PySSL_get_owner(PySSLSocket *self, void *c) return owner; } +/*[clinic input] +@critical_section +@setter +_ssl._SSLSocket.owner +[clinic start generated code]*/ + static int -PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c) +_ssl__SSLSocket_owner_set_impl(PySSLSocket *self, PyObject *value) +/*[clinic end generated code: output=2e3924498f2b6cde input=875666fd32367a73]*/ { Py_XSETREF(self->owner, PyWeakref_NewRef(value, NULL)); if (self->owner == NULL) @@ -2233,10 +2247,6 @@ PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c) return 0; } -PyDoc_STRVAR(PySSL_get_owner_doc, -"The Python-level owner of this object.\ -Passed as \"self\" in servername callback."); - static int PySSL_traverse(PySSLSocket *self, visitproc visit, void *arg) { @@ -2919,8 +2929,7 @@ static PyGetSetDef ssl_getsetlist[] = { PySSL_get_server_side_doc}, {"server_hostname", (getter) PySSL_get_server_hostname, NULL, PySSL_get_server_hostname_doc}, - {"owner", (getter) PySSL_get_owner, (setter) PySSL_set_owner, - PySSL_get_owner_doc}, + _SSL__SSLSOCKET_OWNER_GETSETDEF _SSL__SSLSOCKET_SESSION_GETSETDEF _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {NULL}, /* sentinel */ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 47cb4bdd8067ff..b716dd9eb2b72d 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -258,6 +258,64 @@ _ssl__SSLSocket_compression(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) return _ssl__SSLSocket_compression_impl(self); } +PyDoc_STRVAR(_ssl__SSLSocket_owner__doc__, +"The Python-level owner of this object. Passed as \"self\" in servername callback."); +#define _ssl__SSLSocket_owner_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_owner_HAS_DOCSTR) +# define _ssl__SSLSocket_owner_DOCSTR _ssl__SSLSocket_owner__doc__ +#else +# define _ssl__SSLSocket_owner_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_OWNER_GETSETDEF) +# undef _SSL__SSLSOCKET_OWNER_GETSETDEF +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, (setter)_ssl__SSLSocket_owner_set, _ssl__SSLSocket_owner_DOCSTR}, +#else +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, NULL, _ssl__SSLSocket_owner_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_owner_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_owner_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_owner_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLSOCKET_OWNER_HAS_DOCSTR) +# define _ssl__SSLSocket_owner_DOCSTR _ssl__SSLSocket_owner__doc__ +#else +# define _ssl__SSLSocket_owner_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_OWNER_GETSETDEF) +# undef _SSL__SSLSOCKET_OWNER_GETSETDEF +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, (setter)_ssl__SSLSocket_owner_set, _ssl__SSLSocket_owner_DOCSTR}, +#else +# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", NULL, (setter)_ssl__SSLSocket_owner_set, NULL}, +#endif + +static int +_ssl__SSLSocket_owner_set_impl(PySSLSocket *self, PyObject *value); + +static int +_ssl__SSLSocket_owner_set(PySSLSocket *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_owner_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLSocket_write__doc__, "write($self, b, /)\n" "--\n" @@ -1931,4 +1989,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=4e7e2b7a652aa50a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=21899c86029bc674 input=a9049054013a1b77]*/ From 2424f67b234e592e456521656ffeff8a3c0856b4 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:48:38 -0400 Subject: [PATCH 35/59] Switch server_hostname to argument clinic. --- Modules/_ssl.c | 18 ++++++++++++------ Modules/clinic/_ssl.c.h | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 1f39549ea271ee..6fd95e1ab84507 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2198,17 +2198,24 @@ PySSL_get_server_side(PySSLSocket *self, void *c) PyDoc_STRVAR(PySSL_get_server_side_doc, "Whether this is a server-side socket."); + +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.server_hostname + +The currently set server hostname (for SNI). +[clinic start generated code]*/ + static PyObject * -PySSL_get_server_hostname(PySSLSocket *self, void *c) +_ssl__SSLSocket_server_hostname_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=1f40ea5a076de8e7 input=55d12a1dc6634b08]*/ { if (self->server_hostname == NULL) Py_RETURN_NONE; return Py_NewRef(self->server_hostname); } -PyDoc_STRVAR(PySSL_get_server_hostname_doc, -"The currently set server hostname (for SNI)."); - /*[clinic input] @critical_section @getter @@ -2927,8 +2934,7 @@ static PyGetSetDef ssl_getsetlist[] = { (setter) PySSL_set_context, PySSL_set_context_doc}, {"server_side", (getter) PySSL_get_server_side, NULL, PySSL_get_server_side_doc}, - {"server_hostname", (getter) PySSL_get_server_hostname, NULL, - PySSL_get_server_hostname_doc}, + _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF _SSL__SSLSOCKET_OWNER_GETSETDEF _SSL__SSLSOCKET_SESSION_GETSETDEF _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index b716dd9eb2b72d..9e15844134cd7e 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -258,6 +258,37 @@ _ssl__SSLSocket_compression(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) return _ssl__SSLSocket_compression_impl(self); } +PyDoc_STRVAR(_ssl__SSLSocket_server_hostname__doc__, +"The currently set server hostname (for SNI)."); +#define _ssl__SSLSocket_server_hostname_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_server_hostname_HAS_DOCSTR) +# define _ssl__SSLSocket_server_hostname_DOCSTR _ssl__SSLSocket_server_hostname__doc__ +#else +# define _ssl__SSLSocket_server_hostname_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF) +# undef _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF +# define _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF {"server_hostname", (getter)_ssl__SSLSocket_server_hostname_get, (setter)_ssl__SSLSocket_server_hostname_set, _ssl__SSLSocket_server_hostname_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF {"server_hostname", (getter)_ssl__SSLSocket_server_hostname_get, NULL, _ssl__SSLSocket_server_hostname_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_server_hostname_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_server_hostname_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_server_hostname_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLSocket_owner__doc__, "The Python-level owner of this object. Passed as \"self\" in servername callback."); #define _ssl__SSLSocket_owner_HAS_DOCSTR @@ -1989,4 +2020,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=21899c86029bc674 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=236e1d55e76c93ca input=a9049054013a1b77]*/ From 9b91bc09ee833b04e1e31a3336ec6a51df5f0f07 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:55:00 -0400 Subject: [PATCH 36/59] Switch context to argument clinic. --- Modules/_ssl.c | 50 +++++++++++++---------- Modules/clinic/_ssl.c.h | 87 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 21 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 6fd95e1ab84507..bb6f5cb6519162 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2157,13 +2157,29 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self) #endif } -static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) { - return (PySSLContext*)Py_NewRef(self->ctx); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.context +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLSocket_context_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=d23e82f72f32e3d7 input=25aa82e4d9fa344a]*/ +{ + return Py_NewRef(self->ctx); } -static int PySSL_set_context(PySSLSocket *self, PyObject *value, - void *closure) { +/*[clinic input] +@critical_section +@setter +_ssl._SSLSocket.context +[clinic start generated code]*/ +static int +_ssl__SSLSocket_context_set_impl(PySSLSocket *self, PyObject *value) +/*[clinic end generated code: output=6b0a6cc5cf33d9fe input=48ece77724fd9dd4]*/ +{ if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) { Py_SETREF(self->ctx, (PySSLContext *)Py_NewRef(value)); SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); @@ -2180,25 +2196,21 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value, return 0; } -PyDoc_STRVAR(PySSL_set_context_doc, -"_setter_context(ctx)\n\ -\ -This changes the context associated with the SSLSocket. This is typically\n\ -used from within a callback function set by the sni_callback\n\ -on the SSLContext to change the certificate information associated with the\n\ -SSLSocket before the cryptographic exchange handshake messages\n"); +/*[clinic input] +@critical_section +@getter +_ssl._SSLSocket.server_side +Whether this is a server-side socket. +[clinic start generated code]*/ static PyObject * -PySSL_get_server_side(PySSLSocket *self, void *c) +_ssl__SSLSocket_server_side_get_impl(PySSLSocket *self) +/*[clinic end generated code: output=ae51e372489148e3 input=b09b320510bc7cae]*/ { return PyBool_FromLong(self->socket_type == PY_SSL_SERVER); } -PyDoc_STRVAR(PySSL_get_server_side_doc, -"Whether this is a server-side socket."); - - /*[clinic input] @critical_section @getter @@ -2930,10 +2942,8 @@ _ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self) } static PyGetSetDef ssl_getsetlist[] = { - {"context", (getter) PySSL_get_context, - (setter) PySSL_set_context, PySSL_set_context_doc}, - {"server_side", (getter) PySSL_get_server_side, NULL, - PySSL_get_server_side_doc}, + _SSL__SSLSOCKET_CONTEXT_GETSETDEF + _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF _SSL__SSLSOCKET_OWNER_GETSETDEF _SSL__SSLSOCKET_SESSION_GETSETDEF diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 9e15844134cd7e..70e9112f3edd5d 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -258,6 +258,91 @@ _ssl__SSLSocket_compression(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) return _ssl__SSLSocket_compression_impl(self); } +#if defined(_ssl__SSLSocket_context_HAS_DOCSTR) +# define _ssl__SSLSocket_context_DOCSTR _ssl__SSLSocket_context__doc__ +#else +# define _ssl__SSLSocket_context_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_CONTEXT_GETSETDEF) +# undef _SSL__SSLSOCKET_CONTEXT_GETSETDEF +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, (setter)_ssl__SSLSocket_context_set, _ssl__SSLSocket_context_DOCSTR}, +#else +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, NULL, _ssl__SSLSocket_context_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_context_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_context_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_context_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLSOCKET_CONTEXT_HAS_DOCSTR) +# define _ssl__SSLSocket_context_DOCSTR _ssl__SSLSocket_context__doc__ +#else +# define _ssl__SSLSocket_context_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_CONTEXT_GETSETDEF) +# undef _SSL__SSLSOCKET_CONTEXT_GETSETDEF +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, (setter)_ssl__SSLSocket_context_set, _ssl__SSLSocket_context_DOCSTR}, +#else +# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", NULL, (setter)_ssl__SSLSocket_context_set, NULL}, +#endif + +static int +_ssl__SSLSocket_context_set_impl(PySSLSocket *self, PyObject *value); + +static int +_ssl__SSLSocket_context_set(PySSLSocket *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_context_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_server_side__doc__, +"Whether this is a server-side socket."); +#define _ssl__SSLSocket_server_side_HAS_DOCSTR + +#if defined(_ssl__SSLSocket_server_side_HAS_DOCSTR) +# define _ssl__SSLSocket_server_side_DOCSTR _ssl__SSLSocket_server_side__doc__ +#else +# define _ssl__SSLSocket_server_side_DOCSTR NULL +#endif +#if defined(_SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF) +# undef _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF +# define _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF {"server_side", (getter)_ssl__SSLSocket_server_side_get, (setter)_ssl__SSLSocket_server_side_set, _ssl__SSLSocket_server_side_DOCSTR}, +#else +# define _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF {"server_side", (getter)_ssl__SSLSocket_server_side_get, NULL, _ssl__SSLSocket_server_side_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLSocket_server_side_get_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_server_side_get(PySSLSocket *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLSocket_server_side_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLSocket_server_hostname__doc__, "The currently set server hostname (for SNI)."); #define _ssl__SSLSocket_server_hostname_HAS_DOCSTR @@ -2020,4 +2105,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=236e1d55e76c93ca input=a9049054013a1b77]*/ +/*[clinic end generated code: output=92017ea0e2f2fcba input=a9049054013a1b77]*/ From c0377ebfe03f21cd29d07f12c590f39b5cf8cc58 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 17:58:55 -0400 Subject: [PATCH 37/59] Switch check_hostname to argument clinic. --- Modules/_ssl.c | 23 +++++++++++++---- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index bb6f5cb6519162..43c2724d806088 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3709,17 +3709,31 @@ set_host_flags(PySSLContext *self, PyObject *arg, void *c) return 0; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.check_hostname +[clinic start generated code]*/ + static PyObject * -get_check_hostname(PySSLContext *self, void *c) +_ssl__SSLContext_check_hostname_get_impl(PySSLContext *self) +/*[clinic end generated code: output=e046d6eeefc76063 input=1b8341e705f9ecf5]*/ { return PyBool_FromLong(self->check_hostname); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.check_hostname +[clinic start generated code]*/ + static int -set_check_hostname(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=0e767b4784e7dc3f input=e6a771cb5919f74d]*/ { int check_hostname; - if (!PyArg_Parse(arg, "p", &check_hostname)) + if (!PyArg_Parse(value, "p", &check_hostname)) return -1; int verify_mode = check_hostname ? SSL_CTX_get_verify_mode(self->ctx) : 0; if (check_hostname && @@ -4982,8 +4996,7 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, static PyGetSetDef context_getsetlist[] = { - {"check_hostname", (getter) get_check_hostname, - (setter) set_check_hostname, NULL}, + _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"_host_flags", (getter) get_host_flags, (setter) set_host_flags, NULL}, {"minimum_version", (getter) get_minimum_version, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 70e9112f3edd5d..aac62dc9fe5f21 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -880,6 +880,60 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) return return_value; } +#if defined(_ssl__SSLContext_check_hostname_HAS_DOCSTR) +# define _ssl__SSLContext_check_hostname_DOCSTR _ssl__SSLContext_check_hostname__doc__ +#else +# define _ssl__SSLContext_check_hostname_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF) +# undef _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, (setter)_ssl__SSLContext_check_hostname_set, _ssl__SSLContext_check_hostname_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, NULL, _ssl__SSLContext_check_hostname_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_check_hostname_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_check_hostname_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_check_hostname_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_HAS_DOCSTR) +# define _ssl__SSLContext_check_hostname_DOCSTR _ssl__SSLContext_check_hostname__doc__ +#else +# define _ssl__SSLContext_check_hostname_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF) +# undef _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, (setter)_ssl__SSLContext_check_hostname_set, _ssl__SSLContext_check_hostname_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", NULL, (setter)_ssl__SSLContext_check_hostname_set, NULL}, +#endif + +static int +_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_check_hostname_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_check_hostname_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext_load_cert_chain__doc__, "load_cert_chain($self, /, certfile, keyfile=None, password=None)\n" "--\n" @@ -2105,4 +2159,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=92017ea0e2f2fcba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fdfe4b2244ae2a54 input=a9049054013a1b77]*/ From be02857ed30f8b0f93f40adcae7da004ac96021f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:01:34 -0400 Subject: [PATCH 38/59] Switch host_flags to argument clinic. --- Modules/_ssl.c | 23 +++++++++++++---- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 43c2724d806088..1cd71a7c7b6342 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3688,19 +3688,33 @@ set_options(PySSLContext *self, PyObject *arg, void *c) return 0; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext._host_flags +[clinic start generated code]*/ + static PyObject * -get_host_flags(PySSLContext *self, void *c) +_ssl__SSLContext__host_flags_get_impl(PySSLContext *self) +/*[clinic end generated code: output=0f9db6654ce32582 input=8e3c49499eefd0e5]*/ { return PyLong_FromUnsignedLong(self->hostflags); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext._host_flags +[clinic start generated code]*/ + static int -set_host_flags(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=1ed6f4027aaf2e3e input=28caf1fb9c32f6cb]*/ { X509_VERIFY_PARAM *param; unsigned int new_flags = 0; - if (!PyArg_Parse(arg, "I", &new_flags)) + if (!PyArg_Parse(value, "I", &new_flags)) return -1; param = SSL_CTX_get0_param(self->ctx); @@ -4997,8 +5011,7 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, static PyGetSetDef context_getsetlist[] = { _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF - {"_host_flags", (getter) get_host_flags, - (setter) set_host_flags, NULL}, + _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"minimum_version", (getter) get_minimum_version, (setter) set_minimum_version, NULL}, {"maximum_version", (getter) get_maximum_version, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index aac62dc9fe5f21..7d4fad2afe8252 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -880,6 +880,60 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) return return_value; } +#if defined(_ssl__SSLContext__host_flags_HAS_DOCSTR) +# define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ +#else +# define _ssl__SSLContext__host_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, (setter)_ssl__SSLContext__host_flags_set, _ssl__SSLContext__host_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, NULL, _ssl__SSLContext__host_flags_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext__host_flags_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext__host_flags_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext__host_flags_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_HAS_DOCSTR) +# define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ +#else +# define _ssl__SSLContext__host_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, (setter)_ssl__SSLContext__host_flags_set, _ssl__SSLContext__host_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", NULL, (setter)_ssl__SSLContext__host_flags_set, NULL}, +#endif + +static int +_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext__host_flags_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext__host_flags_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext_check_hostname_HAS_DOCSTR) # define _ssl__SSLContext_check_hostname_DOCSTR _ssl__SSLContext_check_hostname__doc__ #else @@ -2159,4 +2213,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=fdfe4b2244ae2a54 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=caca896be11b53a6 input=a9049054013a1b77]*/ From fe362d4bfbc338501fcf01078cf4e15aa5a3336a Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:03:49 -0400 Subject: [PATCH 39/59] Switch minimum_version to argument clinic. --- Modules/_ssl.c | 24 +++++++++++++---- Modules/clinic/_ssl.c.h | 57 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 1cd71a7c7b6342..f1c6e93ea86efe 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3566,8 +3566,15 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) return 0; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.minimum_version +[clinic start generated code]*/ + static PyObject * -get_minimum_version(PySSLContext *self, void *c) +_ssl__SSLContext_minimum_version_get_impl(PySSLContext *self) +/*[clinic end generated code: output=27fa8382276635ed input=6832821e7e974d40]*/ { int v = SSL_CTX_get_min_proto_version(self->ctx); if (v == 0) { @@ -3576,10 +3583,18 @@ get_minimum_version(PySSLContext *self, void *c) return PyLong_FromLong(v); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.minimum_version +[clinic start generated code]*/ + static int -set_minimum_version(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_minimum_version_set_impl(PySSLContext *self, + PyObject *value) +/*[clinic end generated code: output=482e82f7372afb78 input=2c64724901a514b3]*/ { - return set_min_max_proto_version(self, arg, 0); + return set_min_max_proto_version(self, value, 0); } static PyObject * @@ -5012,8 +5027,7 @@ _ssl__SSLContext_set_psk_server_callback_impl(PySSLContext *self, static PyGetSetDef context_getsetlist[] = { _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF - {"minimum_version", (getter) get_minimum_version, - (setter) set_minimum_version, NULL}, + _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"maximum_version", (getter) get_maximum_version, (setter) set_maximum_version, NULL}, {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 7d4fad2afe8252..7f0664096b2967 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -880,6 +880,61 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) return return_value; } +#if defined(_ssl__SSLContext_minimum_version_HAS_DOCSTR) +# define _ssl__SSLContext_minimum_version_DOCSTR _ssl__SSLContext_minimum_version__doc__ +#else +# define _ssl__SSLContext_minimum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, (setter)_ssl__SSLContext_minimum_version_set, _ssl__SSLContext_minimum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, NULL, _ssl__SSLContext_minimum_version_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_minimum_version_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_minimum_version_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_minimum_version_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_HAS_DOCSTR) +# define _ssl__SSLContext_minimum_version_DOCSTR _ssl__SSLContext_minimum_version__doc__ +#else +# define _ssl__SSLContext_minimum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, (setter)_ssl__SSLContext_minimum_version_set, _ssl__SSLContext_minimum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", NULL, (setter)_ssl__SSLContext_minimum_version_set, NULL}, +#endif + +static int +_ssl__SSLContext_minimum_version_set_impl(PySSLContext *self, + PyObject *value); + +static int +_ssl__SSLContext_minimum_version_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_minimum_version_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext__host_flags_HAS_DOCSTR) # define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ #else @@ -2213,4 +2268,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=caca896be11b53a6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1bdcf2ac943863a1 input=a9049054013a1b77]*/ From fe088d6932087662c9ec1307598eca2c2efec56b Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:06:16 -0400 Subject: [PATCH 40/59] Switch maximum_version to argument clinic. --- Modules/_ssl.c | 24 +++++++++++++---- Modules/clinic/_ssl.c.h | 57 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f1c6e93ea86efe..9bf01f8dbc0cf3 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3597,8 +3597,15 @@ _ssl__SSLContext_minimum_version_set_impl(PySSLContext *self, return set_min_max_proto_version(self, value, 0); } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.maximum_version +[clinic start generated code]*/ + static PyObject * -get_maximum_version(PySSLContext *self, void *c) +_ssl__SSLContext_maximum_version_get_impl(PySSLContext *self) +/*[clinic end generated code: output=889249475112826a input=2b9e4c2d45f16b14]*/ { int v = SSL_CTX_get_max_proto_version(self->ctx); if (v == 0) { @@ -3607,10 +3614,18 @@ get_maximum_version(PySSLContext *self, void *c) return PyLong_FromLong(v); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.maximum_version +[clinic start generated code]*/ + static int -set_maximum_version(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_maximum_version_set_impl(PySSLContext *self, + PyObject *value) +/*[clinic end generated code: output=4c0eed3042ca20d5 input=fe27e9fbbeb73c89]*/ { - return set_min_max_proto_version(self, arg, 1); + return set_min_max_proto_version(self, value, 1); } #if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) @@ -5028,8 +5043,7 @@ static PyGetSetDef context_getsetlist[] = { _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF - {"maximum_version", (getter) get_maximum_version, - (setter) set_maximum_version, NULL}, + _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, (setter) _PySSLContext_set_keylog_filename, NULL}, {"_msg_callback", (getter) _PySSLContext_get_msg_callback, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 7f0664096b2967..6a803c96315211 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -935,6 +935,61 @@ _ssl__SSLContext_minimum_version_set(PySSLContext *self, PyObject *value, void * return return_value; } +#if defined(_ssl__SSLContext_maximum_version_HAS_DOCSTR) +# define _ssl__SSLContext_maximum_version_DOCSTR _ssl__SSLContext_maximum_version__doc__ +#else +# define _ssl__SSLContext_maximum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, (setter)_ssl__SSLContext_maximum_version_set, _ssl__SSLContext_maximum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, NULL, _ssl__SSLContext_maximum_version_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_maximum_version_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_maximum_version_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_maximum_version_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_HAS_DOCSTR) +# define _ssl__SSLContext_maximum_version_DOCSTR _ssl__SSLContext_maximum_version__doc__ +#else +# define _ssl__SSLContext_maximum_version_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF) +# undef _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, (setter)_ssl__SSLContext_maximum_version_set, _ssl__SSLContext_maximum_version_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", NULL, (setter)_ssl__SSLContext_maximum_version_set, NULL}, +#endif + +static int +_ssl__SSLContext_maximum_version_set_impl(PySSLContext *self, + PyObject *value); + +static int +_ssl__SSLContext_maximum_version_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_maximum_version_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext__host_flags_HAS_DOCSTR) # define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ #else @@ -2268,4 +2323,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=1bdcf2ac943863a1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2cdc16c38db51f7c input=a9049054013a1b77]*/ From f9ae8523a0e56fd33b788ab176210f1e119dc29f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:31:46 -0400 Subject: [PATCH 41/59] Switch sni_callback to argument clinic. --- Modules/_ssl.c | 35 +++++++++++++++----------- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 16 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 9bf01f8dbc0cf3..d592ac1e9948b0 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -4595,8 +4595,15 @@ _servername_callback(SSL *s, int *al, void *args) return ret; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.sni_callback +[clinic start generated code]*/ + static PyObject * -get_sni_callback(PySSLContext *self, void *c) +_ssl__SSLContext_sni_callback_get_impl(PySSLContext *self) +/*[clinic end generated code: output=961e6575cdfaf036 input=22dd28c31fdc4318]*/ { PyObject *cb = self->set_sni_cb; if (cb == NULL) { @@ -4605,8 +4612,15 @@ get_sni_callback(PySSLContext *self, void *c) return Py_NewRef(cb); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.sni_callback +[clinic start generated code]*/ + static int -set_sni_callback(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=b32736c6b891f61a input=c3c4ff33540b3c85]*/ { if (self->protocol == PY_SSL_VERSION_TLS_CLIENT) { PyErr_SetString(PyExc_ValueError, @@ -4614,17 +4628,17 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) return -1; } Py_CLEAR(self->set_sni_cb); - if (arg == Py_None) { + if (value == Py_None) { SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); } else { - if (!PyCallable_Check(arg)) { + if (!PyCallable_Check(value)) { SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); PyErr_SetString(PyExc_TypeError, "not a callable object"); return -1; } - self->set_sni_cb = Py_NewRef(arg); + self->set_sni_cb = Py_NewRef(value); SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); SSL_CTX_set_tlsext_servername_arg(self->ctx, self); } @@ -4671,17 +4685,9 @@ X509_STORE_get1_objects(X509_STORE *store) ret = sk_X509_OBJECT_deep_copy(X509_STORE_get0_objects(store), x509_object_dup, X509_OBJECT_free); X509_STORE_unlock(store); - return ret; } #endif -PyDoc_STRVAR(PySSLContext_sni_callback_doc, -"Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension.\n\ -\n\ -If the argument is None then the callback is disabled. The method is called\n\ -with the SSLSocket, the server name as a string, and the SSLContext object.\n\ -See RFC 6066 for details of the SNI extension."); - /*[clinic input] @critical_section _ssl._SSLContext.cert_store_stats @@ -5048,8 +5054,7 @@ static PyGetSetDef context_getsetlist[] = { (setter) _PySSLContext_set_keylog_filename, NULL}, {"_msg_callback", (getter) _PySSLContext_get_msg_callback, (setter) _PySSLContext_set_msg_callback, NULL}, - {"sni_callback", (getter) get_sni_callback, - (setter) set_sni_callback, PySSLContext_sni_callback_doc}, + _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF #if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) {"num_tickets", (getter) get_num_tickets, (setter) set_num_tickets, PySSLContext_num_tickets_doc}, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 6a803c96315211..80585e0303fb39 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -1532,6 +1532,60 @@ _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) return return_value; } +#if defined(_ssl__SSLContext_sni_callback_HAS_DOCSTR) +# define _ssl__SSLContext_sni_callback_DOCSTR _ssl__SSLContext_sni_callback__doc__ +#else +# define _ssl__SSLContext_sni_callback_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF) +# undef _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, (setter)_ssl__SSLContext_sni_callback_set, _ssl__SSLContext_sni_callback_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, NULL, _ssl__SSLContext_sni_callback_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_sni_callback_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_sni_callback_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_sni_callback_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_HAS_DOCSTR) +# define _ssl__SSLContext_sni_callback_DOCSTR _ssl__SSLContext_sni_callback__doc__ +#else +# define _ssl__SSLContext_sni_callback_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF) +# undef _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, (setter)_ssl__SSLContext_sni_callback_set, _ssl__SSLContext_sni_callback_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", NULL, (setter)_ssl__SSLContext_sni_callback_set, NULL}, +#endif + +static int +_ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_sni_callback_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_sni_callback_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, "cert_store_stats($self, /)\n" "--\n" @@ -2323,4 +2377,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=2cdc16c38db51f7c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4fc34fbd4ebf95c7 input=a9049054013a1b77]*/ From eb61a848521345c19ba7746f795a179af0a9b356 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:40:16 -0400 Subject: [PATCH 42/59] Switch num_tickets to clinic. --- Modules/_ssl.c | 33 ++++++++++++++++-------- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 11 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index d592ac1e9948b0..9f3b3e0da4f994 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3628,19 +3628,37 @@ _ssl__SSLContext_maximum_version_set_impl(PySSLContext *self, return set_min_max_proto_version(self, value, 1); } -#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.num_tickets +[clinic start generated code]*/ + static PyObject * -get_num_tickets(PySSLContext *self, void *c) +_ssl__SSLContext_num_tickets_get_impl(PySSLContext *self) +/*[clinic end generated code: output=3d06d016318846c9 input=1dee26d75163c073]*/ { + // Clinic seems to be misbehaving when the comment is wrapped with in directive +#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) PyObject *res = PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); return res; +#else + return 0; +#endif } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.num_tickets +[clinic start generated code]*/ + static int -set_num_tickets(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=ced81b46f3beab09 input=6ef8067ac55607e7]*/ { long num; - if (!PyArg_Parse(arg, "l", &num)) + if (!PyArg_Parse(value, "l", &num)) return -1; if (num < 0) { PyErr_SetString(PyExc_ValueError, "value must be non-negative"); @@ -3658,10 +3676,6 @@ set_num_tickets(PySSLContext *self, PyObject *arg, void *c) return 0; } -PyDoc_STRVAR(PySSLContext_num_tickets_doc, -"Control the number of TLSv1.3 session tickets"); -#endif /* defined(TLS1_3_VERSION) */ - static PyObject * get_security_level(PySSLContext *self, void *c) { @@ -5056,8 +5070,7 @@ static PyGetSetDef context_getsetlist[] = { (setter) _PySSLContext_set_msg_callback, NULL}, _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF #if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) - {"num_tickets", (getter) get_num_tickets, - (setter) set_num_tickets, PySSLContext_num_tickets_doc}, + _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF #endif {"options", (getter) get_options, (setter) set_options, NULL}, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 80585e0303fb39..6305e96c45ef2c 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -990,6 +990,60 @@ _ssl__SSLContext_maximum_version_set(PySSLContext *self, PyObject *value, void * return return_value; } +#if defined(_ssl__SSLContext_num_tickets_HAS_DOCSTR) +# define _ssl__SSLContext_num_tickets_DOCSTR _ssl__SSLContext_num_tickets__doc__ +#else +# define _ssl__SSLContext_num_tickets_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF) +# undef _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, (setter)_ssl__SSLContext_num_tickets_set, _ssl__SSLContext_num_tickets_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, NULL, _ssl__SSLContext_num_tickets_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_num_tickets_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_num_tickets_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_num_tickets_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_HAS_DOCSTR) +# define _ssl__SSLContext_num_tickets_DOCSTR _ssl__SSLContext_num_tickets__doc__ +#else +# define _ssl__SSLContext_num_tickets_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF) +# undef _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, (setter)_ssl__SSLContext_num_tickets_set, _ssl__SSLContext_num_tickets_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", NULL, (setter)_ssl__SSLContext_num_tickets_set, NULL}, +#endif + +static int +_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_num_tickets_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_num_tickets_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext__host_flags_HAS_DOCSTR) # define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ #else @@ -2377,4 +2431,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=4fc34fbd4ebf95c7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9d61586e3ca7fcfd input=a9049054013a1b77]*/ From b9c27327058de20da19eed742296a48e0e18586d Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:43:41 -0400 Subject: [PATCH 43/59] Switch options to argument clinic. --- Modules/_ssl.c | 23 +++++++++++++---- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 9f3b3e0da4f994..4428fbce4b3cb4 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3684,16 +3684,30 @@ get_security_level(PySSLContext *self, void *c) } PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.options +[clinic start generated code]*/ + static PyObject * -get_options(PySSLContext *self, void *c) +_ssl__SSLContext_options_get_impl(PySSLContext *self) +/*[clinic end generated code: output=3dfa6a74837f525b input=f5a2805c7cda6f25]*/ { uint64_t options = SSL_CTX_get_options(self->ctx); Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(options)); return PyLong_FromUnsignedLongLong(options); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.options +[clinic start generated code]*/ + static int -set_options(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=92ca34731ece5dbb input=2b94bf789e9ae5dd]*/ { PyObject *new_opts_obj; unsigned long long new_opts_arg; @@ -3703,7 +3717,7 @@ set_options(PySSLContext *self, PyObject *arg, void *c) SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3 ); - if (!PyArg_Parse(arg, "O!", &PyLong_Type, &new_opts_obj)) { + if (!PyArg_Parse(value, "O!", &PyLong_Type, &new_opts_obj)) { return -1; } new_opts_arg = PyLong_AsUnsignedLongLong(new_opts_obj); @@ -5072,8 +5086,7 @@ static PyGetSetDef context_getsetlist[] = { #if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3) _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF #endif - {"options", (getter) get_options, - (setter) set_options, NULL}, + _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"post_handshake_auth", (getter) get_post_handshake_auth, #if defined(PySSL_HAVE_POST_HS_AUTH) (setter) set_post_handshake_auth, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 6305e96c45ef2c..63fcecbcb475d4 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -1044,6 +1044,60 @@ _ssl__SSLContext_num_tickets_set(PySSLContext *self, PyObject *value, void *Py_U return return_value; } +#if defined(_ssl__SSLContext_options_HAS_DOCSTR) +# define _ssl__SSLContext_options_DOCSTR _ssl__SSLContext_options__doc__ +#else +# define _ssl__SSLContext_options_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_OPTIONS_GETSETDEF) +# undef _SSL__SSLCONTEXT_OPTIONS_GETSETDEF +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, (setter)_ssl__SSLContext_options_set, _ssl__SSLContext_options_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, NULL, _ssl__SSLContext_options_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_options_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_options_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_options_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_OPTIONS_HAS_DOCSTR) +# define _ssl__SSLContext_options_DOCSTR _ssl__SSLContext_options__doc__ +#else +# define _ssl__SSLContext_options_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_OPTIONS_GETSETDEF) +# undef _SSL__SSLCONTEXT_OPTIONS_GETSETDEF +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, (setter)_ssl__SSLContext_options_set, _ssl__SSLContext_options_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", NULL, (setter)_ssl__SSLContext_options_set, NULL}, +#endif + +static int +_ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_options_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_options_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext__host_flags_HAS_DOCSTR) # define _ssl__SSLContext__host_flags_DOCSTR _ssl__SSLContext__host_flags__doc__ #else @@ -2431,4 +2485,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=9d61586e3ca7fcfd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4f8d4d84a6974ef2 input=a9049054013a1b77]*/ From ae25f65168fb947b365ef6f10ad756f76579cccc Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:45:32 -0400 Subject: [PATCH 44/59] Switch protocol to argument clinic. --- Modules/_ssl.c | 13 ++++++++++--- Modules/clinic/_ssl.c.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 4428fbce4b3cb4..93ae6c36f59ccf 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3849,8 +3849,16 @@ set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) { } #endif +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.protocol +[clinic start generated code]*/ + static PyObject * -get_protocol(PySSLContext *self, void *c) { +_ssl__SSLContext_protocol_get_impl(PySSLContext *self) +/*[clinic end generated code: output=a9a48febc16cee22 input=c9f5fa1a2bd4b8a8]*/ +{ return PyLong_FromLong(self->protocol); } @@ -5094,8 +5102,7 @@ static PyGetSetDef context_getsetlist[] = { NULL, #endif NULL}, - {"protocol", (getter) get_protocol, - NULL, NULL}, + _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"verify_flags", (getter) get_verify_flags, (setter) set_verify_flags, NULL}, {"verify_mode", (getter) get_verify_mode, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 63fcecbcb475d4..fdddc28cc89a28 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -1206,6 +1206,33 @@ _ssl__SSLContext_check_hostname_set(PySSLContext *self, PyObject *value, void *P return return_value; } +#if defined(_ssl__SSLContext_protocol_HAS_DOCSTR) +# define _ssl__SSLContext_protocol_DOCSTR _ssl__SSLContext_protocol__doc__ +#else +# define _ssl__SSLContext_protocol_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_PROTOCOL_GETSETDEF) +# undef _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF +# define _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"protocol", (getter)_ssl__SSLContext_protocol_get, (setter)_ssl__SSLContext_protocol_set, _ssl__SSLContext_protocol_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"protocol", (getter)_ssl__SSLContext_protocol_get, NULL, _ssl__SSLContext_protocol_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_protocol_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_protocol_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_protocol_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl__SSLContext_load_cert_chain__doc__, "load_cert_chain($self, /, certfile, keyfile=None, password=None)\n" "--\n" @@ -2485,4 +2512,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=4f8d4d84a6974ef2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=26e79b114b8c43df input=a9049054013a1b77]*/ From 4950f45fc994c1a428c31040e0e0b4fc681f29b8 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:47:09 -0400 Subject: [PATCH 45/59] Switch verify_flags to argument clinic. --- Modules/_ssl.c | 23 +++++++++++++---- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 93ae6c36f59ccf..095060619e090c 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3441,8 +3441,15 @@ set_verify_mode(PySSLContext *self, PyObject *arg, void *c) return _set_verify_mode(self, n); } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.verify_flags +[clinic start generated code]*/ + static PyObject * -get_verify_flags(PySSLContext *self, void *c) +_ssl__SSLContext_verify_flags_get_impl(PySSLContext *self) +/*[clinic end generated code: output=fbbf8ba28ad6e56e input=c1ec36d610b3f391]*/ { X509_VERIFY_PARAM *param; unsigned long flags; @@ -3452,13 +3459,20 @@ get_verify_flags(PySSLContext *self, void *c) return PyLong_FromUnsignedLong(flags); } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.verify_flags +[clinic start generated code]*/ + static int -set_verify_flags(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=a3e3b2a0ce6c2e99 input=b2a0c42583d4f34e]*/ { X509_VERIFY_PARAM *param; unsigned long new_flags, flags, set, clear; - if (!PyArg_Parse(arg, "k", &new_flags)) + if (!PyArg_Parse(value, "k", &new_flags)) return -1; param = SSL_CTX_get0_param(self->ctx); flags = X509_VERIFY_PARAM_get_flags(param); @@ -5103,8 +5117,7 @@ static PyGetSetDef context_getsetlist[] = { #endif NULL}, _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF - {"verify_flags", (getter) get_verify_flags, - (setter) set_verify_flags, NULL}, + _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_mode", (getter) get_verify_mode, (setter) set_verify_mode, NULL}, {"security_level", (getter) get_security_level, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index fdddc28cc89a28..2868341661bfb0 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -880,6 +880,60 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) return return_value; } +#if defined(_ssl__SSLContext_verify_flags_HAS_DOCSTR) +# define _ssl__SSLContext_verify_flags_DOCSTR _ssl__SSLContext_verify_flags__doc__ +#else +# define _ssl__SSLContext_verify_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, (setter)_ssl__SSLContext_verify_flags_set, _ssl__SSLContext_verify_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, NULL, _ssl__SSLContext_verify_flags_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_verify_flags_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_verify_flags_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_flags_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_HAS_DOCSTR) +# define _ssl__SSLContext_verify_flags_DOCSTR _ssl__SSLContext_verify_flags__doc__ +#else +# define _ssl__SSLContext_verify_flags_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, (setter)_ssl__SSLContext_verify_flags_set, _ssl__SSLContext_verify_flags_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", NULL, (setter)_ssl__SSLContext_verify_flags_set, NULL}, +#endif + +static int +_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_verify_flags_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_flags_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext_minimum_version_HAS_DOCSTR) # define _ssl__SSLContext_minimum_version_DOCSTR _ssl__SSLContext_minimum_version__doc__ #else @@ -2512,4 +2566,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=26e79b114b8c43df input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6d9009cbbac4cf2f input=a9049054013a1b77]*/ From fee2d4f50785f157d203d2384ff6dcbc7b4148b9 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:48:35 -0400 Subject: [PATCH 46/59] Switch verify_mode to argument clinic. --- Modules/_ssl.c | 23 +++++++++++++---- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 095060619e090c..837aa7fd70485a 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3406,8 +3406,15 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, Py_RETURN_NONE; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.verify_mode +[clinic start generated code]*/ + static PyObject * -get_verify_mode(PySSLContext *self, void *c) +_ssl__SSLContext_verify_mode_get_impl(PySSLContext *self) +/*[clinic end generated code: output=3e788736cc7229bc input=7e3c7f4454121d0a]*/ { /* ignore SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_POST_HANDSHAKE */ int mask = (SSL_VERIFY_NONE | SSL_VERIFY_PEER | @@ -3426,11 +3433,18 @@ get_verify_mode(PySSLContext *self, void *c) return NULL; } +/*[clinic input] +@critical_section +@setter +_ssl._SSLContext.verify_mode +[clinic start generated code]*/ + static int -set_verify_mode(PySSLContext *self, PyObject *arg, void *c) +_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, PyObject *value) +/*[clinic end generated code: output=d698e16c58db3118 input=3ee60057c3a22378]*/ { int n; - if (!PyArg_Parse(arg, "i", &n)) + if (!PyArg_Parse(value, "i", &n)) return -1; if (n == PY_SSL_CERT_NONE && self->check_hostname) { PyErr_SetString(PyExc_ValueError, @@ -5118,8 +5132,7 @@ static PyGetSetDef context_getsetlist[] = { NULL}, _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF - {"verify_mode", (getter) get_verify_mode, - (setter) set_verify_mode, NULL}, + _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"security_level", (getter) get_security_level, NULL, PySSLContext_security_level_doc}, {NULL}, /* sentinel */ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 2868341661bfb0..40aa8351e873e5 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -880,6 +880,60 @@ _ssl__SSLContext__set_alpn_protocols(PySSLContext *self, PyObject *arg) return return_value; } +#if defined(_ssl__SSLContext_verify_mode_HAS_DOCSTR) +# define _ssl__SSLContext_verify_mode_DOCSTR _ssl__SSLContext_verify_mode__doc__ +#else +# define _ssl__SSLContext_verify_mode_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, (setter)_ssl__SSLContext_verify_mode_set, _ssl__SSLContext_verify_mode_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, NULL, _ssl__SSLContext_verify_mode_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_verify_mode_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_verify_mode_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_mode_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_HAS_DOCSTR) +# define _ssl__SSLContext_verify_mode_DOCSTR _ssl__SSLContext_verify_mode__doc__ +#else +# define _ssl__SSLContext_verify_mode_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF) +# undef _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, (setter)_ssl__SSLContext_verify_mode_set, _ssl__SSLContext_verify_mode_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", NULL, (setter)_ssl__SSLContext_verify_mode_set, NULL}, +#endif + +static int +_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, PyObject *value); + +static int +_ssl__SSLContext_verify_mode_set(PySSLContext *self, PyObject *value, void *Py_UNUSED(context)) +{ + int return_value; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_verify_mode_set_impl(self, value); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext_verify_flags_HAS_DOCSTR) # define _ssl__SSLContext_verify_flags_DOCSTR _ssl__SSLContext_verify_flags__doc__ #else @@ -2566,4 +2620,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=6d9009cbbac4cf2f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f2adf3bcedabfea3 input=a9049054013a1b77]*/ From 6449c954dc5007cfd2ef5df43b69cff389502f5b Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:51:31 -0400 Subject: [PATCH 47/59] Switch security_level to argument clinic. --- Modules/_ssl.c | 13 +++++++++---- Modules/clinic/_ssl.c.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 837aa7fd70485a..9c436de16efefe 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3704,13 +3704,19 @@ _ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, PyObject *value) return 0; } +/*[clinic input] +@critical_section +@getter +_ssl._SSLContext.security_level +[clinic start generated code]*/ + static PyObject * -get_security_level(PySSLContext *self, void *c) +_ssl__SSLContext_security_level_get_impl(PySSLContext *self) +/*[clinic end generated code: output=56ece09e6a9572d0 input=a0416598e07c3183]*/ { PyObject *res = PyLong_FromLong(SSL_CTX_get_security_level(self->ctx)); return res; } -PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); /*[clinic input] @critical_section @@ -5133,8 +5139,7 @@ static PyGetSetDef context_getsetlist[] = { _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF - {"security_level", (getter) get_security_level, - NULL, PySSLContext_security_level_doc}, + _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {NULL}, /* sentinel */ }; diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 40aa8351e873e5..8dce83b1b1e84e 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -1152,6 +1152,33 @@ _ssl__SSLContext_num_tickets_set(PySSLContext *self, PyObject *value, void *Py_U return return_value; } +#if defined(_ssl__SSLContext_security_level_HAS_DOCSTR) +# define _ssl__SSLContext_security_level_DOCSTR _ssl__SSLContext_security_level__doc__ +#else +# define _ssl__SSLContext_security_level_DOCSTR NULL +#endif +#if defined(_SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF) +# undef _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF +# define _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {"security_level", (getter)_ssl__SSLContext_security_level_get, (setter)_ssl__SSLContext_security_level_set, _ssl__SSLContext_security_level_DOCSTR}, +#else +# define _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {"security_level", (getter)_ssl__SSLContext_security_level_get, NULL, _ssl__SSLContext_security_level_DOCSTR}, +#endif + +static PyObject * +_ssl__SSLContext_security_level_get_impl(PySSLContext *self); + +static PyObject * +_ssl__SSLContext_security_level_get(PySSLContext *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl__SSLContext_security_level_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl__SSLContext_options_HAS_DOCSTR) # define _ssl__SSLContext_options_DOCSTR _ssl__SSLContext_options__doc__ #else @@ -2620,4 +2647,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=f2adf3bcedabfea3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5921bfbc09f4d44f input=a9049054013a1b77]*/ From a0fc838dc7e221575f0c9056659deeb170ea0a23 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:55:20 -0400 Subject: [PATCH 48/59] Switch MemoryBIO to argument clinic. --- Modules/_ssl.c | 28 +++++++++++++-------- Modules/clinic/_ssl.c.h | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 9c436de16efefe..525fb8ab9b2ea3 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5239,26 +5239,34 @@ memory_bio_dealloc(PySSLMemoryBIO *self) Py_DECREF(tp); } +/*[clinic input] +@critical_section +@getter +_ssl.MemoryBIO.pending +[clinic start generated code]*/ + static PyObject * -memory_bio_get_pending(PySSLMemoryBIO *self, void *c) +_ssl_MemoryBIO_pending_get_impl(PySSLMemoryBIO *self) +/*[clinic end generated code: output=19236a32a51ac8ff input=c0b6d14eba107f6a]*/ { size_t res = BIO_ctrl_pending(self->bio); return PyLong_FromSize_t(res); } -PyDoc_STRVAR(PySSL_memory_bio_pending_doc, -"The number of bytes pending in the memory BIO."); +/*[clinic input] +@critical_section +@getter +_ssl.MemoryBIO.eof +[clinic start generated code]*/ static PyObject * -memory_bio_get_eof(PySSLMemoryBIO *self, void *c) +_ssl_MemoryBIO_eof_get_impl(PySSLMemoryBIO *self) +/*[clinic end generated code: output=c255a9ea16e31b92 input=0f5c6be69752e04c]*/ { size_t pending = BIO_ctrl_pending(self->bio); return PyBool_FromLong((pending == 0) && self->eof_written); } -PyDoc_STRVAR(PySSL_memory_bio_eof_doc, -"Whether the memory BIO is at EOF."); - /*[clinic input] @critical_section _ssl.MemoryBIO.read @@ -5369,10 +5377,8 @@ _ssl_MemoryBIO_write_eof_impl(PySSLMemoryBIO *self) } static PyGetSetDef memory_bio_getsetlist[] = { - {"pending", (getter) memory_bio_get_pending, NULL, - PySSL_memory_bio_pending_doc}, - {"eof", (getter) memory_bio_get_eof, NULL, - PySSL_memory_bio_eof_doc}, + _SSL_MEMORYBIO_PENDING_GETSETDEF + _SSL_MEMORYBIO_EOF_GETSETDEF {NULL}, /* sentinel */ }; diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 8dce83b1b1e84e..a2e171e9c1e48e 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2121,6 +2121,60 @@ _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) return return_value; } +#if defined(_ssl_MemoryBIO_pending_HAS_DOCSTR) +# define _ssl_MemoryBIO_pending_DOCSTR _ssl_MemoryBIO_pending__doc__ +#else +# define _ssl_MemoryBIO_pending_DOCSTR NULL +#endif +#if defined(_SSL_MEMORYBIO_PENDING_GETSETDEF) +# undef _SSL_MEMORYBIO_PENDING_GETSETDEF +# define _SSL_MEMORYBIO_PENDING_GETSETDEF {"pending", (getter)_ssl_MemoryBIO_pending_get, (setter)_ssl_MemoryBIO_pending_set, _ssl_MemoryBIO_pending_DOCSTR}, +#else +# define _SSL_MEMORYBIO_PENDING_GETSETDEF {"pending", (getter)_ssl_MemoryBIO_pending_get, NULL, _ssl_MemoryBIO_pending_DOCSTR}, +#endif + +static PyObject * +_ssl_MemoryBIO_pending_get_impl(PySSLMemoryBIO *self); + +static PyObject * +_ssl_MemoryBIO_pending_get(PySSLMemoryBIO *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_MemoryBIO_pending_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + +#if defined(_ssl_MemoryBIO_eof_HAS_DOCSTR) +# define _ssl_MemoryBIO_eof_DOCSTR _ssl_MemoryBIO_eof__doc__ +#else +# define _ssl_MemoryBIO_eof_DOCSTR NULL +#endif +#if defined(_SSL_MEMORYBIO_EOF_GETSETDEF) +# undef _SSL_MEMORYBIO_EOF_GETSETDEF +# define _SSL_MEMORYBIO_EOF_GETSETDEF {"eof", (getter)_ssl_MemoryBIO_eof_get, (setter)_ssl_MemoryBIO_eof_set, _ssl_MemoryBIO_eof_DOCSTR}, +#else +# define _SSL_MEMORYBIO_EOF_GETSETDEF {"eof", (getter)_ssl_MemoryBIO_eof_get, NULL, _ssl_MemoryBIO_eof_DOCSTR}, +#endif + +static PyObject * +_ssl_MemoryBIO_eof_get_impl(PySSLMemoryBIO *self); + +static PyObject * +_ssl_MemoryBIO_eof_get(PySSLMemoryBIO *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_MemoryBIO_eof_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl_MemoryBIO_read__doc__, "read($self, size=-1, /)\n" "--\n" @@ -2647,4 +2701,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=5921bfbc09f4d44f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a006967d9642ce21 input=a9049054013a1b77]*/ From 8c4e20dceaabb01e22ddc968662f7bd19bfbb9a1 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:57:04 -0400 Subject: [PATCH 49/59] Switch has_ticket to argument clinic. --- Modules/_ssl.c | 13 ++++++++++--- Modules/clinic/_ssl.c.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 525fb8ab9b2ea3..8332a1998f8a8d 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5544,8 +5544,16 @@ PyDoc_STRVAR(PySSLSession_get_session_id_doc, "Session id"); +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.has_ticket +[clinic start generated code]*/ + static PyObject * -PySSLSession_get_has_ticket(PySSLSession *self, void *closure) { +_ssl_SSLSession_has_ticket_get_impl(PySSLSession *self) +/*[clinic end generated code: output=aa3ccfc40b10b96d input=1a48ae8955fa9601]*/ +{ int res = SSL_SESSION_has_ticket(self->session); return res ? Py_True : Py_False; } @@ -5555,8 +5563,7 @@ PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, static PyGetSetDef PySSLSession_getsetlist[] = { - {"has_ticket", (getter) PySSLSession_get_has_ticket, NULL, - PySSLSession_get_has_ticket_doc}, + _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"id", (getter) PySSLSession_get_session_id, NULL, PySSLSession_get_session_id_doc}, {"ticket_lifetime_hint", (getter) PySSLSession_get_ticket_lifetime_hint, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index a2e171e9c1e48e..103415a0098711 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2279,6 +2279,33 @@ _ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) return return_value; } +#if defined(_ssl_SSLSession_has_ticket_HAS_DOCSTR) +# define _ssl_SSLSession_has_ticket_DOCSTR _ssl_SSLSession_has_ticket__doc__ +#else +# define _ssl_SSLSession_has_ticket_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_HAS_TICKET_GETSETDEF) +# undef _SSL_SSLSESSION_HAS_TICKET_GETSETDEF +# define _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"has_ticket", (getter)_ssl_SSLSession_has_ticket_get, (setter)_ssl_SSLSession_has_ticket_set, _ssl_SSLSession_has_ticket_DOCSTR}, +#else +# define _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"has_ticket", (getter)_ssl_SSLSession_has_ticket_get, NULL, _ssl_SSLSession_has_ticket_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_has_ticket_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_has_ticket_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_has_ticket_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + PyDoc_STRVAR(_ssl_RAND_add__doc__, "RAND_add($module, string, entropy, /)\n" "--\n" @@ -2701,4 +2728,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=a006967d9642ce21 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3e62ae8f7ba3d7f9 input=a9049054013a1b77]*/ From 44f17826e4edfcb077cba905b75cc0394155677f Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:57:51 -0400 Subject: [PATCH 50/59] Switch session_id to argument clinic. --- Modules/_ssl.c | 14 +++++++++----- Modules/clinic/_ssl.c.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 8332a1998f8a8d..a2e4daeb71ccc0 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5532,18 +5532,22 @@ PyDoc_STRVAR(PySSLSession_get_ticket_lifetime_hint_doc, "Ticket life time hint."); +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.session_id +[clinic start generated code]*/ + static PyObject * -PySSLSession_get_session_id(PySSLSession *self, void *closure) { +_ssl_SSLSession_session_id_get_impl(PySSLSession *self) +/*[clinic end generated code: output=3882d1e7a7f8bab3 input=3a867b83fdff3183]*/ +{ const unsigned char *id; unsigned int len; id = SSL_SESSION_get_id(self->session, &len); return PyBytes_FromStringAndSize((const char *)id, len); } -PyDoc_STRVAR(PySSLSession_get_session_id_doc, -"Session id"); - - /*[clinic input] @critical_section @getter diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 103415a0098711..6b717f83fb5626 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2279,6 +2279,33 @@ _ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) return return_value; } +#if defined(_ssl_SSLSession_session_id_HAS_DOCSTR) +# define _ssl_SSLSession_session_id_DOCSTR _ssl_SSLSession_session_id__doc__ +#else +# define _ssl_SSLSession_session_id_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_SESSION_ID_GETSETDEF) +# undef _SSL_SSLSESSION_SESSION_ID_GETSETDEF +# define _SSL_SSLSESSION_SESSION_ID_GETSETDEF {"session_id", (getter)_ssl_SSLSession_session_id_get, (setter)_ssl_SSLSession_session_id_set, _ssl_SSLSession_session_id_DOCSTR}, +#else +# define _SSL_SSLSESSION_SESSION_ID_GETSETDEF {"session_id", (getter)_ssl_SSLSession_session_id_get, NULL, _ssl_SSLSession_session_id_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_session_id_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_session_id_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_session_id_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl_SSLSession_has_ticket_HAS_DOCSTR) # define _ssl_SSLSession_has_ticket_DOCSTR _ssl_SSLSession_has_ticket__doc__ #else @@ -2728,4 +2755,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=3e62ae8f7ba3d7f9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9cc4a80ccece933a input=a9049054013a1b77]*/ From 216c318dc5b171b50cf8a4c3109a8d9c79cd0849 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 18:59:21 -0400 Subject: [PATCH 51/59] Switch ticket_lifetime_hint to argument clinic. --- Modules/_ssl.c | 20 +++++++++++--------- Modules/clinic/_ssl.c.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a2e4daeb71ccc0..176326bee5c160 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5522,16 +5522,20 @@ PyDoc_STRVAR(PySSLSession_get_timeout_doc, "Session timeout (delta in seconds)."); +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.ticket_lifetime_hint +[clinic start generated code]*/ + static PyObject * -PySSLSession_get_ticket_lifetime_hint(PySSLSession *self, void *closure) { +_ssl_SSLSession_ticket_lifetime_hint_get_impl(PySSLSession *self) +/*[clinic end generated code: output=c8b6db498136c275 input=d0e06942ddd8d07f]*/ +{ unsigned long hint = SSL_SESSION_get_ticket_lifetime_hint(self->session); return PyLong_FromUnsignedLong(hint); } -PyDoc_STRVAR(PySSLSession_get_ticket_lifetime_hint_doc, -"Ticket life time hint."); - - /*[clinic input] @critical_section @getter @@ -5568,10 +5572,8 @@ PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, static PyGetSetDef PySSLSession_getsetlist[] = { _SSL_SSLSESSION_HAS_TICKET_GETSETDEF - {"id", (getter) PySSLSession_get_session_id, NULL, - PySSLSession_get_session_id_doc}, - {"ticket_lifetime_hint", (getter) PySSLSession_get_ticket_lifetime_hint, - NULL, PySSLSession_get_ticket_lifetime_hint_doc}, + _SSL_SSLSESSION_SESSION_ID_GETSETDEF + _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"time", (getter) PySSLSession_get_time, NULL, PySSLSession_get_time_doc}, {"timeout", (getter) PySSLSession_get_timeout, NULL, diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 6b717f83fb5626..3968729d6aa5c6 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2279,6 +2279,33 @@ _ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) return return_value; } +#if defined(_ssl_SSLSession_ticket_lifetime_hint_HAS_DOCSTR) +# define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR _ssl_SSLSession_ticket_lifetime_hint__doc__ +#else +# define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF) +# undef _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF +# define _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"ticket_lifetime_hint", (getter)_ssl_SSLSession_ticket_lifetime_hint_get, (setter)_ssl_SSLSession_ticket_lifetime_hint_set, _ssl_SSLSession_ticket_lifetime_hint_DOCSTR}, +#else +# define _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"ticket_lifetime_hint", (getter)_ssl_SSLSession_ticket_lifetime_hint_get, NULL, _ssl_SSLSession_ticket_lifetime_hint_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_ticket_lifetime_hint_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_ticket_lifetime_hint_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_ticket_lifetime_hint_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl_SSLSession_session_id_HAS_DOCSTR) # define _ssl_SSLSession_session_id_DOCSTR _ssl_SSLSession_session_id__doc__ #else @@ -2755,4 +2782,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=9cc4a80ccece933a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f09b15ce11130fd6 input=a9049054013a1b77]*/ From 701bf00f876c11801202402c77428c7ad73f6f9a Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 19:01:18 -0400 Subject: [PATCH 52/59] Switch time to argument clinic. --- Modules/_ssl.c | 18 ++++++++++-------- Modules/clinic/_ssl.c.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 176326bee5c160..70a5eb458f0df9 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5498,8 +5498,16 @@ PySSLSession_clear(PySSLSession *self) } +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.time +[clinic start generated code]*/ + static PyObject * -PySSLSession_get_time(PySSLSession *self, void *closure) { +_ssl_SSLSession_time_get_impl(PySSLSession *self) +/*[clinic end generated code: output=4b887b9299de9be4 input=8d1e4afd09103279]*/ +{ #if OPENSSL_VERSION_NUMBER >= 0x30300000L return _PyLong_FromTime_t(SSL_SESSION_get_time_ex(self->session)); #else @@ -5507,10 +5515,6 @@ PySSLSession_get_time(PySSLSession *self, void *closure) { #endif } -PyDoc_STRVAR(PySSLSession_get_time_doc, -"Session creation time (seconds since epoch)."); - - static PyObject * PySSLSession_get_timeout(PySSLSession *self, void *closure) { long timeout = SSL_SESSION_get_timeout(self->session); @@ -5521,7 +5525,6 @@ PySSLSession_get_timeout(PySSLSession *self, void *closure) { PyDoc_STRVAR(PySSLSession_get_timeout_doc, "Session timeout (delta in seconds)."); - /*[clinic input] @critical_section @getter @@ -5574,8 +5577,7 @@ static PyGetSetDef PySSLSession_getsetlist[] = { _SSL_SSLSESSION_HAS_TICKET_GETSETDEF _SSL_SSLSESSION_SESSION_ID_GETSETDEF _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF - {"time", (getter) PySSLSession_get_time, NULL, - PySSLSession_get_time_doc}, + _SSL_SSLSESSION_TIME_GETSETDEF {"timeout", (getter) PySSLSession_get_timeout, NULL, PySSLSession_get_timeout_doc}, {NULL}, /* sentinel */ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 3968729d6aa5c6..c8a86e3b119659 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2279,6 +2279,33 @@ _ssl_MemoryBIO_write_eof(PySSLMemoryBIO *self, PyObject *Py_UNUSED(ignored)) return return_value; } +#if defined(_ssl_SSLSession_time_HAS_DOCSTR) +# define _ssl_SSLSession_time_DOCSTR _ssl_SSLSession_time__doc__ +#else +# define _ssl_SSLSession_time_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_TIME_GETSETDEF) +# undef _SSL_SSLSESSION_TIME_GETSETDEF +# define _SSL_SSLSESSION_TIME_GETSETDEF {"time", (getter)_ssl_SSLSession_time_get, (setter)_ssl_SSLSession_time_set, _ssl_SSLSession_time_DOCSTR}, +#else +# define _SSL_SSLSESSION_TIME_GETSETDEF {"time", (getter)_ssl_SSLSession_time_get, NULL, _ssl_SSLSession_time_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_time_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_time_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_time_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl_SSLSession_ticket_lifetime_hint_HAS_DOCSTR) # define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR _ssl_SSLSession_ticket_lifetime_hint__doc__ #else @@ -2782,4 +2809,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=f09b15ce11130fd6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6a8338feec145d07 input=a9049054013a1b77]*/ From ffc48793785ba695ca64f5a659e0340ec7f2990a Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 19:02:22 -0400 Subject: [PATCH 53/59] Switch timeout to argument clinic. --- Modules/_ssl.c | 16 ++++++++++------ Modules/clinic/_ssl.c.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 70a5eb458f0df9..94f100d5306ebb 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5515,16 +5515,21 @@ _ssl_SSLSession_time_get_impl(PySSLSession *self) #endif } +/*[clinic input] +@critical_section +@getter +_ssl.SSLSession.timeout +[clinic start generated code]*/ + static PyObject * -PySSLSession_get_timeout(PySSLSession *self, void *closure) { +_ssl_SSLSession_timeout_get_impl(PySSLSession *self) +/*[clinic end generated code: output=82339c148ab2f7d1 input=ae5e84a9d85df60d]*/ +{ long timeout = SSL_SESSION_get_timeout(self->session); PyObject *res = PyLong_FromLong(timeout); return res; } -PyDoc_STRVAR(PySSLSession_get_timeout_doc, -"Session timeout (delta in seconds)."); - /*[clinic input] @critical_section @getter @@ -5578,8 +5583,7 @@ static PyGetSetDef PySSLSession_getsetlist[] = { _SSL_SSLSESSION_SESSION_ID_GETSETDEF _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF _SSL_SSLSESSION_TIME_GETSETDEF - {"timeout", (getter) PySSLSession_get_timeout, NULL, - PySSLSession_get_timeout_doc}, + _SSL_SSLSESSION_TIMEOUT_GETSETDEF {NULL}, /* sentinel */ }; diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index c8a86e3b119659..439b8f41aaf0da 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2306,6 +2306,33 @@ _ssl_SSLSession_time_get(PySSLSession *self, void *Py_UNUSED(context)) return return_value; } +#if defined(_ssl_SSLSession_timeout_HAS_DOCSTR) +# define _ssl_SSLSession_timeout_DOCSTR _ssl_SSLSession_timeout__doc__ +#else +# define _ssl_SSLSession_timeout_DOCSTR NULL +#endif +#if defined(_SSL_SSLSESSION_TIMEOUT_GETSETDEF) +# undef _SSL_SSLSESSION_TIMEOUT_GETSETDEF +# define _SSL_SSLSESSION_TIMEOUT_GETSETDEF {"timeout", (getter)_ssl_SSLSession_timeout_get, (setter)_ssl_SSLSession_timeout_set, _ssl_SSLSession_timeout_DOCSTR}, +#else +# define _SSL_SSLSESSION_TIMEOUT_GETSETDEF {"timeout", (getter)_ssl_SSLSession_timeout_get, NULL, _ssl_SSLSession_timeout_DOCSTR}, +#endif + +static PyObject * +_ssl_SSLSession_timeout_get_impl(PySSLSession *self); + +static PyObject * +_ssl_SSLSession_timeout_get(PySSLSession *self, void *Py_UNUSED(context)) +{ + PyObject *return_value = NULL; + + Py_BEGIN_CRITICAL_SECTION(self); + return_value = _ssl_SSLSession_timeout_get_impl(self); + Py_END_CRITICAL_SECTION(); + + return return_value; +} + #if defined(_ssl_SSLSession_ticket_lifetime_hint_HAS_DOCSTR) # define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR _ssl_SSLSession_ticket_lifetime_hint__doc__ #else @@ -2809,4 +2836,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=6a8338feec145d07 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=139101c7caeefcae input=a9049054013a1b77]*/ From ebd621bc5f3d8102686caadccb19272a4baf5efe Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 19:09:41 -0400 Subject: [PATCH 54/59] Fix name inconsistency. --- Modules/_ssl.c | 9 +++++---- Modules/clinic/_ssl.c.h | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 94f100d5306ebb..17fb44cb634be1 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5547,12 +5547,13 @@ _ssl_SSLSession_ticket_lifetime_hint_get_impl(PySSLSession *self) /*[clinic input] @critical_section @getter -_ssl.SSLSession.session_id +_ssl.SSLSession.id [clinic start generated code]*/ static PyObject * -_ssl_SSLSession_session_id_get_impl(PySSLSession *self) -/*[clinic end generated code: output=3882d1e7a7f8bab3 input=3a867b83fdff3183]*/ +_ssl_SSLSession_id_get_impl(PySSLSession *self) +/*[clinic end generated code: output=c532fb96b10c5adf input=e7322372cf6325dd]*/ + { const unsigned char *id; unsigned int len; @@ -5580,7 +5581,7 @@ PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, static PyGetSetDef PySSLSession_getsetlist[] = { _SSL_SSLSESSION_HAS_TICKET_GETSETDEF - _SSL_SSLSESSION_SESSION_ID_GETSETDEF + _SSL_SSLSESSION_ID_GETSETDEF _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF _SSL_SSLSESSION_TIME_GETSETDEF _SSL_SSLSESSION_TIMEOUT_GETSETDEF diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 439b8f41aaf0da..91ba19e183767e 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2360,28 +2360,28 @@ _ssl_SSLSession_ticket_lifetime_hint_get(PySSLSession *self, void *Py_UNUSED(con return return_value; } -#if defined(_ssl_SSLSession_session_id_HAS_DOCSTR) -# define _ssl_SSLSession_session_id_DOCSTR _ssl_SSLSession_session_id__doc__ +#if defined(_ssl_SSLSession_id_HAS_DOCSTR) +# define _ssl_SSLSession_id_DOCSTR _ssl_SSLSession_id__doc__ #else -# define _ssl_SSLSession_session_id_DOCSTR NULL +# define _ssl_SSLSession_id_DOCSTR NULL #endif -#if defined(_SSL_SSLSESSION_SESSION_ID_GETSETDEF) -# undef _SSL_SSLSESSION_SESSION_ID_GETSETDEF -# define _SSL_SSLSESSION_SESSION_ID_GETSETDEF {"session_id", (getter)_ssl_SSLSession_session_id_get, (setter)_ssl_SSLSession_session_id_set, _ssl_SSLSession_session_id_DOCSTR}, +#if defined(_SSL_SSLSESSION_ID_GETSETDEF) +# undef _SSL_SSLSESSION_ID_GETSETDEF +# define _SSL_SSLSESSION_ID_GETSETDEF {"id", (getter)_ssl_SSLSession_id_get, (setter)_ssl_SSLSession_id_set, _ssl_SSLSession_id_DOCSTR}, #else -# define _SSL_SSLSESSION_SESSION_ID_GETSETDEF {"session_id", (getter)_ssl_SSLSession_session_id_get, NULL, _ssl_SSLSession_session_id_DOCSTR}, +# define _SSL_SSLSESSION_ID_GETSETDEF {"id", (getter)_ssl_SSLSession_id_get, NULL, _ssl_SSLSession_id_DOCSTR}, #endif static PyObject * -_ssl_SSLSession_session_id_get_impl(PySSLSession *self); +_ssl_SSLSession_id_get_impl(PySSLSession *self); static PyObject * -_ssl_SSLSession_session_id_get(PySSLSession *self, void *Py_UNUSED(context)) +_ssl_SSLSession_id_get(PySSLSession *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _ssl_SSLSession_session_id_get_impl(self); + return_value = _ssl_SSLSession_id_get_impl(self); Py_END_CRITICAL_SECTION(); return return_value; @@ -2836,4 +2836,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=139101c7caeefcae input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4d8f9eb33016974 input=a9049054013a1b77]*/ From 3b81e78ae2e42d75f05ae01396d43706c6e2849c Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 19:17:57 -0400 Subject: [PATCH 55/59] Fix build complaints. --- Modules/_ssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 17fb44cb634be1..3755bd8882b8a8 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -4755,6 +4755,7 @@ X509_STORE_get1_objects(X509_STORE *store) ret = sk_X509_OBJECT_deep_copy(X509_STORE_get0_objects(store), x509_object_dup, X509_OBJECT_free); X509_STORE_unlock(store); + return ret; } #endif From e7e0f470918cce18736b9d569a0846f366b88ebb Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Thu, 10 Oct 2024 19:18:44 -0400 Subject: [PATCH 56/59] Fix more build complaints. --- Modules/_ssl.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 3755bd8882b8a8..3c70c8120987c0 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5576,10 +5576,6 @@ _ssl_SSLSession_has_ticket_get_impl(PySSLSession *self) return res ? Py_True : Py_False; } -PyDoc_STRVAR(PySSLSession_get_has_ticket_doc, -"Does the session contain a ticket?"); - - static PyGetSetDef PySSLSession_getsetlist[] = { _SSL_SSLSESSION_HAS_TICKET_GETSETDEF _SSL_SSLSESSION_ID_GETSETDEF From 8cf4992da91cb1aba5e5033ec7f62becaebd8a62 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 11 Oct 2024 07:12:25 -0400 Subject: [PATCH 57/59] Fix failing builds. --- Modules/_ssl.c | 8 ++------ Modules/clinic/_ssl.c.h | 10 +--------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 3c70c8120987c0..62a94314512dd9 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2232,13 +2232,11 @@ _ssl__SSLSocket_server_hostname_get_impl(PySSLSocket *self) @critical_section @getter _ssl._SSLSocket.owner - -The Python-level owner of this object. Passed as "self" in servername callback. [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_owner_get_impl(PySSLSocket *self) -/*[clinic end generated code: output=1f278cb930382927 input=57fd0d5f2644757a]*/ +/*[clinic end generated code: output=1f278cb930382927 input=bc2861ff3cf1402e]*/ { if (self->owner == NULL) { Py_RETURN_NONE; @@ -2852,13 +2850,11 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self) @critical_section @getter _ssl._SSLSocket.session - -Get / set SSLSession. [clinic start generated code]*/ static PyObject * _ssl__SSLSocket_session_get_impl(PySSLSocket *self) -/*[clinic end generated code: output=a5cd5755b35da670 input=be77165ad3547c3d]*/ +/*[clinic end generated code: output=a5cd5755b35da670 input=b9792df9255a9f63]*/ { /* get_session can return sessions from a server-side connection, * it does not check for handshake done or client socket. */ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 91ba19e183767e..9d5b70dfad553d 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -374,10 +374,6 @@ _ssl__SSLSocket_server_hostname_get(PySSLSocket *self, void *Py_UNUSED(context)) return return_value; } -PyDoc_STRVAR(_ssl__SSLSocket_owner__doc__, -"The Python-level owner of this object. Passed as \"self\" in servername callback."); -#define _ssl__SSLSocket_owner_HAS_DOCSTR - #if defined(_ssl__SSLSocket_owner_HAS_DOCSTR) # define _ssl__SSLSocket_owner_DOCSTR _ssl__SSLSocket_owner__doc__ #else @@ -667,10 +663,6 @@ _ssl__SSLSocket_verify_client_post_handshake(PySSLSocket *self, PyObject *Py_UNU return return_value; } -PyDoc_STRVAR(_ssl__SSLSocket_session__doc__, -"Get / set SSLSession."); -#define _ssl__SSLSocket_session_HAS_DOCSTR - #if defined(_ssl__SSLSocket_session_HAS_DOCSTR) # define _ssl__SSLSocket_session_DOCSTR _ssl__SSLSocket_session__doc__ #else @@ -2836,4 +2828,4 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=b4d8f9eb33016974 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c1489122072a9f5e input=a9049054013a1b77]*/ From d9152afde918e32fa5379b2be593fae7eb399b41 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Fri, 18 Oct 2024 12:53:10 +0000 Subject: [PATCH 58/59] Clarify comment and use catch_threading_exception() --- Lib/test/test_ssl.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 3453ccde0d414d..4a87bb33865139 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2815,7 +2815,7 @@ def test_echo(self): @unittest.skipUnless(support.Py_GIL_DISABLED, "test is only useful if the GIL is disabled") def test_ssl_in_multiple_threads(self): - # See GH-124984 + # See GH-124984: OpenSSL is not thread safe. threads = [] global USE_SAME_TEST_CONTEXT @@ -2836,13 +2836,15 @@ def test_ssl_in_multiple_threads(self): with self.subTest(func=func, num=num): threads.append(Thread(target=func)) - for thread in threads: - with self.subTest(thread=thread): - thread.start() + with threading_helper.catch_threading_exception() as cm: + for thread in threads: + with self.subTest(thread=thread): + thread.start() - for thread in threads: - with self.subTest(thread=thread): - thread.join() + for thread in threads: + with self.subTest(thread=thread): + thread.join() + self.assertIsNone(cm.exc_value) finally: USE_SAME_TEST_CONTEXT = False From 07f848c9e3adc48c589dd3f0957bed127af29f89 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 19 Oct 2024 12:40:12 -0400 Subject: [PATCH 59/59] Check for SkipTest in exc_value. --- Lib/test/test_ssl.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 4a87bb33865139..0442493d894c7d 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2844,7 +2844,10 @@ def test_ssl_in_multiple_threads(self): for thread in threads: with self.subTest(thread=thread): thread.join() - self.assertIsNone(cm.exc_value) + if cm.exc_value is not None: + # Some threads can skip their test + if not isinstance(cm.exc_value, unittest.SkipTest): + raise cm.exc_value finally: USE_SAME_TEST_CONTEXT = False