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()
@@ -5153,12 +5154,15 @@ _servername_callback(SSL *s, int *al, void *args)
51535154 PyObject * result ;
51545155 /* The high-level ssl.SSLSocket object */
51555156 PyObject * ssl_socket ;
5157+ PyObject * sni_cb ;
51565158 const char * servername = SSL_get_servername (s , TLSEXT_NAMETYPE_host_name );
51575159 PyGILState_STATE gstate = PyGILState_Ensure ();
51585160
5159- if (sslctx -> set_sni_cb == NULL ) {
5160- /* remove race condition in this the call back while if removing the
5161- * callback is in progress */
5161+ Py_BEGIN_CRITICAL_SECTION (sslctx );
5162+ sni_cb = Py_XNewRef (sslctx -> set_sni_cb );
5163+ Py_END_CRITICAL_SECTION ();
5164+
5165+ if (sni_cb == NULL ) {
51625166 PyGILState_Release (gstate );
51635167 return SSL_TLSEXT_ERR_OK ;
51645168 }
@@ -5185,7 +5189,7 @@ _servername_callback(SSL *s, int *al, void *args)
51855189 goto error ;
51865190
51875191 if (servername == NULL ) {
5188- result = PyObject_CallFunctionObjArgs (sslctx -> set_sni_cb , ssl_socket ,
5192+ result = PyObject_CallFunctionObjArgs (sni_cb , ssl_socket ,
51895193 Py_None , sslctx , NULL );
51905194 }
51915195 else {
@@ -5212,7 +5216,7 @@ _servername_callback(SSL *s, int *al, void *args)
52125216 }
52135217 Py_DECREF (servername_bytes );
52145218 result = PyObject_CallFunctionObjArgs (
5215- sslctx -> set_sni_cb , ssl_socket , servername_str ,
5219+ sni_cb , ssl_socket , servername_str ,
52165220 sslctx , NULL );
52175221 Py_DECREF (servername_str );
52185222 }
@@ -5222,7 +5226,7 @@ _servername_callback(SSL *s, int *al, void *args)
52225226 PyErr_FormatUnraisable ("Exception ignored "
52235227 "in ssl servername callback "
52245228 "while calling set SNI callback %R" ,
5225- sslctx -> set_sni_cb );
5229+ sni_cb );
52265230 * al = SSL_AD_HANDSHAKE_FAILURE ;
52275231 ret = SSL_TLSEXT_ERR_ALERT_FATAL ;
52285232 }
@@ -5247,11 +5251,13 @@ _servername_callback(SSL *s, int *al, void *args)
52475251 Py_DECREF (result );
52485252 }
52495253
5254+ Py_DECREF (sni_cb );
52505255 PyGILState_Release (gstate );
52515256 return ret ;
52525257
52535258error :
52545259 Py_XDECREF (ssl_socket );
5260+ Py_XDECREF (sni_cb );
52555261 * al = SSL_AD_INTERNAL_ERROR ;
52565262 ret = SSL_TLSEXT_ERR_ALERT_FATAL ;
52575263 PyGILState_Release (gstate );
@@ -5301,20 +5307,18 @@ _ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value)
53015307 "sni_callback cannot be set on TLS_CLIENT context" );
53025308 return -1 ;
53035309 }
5304- Py_CLEAR (self -> set_sni_cb );
5305- if (value == Py_None ) {
5310+ if (!PyCallable_Check (value )) {
53065311 SSL_CTX_set_tlsext_servername_callback (self -> ctx , NULL );
5307- }
5308- else {
5309- if (!PyCallable_Check (value )) {
5310- SSL_CTX_set_tlsext_servername_callback (self -> ctx , NULL );
5311- PyErr_SetString (PyExc_TypeError ,
5312- "not a callable object" );
5312+ Py_CLEAR (self -> set_sni_cb );
5313+ if (value != Py_None ) {
5314+ PyErr_SetString (PyExc_TypeError , "not a callable object" );
53135315 return -1 ;
53145316 }
5315- self -> set_sni_cb = Py_NewRef (value );
5316- SSL_CTX_set_tlsext_servername_callback (self -> ctx , _servername_callback );
5317+ }
5318+ else {
5319+ Py_XSETREF (self -> set_sni_cb , Py_NewRef (value ));
53175320 SSL_CTX_set_tlsext_servername_arg (self -> ctx , self );
5321+ SSL_CTX_set_tlsext_servername_callback (self -> ctx , _servername_callback );
53185322 }
53195323 return 0 ;
53205324}
0 commit comments