2626#define OPENSSL_NO_DEPRECATED 1
2727
2828#include "Python.h"
29+ #include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
2930#include "pycore_fileutils.h" // _PyIsSelectable_fd()
3031#include "pycore_long.h" // _PyLong_UnsignedLongLong_Converter()
3132#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
@@ -5151,12 +5152,15 @@ _servername_callback(SSL *s, int *al, void *args)
51515152 PyObject * result ;
51525153 /* The high-level ssl.SSLSocket object */
51535154 PyObject * ssl_socket ;
5155+ PyObject * sni_cb ;
51545156 const char * servername = SSL_get_servername (s , TLSEXT_NAMETYPE_host_name );
51555157 PyGILState_STATE gstate = PyGILState_Ensure ();
51565158
5157- if (sslctx -> set_sni_cb == NULL ) {
5158- /* remove race condition in this the call back while if removing the
5159- * callback is in progress */
5159+ Py_BEGIN_CRITICAL_SECTION (sslctx );
5160+ sni_cb = Py_XNewRef (sslctx -> set_sni_cb );
5161+ Py_END_CRITICAL_SECTION ();
5162+
5163+ if (sni_cb == NULL ) {
51605164 PyGILState_Release (gstate );
51615165 return SSL_TLSEXT_ERR_OK ;
51625166 }
@@ -5183,7 +5187,7 @@ _servername_callback(SSL *s, int *al, void *args)
51835187 goto error ;
51845188
51855189 if (servername == NULL ) {
5186- result = PyObject_CallFunctionObjArgs (sslctx -> set_sni_cb , ssl_socket ,
5190+ result = PyObject_CallFunctionObjArgs (sni_cb , ssl_socket ,
51875191 Py_None , sslctx , NULL );
51885192 }
51895193 else {
@@ -5210,7 +5214,7 @@ _servername_callback(SSL *s, int *al, void *args)
52105214 }
52115215 Py_DECREF (servername_bytes );
52125216 result = PyObject_CallFunctionObjArgs (
5213- sslctx -> set_sni_cb , ssl_socket , servername_str ,
5217+ sni_cb , ssl_socket , servername_str ,
52145218 sslctx , NULL );
52155219 Py_DECREF (servername_str );
52165220 }
@@ -5220,7 +5224,7 @@ _servername_callback(SSL *s, int *al, void *args)
52205224 PyErr_FormatUnraisable ("Exception ignored "
52215225 "in ssl servername callback "
52225226 "while calling set SNI callback %R" ,
5223- sslctx -> set_sni_cb );
5227+ sni_cb );
52245228 * al = SSL_AD_HANDSHAKE_FAILURE ;
52255229 ret = SSL_TLSEXT_ERR_ALERT_FATAL ;
52265230 }
@@ -5245,11 +5249,13 @@ _servername_callback(SSL *s, int *al, void *args)
52455249 Py_DECREF (result );
52465250 }
52475251
5252+ Py_DECREF (sni_cb );
52485253 PyGILState_Release (gstate );
52495254 return ret ;
52505255
52515256error :
52525257 Py_XDECREF (ssl_socket );
5258+ Py_XDECREF (sni_cb );
52535259 * al = SSL_AD_INTERNAL_ERROR ;
52545260 ret = SSL_TLSEXT_ERR_ALERT_FATAL ;
52555261 PyGILState_Release (gstate );
@@ -5298,20 +5304,18 @@ _ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value)
52985304 "sni_callback cannot be set on TLS_CLIENT context" );
52995305 return -1 ;
53005306 }
5301- Py_CLEAR (self -> set_sni_cb );
5302- if (value == Py_None ) {
5307+ if (!PyCallable_Check (value )) {
53035308 SSL_CTX_set_tlsext_servername_callback (self -> ctx , NULL );
5304- }
5305- else {
5306- if (!PyCallable_Check (value )) {
5307- SSL_CTX_set_tlsext_servername_callback (self -> ctx , NULL );
5308- PyErr_SetString (PyExc_TypeError ,
5309- "not a callable object" );
5309+ Py_CLEAR (self -> set_sni_cb );
5310+ if (value != Py_None ) {
5311+ PyErr_SetString (PyExc_TypeError , "not a callable object" );
53105312 return -1 ;
53115313 }
5312- self -> set_sni_cb = Py_NewRef (value );
5313- SSL_CTX_set_tlsext_servername_callback (self -> ctx , _servername_callback );
5314+ }
5315+ else {
5316+ Py_XSETREF (self -> set_sni_cb , Py_NewRef (value ));
53145317 SSL_CTX_set_tlsext_servername_arg (self -> ctx , self );
5318+ SSL_CTX_set_tlsext_servername_callback (self -> ctx , _servername_callback );
53155319 }
53165320 return 0 ;
53175321}
0 commit comments