[3.7] bpo-24334: Cleanup SSLSocket (GH-5252) (#5857)
* The SSLSocket is no longer implemented on top of SSLObject to
avoid an extra level of indirection.
* Owner and session are now handled in the internal constructor.
* _ssl._SSLSocket now uses the same method names as SSLSocket and
SSLObject.
* Channel binding type check is now handled in C code. Channel binding
is always available.
The patch also changes the signature of SSLObject.__init__(). In my
opinion it's fine. A SSLObject is not a user-constructable object.
SSLContext.wrap_bio() is the only valid factory.
(cherry picked from commit 141c5e8c24
)
Co-authored-by: Christian Heimes <christian@python.org>
This commit is contained in:
parent
d24c5a068c
commit
8fa8478dde
116
Lib/ssl.py
116
Lib/ssl.py
|
@ -166,10 +166,7 @@ import warnings
|
||||||
|
|
||||||
socket_error = OSError # keep that public name in module namespace
|
socket_error = OSError # keep that public name in module namespace
|
||||||
|
|
||||||
if _ssl.HAS_TLS_UNIQUE:
|
CHANNEL_BINDING_TYPES = ['tls-unique']
|
||||||
CHANNEL_BINDING_TYPES = ['tls-unique']
|
|
||||||
else:
|
|
||||||
CHANNEL_BINDING_TYPES = []
|
|
||||||
|
|
||||||
HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')
|
HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')
|
||||||
|
|
||||||
|
@ -407,11 +404,11 @@ class SSLContext(_SSLContext):
|
||||||
server_hostname=None, session=None):
|
server_hostname=None, session=None):
|
||||||
# Need to encode server_hostname here because _wrap_bio() can only
|
# Need to encode server_hostname here because _wrap_bio() can only
|
||||||
# handle ASCII str.
|
# handle ASCII str.
|
||||||
sslobj = self._wrap_bio(
|
return self.sslobject_class(
|
||||||
incoming, outgoing, server_side=server_side,
|
incoming, outgoing, server_side=server_side,
|
||||||
server_hostname=self._encode_hostname(server_hostname)
|
server_hostname=self._encode_hostname(server_hostname),
|
||||||
|
session=session, _context=self,
|
||||||
)
|
)
|
||||||
return self.sslobject_class(sslobj, session=session)
|
|
||||||
|
|
||||||
def set_npn_protocols(self, npn_protocols):
|
def set_npn_protocols(self, npn_protocols):
|
||||||
protos = bytearray()
|
protos = bytearray()
|
||||||
|
@ -616,12 +613,13 @@ class SSLObject:
|
||||||
* The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery.
|
* The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sslobj, owner=None, session=None):
|
def __init__(self, incoming, outgoing, server_side=False,
|
||||||
self._sslobj = sslobj
|
server_hostname=None, session=None, _context=None):
|
||||||
# Note: _sslobj takes a weak reference to owner
|
self._sslobj = _context._wrap_bio(
|
||||||
self._sslobj.owner = owner or self
|
incoming, outgoing, server_side=server_side,
|
||||||
if session is not None:
|
server_hostname=server_hostname,
|
||||||
self._sslobj.session = session
|
owner=self, session=session
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def context(self):
|
def context(self):
|
||||||
|
@ -684,7 +682,7 @@ class SSLObject:
|
||||||
Return None if no certificate was provided, {} if a certificate was
|
Return None if no certificate was provided, {} if a certificate was
|
||||||
provided, but not validated.
|
provided, but not validated.
|
||||||
"""
|
"""
|
||||||
return self._sslobj.peer_certificate(binary_form)
|
return self._sslobj.getpeercert(binary_form)
|
||||||
|
|
||||||
def selected_npn_protocol(self):
|
def selected_npn_protocol(self):
|
||||||
"""Return the currently selected NPN protocol as a string, or ``None``
|
"""Return the currently selected NPN protocol as a string, or ``None``
|
||||||
|
@ -732,13 +730,7 @@ class SSLObject:
|
||||||
"""Get channel binding data for current connection. Raise ValueError
|
"""Get channel binding data for current connection. Raise ValueError
|
||||||
if the requested `cb_type` is not supported. Return bytes of the data
|
if the requested `cb_type` is not supported. Return bytes of the data
|
||||||
or None if the data is not available (e.g. before the handshake)."""
|
or None if the data is not available (e.g. before the handshake)."""
|
||||||
if cb_type not in CHANNEL_BINDING_TYPES:
|
return self._sslobj.get_channel_binding(cb_type)
|
||||||
raise ValueError("Unsupported channel binding type")
|
|
||||||
if cb_type != "tls-unique":
|
|
||||||
raise NotImplementedError(
|
|
||||||
"{0} channel binding type not implemented"
|
|
||||||
.format(cb_type))
|
|
||||||
return self._sslobj.tls_unique_cb()
|
|
||||||
|
|
||||||
def version(self):
|
def version(self):
|
||||||
"""Return a string identifying the protocol version used by the
|
"""Return a string identifying the protocol version used by the
|
||||||
|
@ -832,10 +824,10 @@ class SSLSocket(socket):
|
||||||
if connected:
|
if connected:
|
||||||
# create the SSL object
|
# create the SSL object
|
||||||
try:
|
try:
|
||||||
sslobj = self._context._wrap_socket(self, server_side,
|
self._sslobj = self._context._wrap_socket(
|
||||||
self.server_hostname)
|
self, server_side, self.server_hostname,
|
||||||
self._sslobj = SSLObject(sslobj, owner=self,
|
owner=self, session=self._session,
|
||||||
session=self._session)
|
)
|
||||||
if do_handshake_on_connect:
|
if do_handshake_on_connect:
|
||||||
timeout = self.gettimeout()
|
timeout = self.gettimeout()
|
||||||
if timeout == 0.0:
|
if timeout == 0.0:
|
||||||
|
@ -895,10 +887,13 @@ class SSLSocket(socket):
|
||||||
Return zero-length string on EOF."""
|
Return zero-length string on EOF."""
|
||||||
|
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if not self._sslobj:
|
if self._sslobj is None:
|
||||||
raise ValueError("Read on closed or unwrapped SSL socket.")
|
raise ValueError("Read on closed or unwrapped SSL socket.")
|
||||||
try:
|
try:
|
||||||
return self._sslobj.read(len, buffer)
|
if buffer is not None:
|
||||||
|
return self._sslobj.read(len, buffer)
|
||||||
|
else:
|
||||||
|
return self._sslobj.read(len)
|
||||||
except SSLError as x:
|
except SSLError as x:
|
||||||
if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
|
if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
|
||||||
if buffer is not None:
|
if buffer is not None:
|
||||||
|
@ -913,7 +908,7 @@ class SSLSocket(socket):
|
||||||
number of bytes of DATA actually transmitted."""
|
number of bytes of DATA actually transmitted."""
|
||||||
|
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if not self._sslobj:
|
if self._sslobj is None:
|
||||||
raise ValueError("Write on closed or unwrapped SSL socket.")
|
raise ValueError("Write on closed or unwrapped SSL socket.")
|
||||||
return self._sslobj.write(data)
|
return self._sslobj.write(data)
|
||||||
|
|
||||||
|
@ -929,41 +924,42 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def selected_npn_protocol(self):
|
def selected_npn_protocol(self):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if not self._sslobj or not _ssl.HAS_NPN:
|
if self._sslobj is None or not _ssl.HAS_NPN:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self._sslobj.selected_npn_protocol()
|
return self._sslobj.selected_npn_protocol()
|
||||||
|
|
||||||
def selected_alpn_protocol(self):
|
def selected_alpn_protocol(self):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if not self._sslobj or not _ssl.HAS_ALPN:
|
if self._sslobj is None or not _ssl.HAS_ALPN:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self._sslobj.selected_alpn_protocol()
|
return self._sslobj.selected_alpn_protocol()
|
||||||
|
|
||||||
def cipher(self):
|
def cipher(self):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if not self._sslobj:
|
if self._sslobj is None:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self._sslobj.cipher()
|
return self._sslobj.cipher()
|
||||||
|
|
||||||
def shared_ciphers(self):
|
def shared_ciphers(self):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if not self._sslobj:
|
if self._sslobj is None:
|
||||||
return None
|
return None
|
||||||
return self._sslobj.shared_ciphers()
|
else:
|
||||||
|
return self._sslobj.shared_ciphers()
|
||||||
|
|
||||||
def compression(self):
|
def compression(self):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if not self._sslobj:
|
if self._sslobj is None:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self._sslobj.compression()
|
return self._sslobj.compression()
|
||||||
|
|
||||||
def send(self, data, flags=0):
|
def send(self, data, flags=0):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
if flags != 0:
|
if flags != 0:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"non-zero flags not allowed in calls to send() on %s" %
|
"non-zero flags not allowed in calls to send() on %s" %
|
||||||
|
@ -974,7 +970,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def sendto(self, data, flags_or_addr, addr=None):
|
def sendto(self, data, flags_or_addr, addr=None):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
raise ValueError("sendto not allowed on instances of %s" %
|
raise ValueError("sendto not allowed on instances of %s" %
|
||||||
self.__class__)
|
self.__class__)
|
||||||
elif addr is None:
|
elif addr is None:
|
||||||
|
@ -990,7 +986,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def sendall(self, data, flags=0):
|
def sendall(self, data, flags=0):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
if flags != 0:
|
if flags != 0:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"non-zero flags not allowed in calls to sendall() on %s" %
|
"non-zero flags not allowed in calls to sendall() on %s" %
|
||||||
|
@ -1008,15 +1004,15 @@ class SSLSocket(socket):
|
||||||
"""Send a file, possibly by using os.sendfile() if this is a
|
"""Send a file, possibly by using os.sendfile() if this is a
|
||||||
clear-text socket. Return the total number of bytes sent.
|
clear-text socket. Return the total number of bytes sent.
|
||||||
"""
|
"""
|
||||||
if self._sslobj is None:
|
if self._sslobj is not None:
|
||||||
|
return self._sendfile_use_send(file, offset, count)
|
||||||
|
else:
|
||||||
# os.sendfile() works with plain sockets only
|
# os.sendfile() works with plain sockets only
|
||||||
return super().sendfile(file, offset, count)
|
return super().sendfile(file, offset, count)
|
||||||
else:
|
|
||||||
return self._sendfile_use_send(file, offset, count)
|
|
||||||
|
|
||||||
def recv(self, buflen=1024, flags=0):
|
def recv(self, buflen=1024, flags=0):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
if flags != 0:
|
if flags != 0:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"non-zero flags not allowed in calls to recv() on %s" %
|
"non-zero flags not allowed in calls to recv() on %s" %
|
||||||
|
@ -1031,7 +1027,7 @@ class SSLSocket(socket):
|
||||||
nbytes = len(buffer)
|
nbytes = len(buffer)
|
||||||
elif nbytes is None:
|
elif nbytes is None:
|
||||||
nbytes = 1024
|
nbytes = 1024
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
if flags != 0:
|
if flags != 0:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"non-zero flags not allowed in calls to recv_into() on %s" %
|
"non-zero flags not allowed in calls to recv_into() on %s" %
|
||||||
|
@ -1042,7 +1038,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def recvfrom(self, buflen=1024, flags=0):
|
def recvfrom(self, buflen=1024, flags=0):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
raise ValueError("recvfrom not allowed on instances of %s" %
|
raise ValueError("recvfrom not allowed on instances of %s" %
|
||||||
self.__class__)
|
self.__class__)
|
||||||
else:
|
else:
|
||||||
|
@ -1050,7 +1046,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def recvfrom_into(self, buffer, nbytes=None, flags=0):
|
def recvfrom_into(self, buffer, nbytes=None, flags=0):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
raise ValueError("recvfrom_into not allowed on instances of %s" %
|
raise ValueError("recvfrom_into not allowed on instances of %s" %
|
||||||
self.__class__)
|
self.__class__)
|
||||||
else:
|
else:
|
||||||
|
@ -1066,7 +1062,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def pending(self):
|
def pending(self):
|
||||||
self._checkClosed()
|
self._checkClosed()
|
||||||
if self._sslobj:
|
if self._sslobj is not None:
|
||||||
return self._sslobj.pending()
|
return self._sslobj.pending()
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
@ -1078,7 +1074,7 @@ class SSLSocket(socket):
|
||||||
|
|
||||||
def unwrap(self):
|
def unwrap(self):
|
||||||
if self._sslobj:
|
if self._sslobj:
|
||||||
s = self._sslobj.unwrap()
|
s = self._sslobj.shutdown()
|
||||||
self._sslobj = None
|
self._sslobj = None
|
||||||
return s
|
return s
|
||||||
else:
|
else:
|
||||||
|
@ -1096,6 +1092,11 @@ class SSLSocket(socket):
|
||||||
if timeout == 0.0 and block:
|
if timeout == 0.0 and block:
|
||||||
self.settimeout(None)
|
self.settimeout(None)
|
||||||
self._sslobj.do_handshake()
|
self._sslobj.do_handshake()
|
||||||
|
if self.context.check_hostname:
|
||||||
|
if not self.server_hostname:
|
||||||
|
raise ValueError("check_hostname needs server_hostname "
|
||||||
|
"argument")
|
||||||
|
match_hostname(self.getpeercert(), self.server_hostname)
|
||||||
finally:
|
finally:
|
||||||
self.settimeout(timeout)
|
self.settimeout(timeout)
|
||||||
|
|
||||||
|
@ -1104,11 +1105,12 @@ class SSLSocket(socket):
|
||||||
raise ValueError("can't connect in server-side mode")
|
raise ValueError("can't connect in server-side mode")
|
||||||
# Here we assume that the socket is client-side, and not
|
# Here we assume that the socket is client-side, and not
|
||||||
# connected at the time of the call. We connect it, then wrap it.
|
# connected at the time of the call. We connect it, then wrap it.
|
||||||
if self._connected:
|
if self._connected or self._sslobj is not None:
|
||||||
raise ValueError("attempt to connect already-connected SSLSocket!")
|
raise ValueError("attempt to connect already-connected SSLSocket!")
|
||||||
sslobj = self.context._wrap_socket(self, False, self.server_hostname)
|
self._sslobj = self.context._wrap_socket(
|
||||||
self._sslobj = SSLObject(sslobj, owner=self,
|
self, False, self.server_hostname,
|
||||||
session=self._session)
|
owner=self, session=self._session
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
if connect_ex:
|
if connect_ex:
|
||||||
rc = super().connect_ex(addr)
|
rc = super().connect_ex(addr)
|
||||||
|
@ -1151,18 +1153,24 @@ class SSLSocket(socket):
|
||||||
if the requested `cb_type` is not supported. Return bytes of the data
|
if the requested `cb_type` is not supported. Return bytes of the data
|
||||||
or None if the data is not available (e.g. before the handshake).
|
or None if the data is not available (e.g. before the handshake).
|
||||||
"""
|
"""
|
||||||
if self._sslobj is None:
|
if self._sslobj is not None:
|
||||||
|
return self._sslobj.get_channel_binding(cb_type)
|
||||||
|
else:
|
||||||
|
if cb_type not in CHANNEL_BINDING_TYPES:
|
||||||
|
raise ValueError(
|
||||||
|
"{0} channel binding type not implemented".format(cb_type)
|
||||||
|
)
|
||||||
return None
|
return None
|
||||||
return self._sslobj.get_channel_binding(cb_type)
|
|
||||||
|
|
||||||
def version(self):
|
def version(self):
|
||||||
"""
|
"""
|
||||||
Return a string identifying the protocol version used by the
|
Return a string identifying the protocol version used by the
|
||||||
current SSL channel, or None if there is no established channel.
|
current SSL channel, or None if there is no established channel.
|
||||||
"""
|
"""
|
||||||
if self._sslobj is None:
|
if self._sslobj is not None:
|
||||||
|
return self._sslobj.version()
|
||||||
|
else:
|
||||||
return None
|
return None
|
||||||
return self._sslobj.version()
|
|
||||||
|
|
||||||
|
|
||||||
# Python does not support forward declaration of types.
|
# Python does not support forward declaration of types.
|
||||||
|
|
|
@ -455,6 +455,8 @@ class BasicSocketTests(unittest.TestCase):
|
||||||
self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
|
self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
|
||||||
self.assertRaises(OSError, ss.send, b'x')
|
self.assertRaises(OSError, ss.send, b'x')
|
||||||
self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
|
self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
|
||||||
|
self.assertRaises(NotImplementedError, ss.sendmsg,
|
||||||
|
[b'x'], (), 0, ('0.0.0.0', 0))
|
||||||
|
|
||||||
def test_timeout(self):
|
def test_timeout(self):
|
||||||
# Issue #8524: when creating an SSL socket, the timeout of the
|
# Issue #8524: when creating an SSL socket, the timeout of the
|
||||||
|
@ -3381,11 +3383,13 @@ class ThreadedTests(unittest.TestCase):
|
||||||
chatty=False) as server:
|
chatty=False) as server:
|
||||||
with context.wrap_socket(socket.socket()) as s:
|
with context.wrap_socket(socket.socket()) as s:
|
||||||
self.assertIs(s.version(), None)
|
self.assertIs(s.version(), None)
|
||||||
|
self.assertIs(s._sslobj, None)
|
||||||
s.connect((HOST, server.port))
|
s.connect((HOST, server.port))
|
||||||
if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
|
if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
|
||||||
self.assertEqual(s.version(), 'TLSv1.2')
|
self.assertEqual(s.version(), 'TLSv1.2')
|
||||||
else: # 0.9.8 to 1.0.1
|
else: # 0.9.8 to 1.0.1
|
||||||
self.assertIn(s.version(), ('TLSv1', 'TLSv1.2'))
|
self.assertIn(s.version(), ('TLSv1', 'TLSv1.2'))
|
||||||
|
self.assertIs(s._sslobj, None)
|
||||||
self.assertIs(s.version(), None)
|
self.assertIs(s.version(), None)
|
||||||
|
|
||||||
@unittest.skipUnless(ssl.HAS_TLSv1_3,
|
@unittest.skipUnless(ssl.HAS_TLSv1_3,
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Internal implementation details of ssl module were cleaned up. The SSLSocket
|
||||||
|
has one less layer of indirection. Owner and session information are now
|
||||||
|
handled by the SSLSocket and SSLObject constructor. Channel binding
|
||||||
|
implementation has been simplified.
|
|
@ -408,6 +408,8 @@ class _ssl.SSLSession "PySSLSession *" "&PySSLSession_Type"
|
||||||
|
|
||||||
static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout);
|
static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout);
|
||||||
|
|
||||||
|
static int PySSL_set_owner(PySSLSocket *, PyObject *, void *);
|
||||||
|
static int PySSL_set_session(PySSLSocket *, PyObject *, void *);
|
||||||
#define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type)
|
#define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type)
|
||||||
#define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type)
|
#define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type)
|
||||||
#define PySSLSession_Check(v) (Py_TYPE(v) == &PySSLSession_Type)
|
#define PySSLSession_Check(v) (Py_TYPE(v) == &PySSLSession_Type)
|
||||||
|
@ -799,6 +801,7 @@ static PySSLSocket *
|
||||||
newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
|
newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
|
||||||
enum py_ssl_server_or_client socket_type,
|
enum py_ssl_server_or_client socket_type,
|
||||||
char *server_hostname,
|
char *server_hostname,
|
||||||
|
PyObject *owner, PyObject *session,
|
||||||
PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio)
|
PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio)
|
||||||
{
|
{
|
||||||
PySSLSocket *self;
|
PySSLSocket *self;
|
||||||
|
@ -875,6 +878,18 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (owner && owner != Py_None) {
|
||||||
|
if (PySSL_set_owner(self, owner, NULL) == -1) {
|
||||||
|
Py_DECREF(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (session && session != Py_None) {
|
||||||
|
if (PySSL_set_session(self, session, NULL) == -1) {
|
||||||
|
Py_DECREF(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1677,7 +1692,7 @@ _ssl__test_decode_cert_impl(PyObject *module, PyObject *path)
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_ssl._SSLSocket.peer_certificate
|
_ssl._SSLSocket.getpeercert
|
||||||
der as binary_mode: bool = False
|
der as binary_mode: bool = False
|
||||||
/
|
/
|
||||||
|
|
||||||
|
@ -1693,8 +1708,8 @@ return the certificate even if it wasn't validated.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLSocket_peer_certificate_impl(PySSLSocket *self, int binary_mode)
|
_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode)
|
||||||
/*[clinic end generated code: output=f0dc3e4d1d818a1d input=8281bd1d193db843]*/
|
/*[clinic end generated code: output=1f0ab66dfb693c88 input=c0fbe802e57629b7]*/
|
||||||
{
|
{
|
||||||
int verification;
|
int verification;
|
||||||
X509 *peer_cert;
|
X509 *peer_cert;
|
||||||
|
@ -2395,13 +2410,11 @@ error:
|
||||||
_ssl._SSLSocket.shutdown
|
_ssl._SSLSocket.shutdown
|
||||||
|
|
||||||
Does the SSL shutdown handshake with the remote end.
|
Does the SSL shutdown handshake with the remote end.
|
||||||
|
|
||||||
Returns the underlying socket object.
|
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
|
_ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
|
||||||
/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=ede2cc1a2ddf0ee4]*/
|
/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=11d39e69b0a2bf4a]*/
|
||||||
{
|
{
|
||||||
int err, sockstate, nonblocking;
|
int err, sockstate, nonblocking;
|
||||||
int zeros = 0;
|
int zeros = 0;
|
||||||
|
@ -2506,37 +2519,48 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_ssl._SSLSocket.tls_unique_cb
|
_ssl._SSLSocket.get_channel_binding
|
||||||
|
cb_type: str = "tls-unique"
|
||||||
|
|
||||||
Returns the 'tls-unique' channel binding data, as defined by RFC 5929.
|
Get channel binding data for current connection.
|
||||||
|
|
||||||
If the TLS handshake is not yet complete, None is returned.
|
Raise ValueError if the requested `cb_type` is not supported. Return bytes
|
||||||
|
of the data or None if the data is not available (e.g. before the handshake).
|
||||||
|
Only 'tls-unique' channel binding data from RFC 5929 is supported.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLSocket_tls_unique_cb_impl(PySSLSocket *self)
|
_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self,
|
||||||
/*[clinic end generated code: output=f3a832d603f586af input=439525c7b3d8d34d]*/
|
const char *cb_type)
|
||||||
|
/*[clinic end generated code: output=34bac9acb6a61d31 input=08b7e43b99c17d41]*/
|
||||||
{
|
{
|
||||||
PyObject *retval = NULL;
|
|
||||||
char buf[PySSL_CB_MAXLEN];
|
char buf[PySSL_CB_MAXLEN];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
if (SSL_session_reused(self->ssl) ^ !self->socket_type) {
|
if (strcmp(cb_type, "tls-unique") == 0) {
|
||||||
/* if session is resumed XOR we are the client */
|
if (SSL_session_reused(self->ssl) ^ !self->socket_type) {
|
||||||
len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN);
|
/* if session is resumed XOR we are the client */
|
||||||
|
len = SSL_get_finished(self->ssl, buf, PySSL_CB_MAXLEN);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* if a new session XOR we are the server */
|
||||||
|
len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* if a new session XOR we are the server */
|
PyErr_Format(
|
||||||
len = SSL_get_peer_finished(self->ssl, buf, PySSL_CB_MAXLEN);
|
PyExc_ValueError,
|
||||||
|
"'%s' channel binding type not implemented",
|
||||||
|
cb_type
|
||||||
|
);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It cannot be negative in current OpenSSL version as of July 2011 */
|
/* It cannot be negative in current OpenSSL version as of July 2011 */
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
||||||
retval = PyBytes_FromStringAndSize(buf, len);
|
return PyBytes_FromStringAndSize(buf, len);
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSSL_VERSION_1_1
|
#ifdef OPENSSL_VERSION_1_1
|
||||||
|
@ -2706,7 +2730,8 @@ static PyMethodDef PySSLMethods[] = {
|
||||||
_SSL__SSLSOCKET_WRITE_METHODDEF
|
_SSL__SSLSOCKET_WRITE_METHODDEF
|
||||||
_SSL__SSLSOCKET_READ_METHODDEF
|
_SSL__SSLSOCKET_READ_METHODDEF
|
||||||
_SSL__SSLSOCKET_PENDING_METHODDEF
|
_SSL__SSLSOCKET_PENDING_METHODDEF
|
||||||
_SSL__SSLSOCKET_PEER_CERTIFICATE_METHODDEF
|
_SSL__SSLSOCKET_GETPEERCERT_METHODDEF
|
||||||
|
_SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF
|
||||||
_SSL__SSLSOCKET_CIPHER_METHODDEF
|
_SSL__SSLSOCKET_CIPHER_METHODDEF
|
||||||
_SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF
|
_SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF
|
||||||
_SSL__SSLSOCKET_VERSION_METHODDEF
|
_SSL__SSLSOCKET_VERSION_METHODDEF
|
||||||
|
@ -2714,7 +2739,6 @@ static PyMethodDef PySSLMethods[] = {
|
||||||
_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF
|
_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF
|
||||||
_SSL__SSLSOCKET_COMPRESSION_METHODDEF
|
_SSL__SSLSOCKET_COMPRESSION_METHODDEF
|
||||||
_SSL__SSLSOCKET_SHUTDOWN_METHODDEF
|
_SSL__SSLSOCKET_SHUTDOWN_METHODDEF
|
||||||
_SSL__SSLSOCKET_TLS_UNIQUE_CB_METHODDEF
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3810,13 +3834,17 @@ _ssl._SSLContext._wrap_socket
|
||||||
sock: object(subclass_of="PySocketModule.Sock_Type")
|
sock: object(subclass_of="PySocketModule.Sock_Type")
|
||||||
server_side: int
|
server_side: int
|
||||||
server_hostname as hostname_obj: object = None
|
server_hostname as hostname_obj: object = None
|
||||||
|
*
|
||||||
|
owner: object = None
|
||||||
|
session: object = None
|
||||||
|
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
|
_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
|
||||||
int server_side, PyObject *hostname_obj)
|
int server_side, PyObject *hostname_obj,
|
||||||
/*[clinic end generated code: output=6973e4b60995e933 input=83859b9156ddfc63]*/
|
PyObject *owner, PyObject *session)
|
||||||
|
/*[clinic end generated code: output=f103f238633940b4 input=957d5006183d1894]*/
|
||||||
{
|
{
|
||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
|
@ -3830,6 +3858,7 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
|
||||||
|
|
||||||
res = (PyObject *) newPySSLSocket(self, (PySocketSockObject *)sock,
|
res = (PyObject *) newPySSLSocket(self, (PySocketSockObject *)sock,
|
||||||
server_side, hostname,
|
server_side, hostname,
|
||||||
|
owner, session,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (hostname != NULL)
|
if (hostname != NULL)
|
||||||
PyMem_Free(hostname);
|
PyMem_Free(hostname);
|
||||||
|
@ -3842,14 +3871,18 @@ _ssl._SSLContext._wrap_bio
|
||||||
outgoing: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *")
|
outgoing: object(subclass_of="&PySSLMemoryBIO_Type", type="PySSLMemoryBIO *")
|
||||||
server_side: int
|
server_side: int
|
||||||
server_hostname as hostname_obj: object = None
|
server_hostname as hostname_obj: object = None
|
||||||
|
*
|
||||||
|
owner: object = None
|
||||||
|
session: object = None
|
||||||
|
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
|
_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
|
||||||
PySSLMemoryBIO *outgoing, int server_side,
|
PySSLMemoryBIO *outgoing, int server_side,
|
||||||
PyObject *hostname_obj)
|
PyObject *hostname_obj, PyObject *owner,
|
||||||
/*[clinic end generated code: output=4fe4ba75ad95940d input=17725ecdac0bf220]*/
|
PyObject *session)
|
||||||
|
/*[clinic end generated code: output=5c5d6d9b41f99332 input=8cf22f4d586ac56a]*/
|
||||||
{
|
{
|
||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
|
@ -3862,6 +3895,7 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
|
||||||
}
|
}
|
||||||
|
|
||||||
res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname,
|
res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname,
|
||||||
|
owner, session,
|
||||||
incoming, outgoing);
|
incoming, outgoing);
|
||||||
|
|
||||||
PyMem_Free(hostname);
|
PyMem_Free(hostname);
|
||||||
|
@ -5663,10 +5697,6 @@ PyInit__ssl(void)
|
||||||
Py_INCREF(r);
|
Py_INCREF(r);
|
||||||
PyModule_AddObject(m, "HAS_SNI", r);
|
PyModule_AddObject(m, "HAS_SNI", r);
|
||||||
|
|
||||||
r = Py_True;
|
|
||||||
Py_INCREF(r);
|
|
||||||
PyModule_AddObject(m, "HAS_TLS_UNIQUE", r);
|
|
||||||
|
|
||||||
#ifdef OPENSSL_NO_ECDH
|
#ifdef OPENSSL_NO_ECDH
|
||||||
r = Py_False;
|
r = Py_False;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -45,8 +45,8 @@ exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_ssl__SSLSocket_peer_certificate__doc__,
|
PyDoc_STRVAR(_ssl__SSLSocket_getpeercert__doc__,
|
||||||
"peer_certificate($self, der=False, /)\n"
|
"getpeercert($self, der=False, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Returns the certificate for the peer.\n"
|
"Returns the certificate for the peer.\n"
|
||||||
|
@ -59,23 +59,23 @@ PyDoc_STRVAR(_ssl__SSLSocket_peer_certificate__doc__,
|
||||||
"peer certificate, or None if no certificate was provided. This will\n"
|
"peer certificate, or None if no certificate was provided. This will\n"
|
||||||
"return the certificate even if it wasn\'t validated.");
|
"return the certificate even if it wasn\'t validated.");
|
||||||
|
|
||||||
#define _SSL__SSLSOCKET_PEER_CERTIFICATE_METHODDEF \
|
#define _SSL__SSLSOCKET_GETPEERCERT_METHODDEF \
|
||||||
{"peer_certificate", (PyCFunction)_ssl__SSLSocket_peer_certificate, METH_FASTCALL, _ssl__SSLSocket_peer_certificate__doc__},
|
{"getpeercert", (PyCFunction)_ssl__SSLSocket_getpeercert, METH_FASTCALL, _ssl__SSLSocket_getpeercert__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLSocket_peer_certificate_impl(PySSLSocket *self, int binary_mode);
|
_ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLSocket_peer_certificate(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs)
|
_ssl__SSLSocket_getpeercert(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
int binary_mode = 0;
|
int binary_mode = 0;
|
||||||
|
|
||||||
if (!_PyArg_ParseStack(args, nargs, "|p:peer_certificate",
|
if (!_PyArg_ParseStack(args, nargs, "|p:getpeercert",
|
||||||
&binary_mode)) {
|
&binary_mode)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
return_value = _ssl__SSLSocket_peer_certificate_impl(self, binary_mode);
|
return_value = _ssl__SSLSocket_getpeercert_impl(self, binary_mode);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
|
@ -293,9 +293,7 @@ PyDoc_STRVAR(_ssl__SSLSocket_shutdown__doc__,
|
||||||
"shutdown($self, /)\n"
|
"shutdown($self, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Does the SSL shutdown handshake with the remote end.\n"
|
"Does the SSL shutdown handshake with the remote end.");
|
||||||
"\n"
|
|
||||||
"Returns the underlying socket object.");
|
|
||||||
|
|
||||||
#define _SSL__SSLSOCKET_SHUTDOWN_METHODDEF \
|
#define _SSL__SSLSOCKET_SHUTDOWN_METHODDEF \
|
||||||
{"shutdown", (PyCFunction)_ssl__SSLSocket_shutdown, METH_NOARGS, _ssl__SSLSocket_shutdown__doc__},
|
{"shutdown", (PyCFunction)_ssl__SSLSocket_shutdown, METH_NOARGS, _ssl__SSLSocket_shutdown__doc__},
|
||||||
|
@ -309,24 +307,39 @@ _ssl__SSLSocket_shutdown(PySSLSocket *self, PyObject *Py_UNUSED(ignored))
|
||||||
return _ssl__SSLSocket_shutdown_impl(self);
|
return _ssl__SSLSocket_shutdown_impl(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_ssl__SSLSocket_tls_unique_cb__doc__,
|
PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__,
|
||||||
"tls_unique_cb($self, /)\n"
|
"get_channel_binding($self, /, cb_type=\'tls-unique\')\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Returns the \'tls-unique\' channel binding data, as defined by RFC 5929.\n"
|
"Get channel binding data for current connection.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If the TLS handshake is not yet complete, None is returned.");
|
"Raise ValueError if the requested `cb_type` is not supported. Return bytes\n"
|
||||||
|
"of the data or None if the data is not available (e.g. before the handshake).\n"
|
||||||
|
"Only \'tls-unique\' channel binding data from RFC 5929 is supported.");
|
||||||
|
|
||||||
#define _SSL__SSLSOCKET_TLS_UNIQUE_CB_METHODDEF \
|
#define _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF \
|
||||||
{"tls_unique_cb", (PyCFunction)_ssl__SSLSocket_tls_unique_cb, METH_NOARGS, _ssl__SSLSocket_tls_unique_cb__doc__},
|
{"get_channel_binding", (PyCFunction)_ssl__SSLSocket_get_channel_binding, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLSocket_get_channel_binding__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLSocket_tls_unique_cb_impl(PySSLSocket *self);
|
_ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self,
|
||||||
|
const char *cb_type);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLSocket_tls_unique_cb(PySSLSocket *self, PyObject *Py_UNUSED(ignored))
|
_ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
return _ssl__SSLSocket_tls_unique_cb_impl(self);
|
PyObject *return_value = NULL;
|
||||||
|
static const char * const _keywords[] = {"cb_type", NULL};
|
||||||
|
static _PyArg_Parser _parser = {"|s:get_channel_binding", _keywords, 0};
|
||||||
|
const char *cb_type = "tls-unique";
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
|
||||||
|
&cb_type)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = _ssl__SSLSocket_get_channel_binding_impl(self, cb_type);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -538,7 +551,8 @@ PyDoc_STRVAR(_ssl__SSLContext_load_dh_params__doc__,
|
||||||
{"load_dh_params", (PyCFunction)_ssl__SSLContext_load_dh_params, METH_O, _ssl__SSLContext_load_dh_params__doc__},
|
{"load_dh_params", (PyCFunction)_ssl__SSLContext_load_dh_params, METH_O, _ssl__SSLContext_load_dh_params__doc__},
|
||||||
|
|
||||||
PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__,
|
PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__,
|
||||||
"_wrap_socket($self, /, sock, server_side, server_hostname=None)\n"
|
"_wrap_socket($self, /, sock, server_side, server_hostname=None, *,\n"
|
||||||
|
" owner=None, session=None)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
|
@ -547,23 +561,26 @@ PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__,
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
|
_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock,
|
||||||
int server_side, PyObject *hostname_obj);
|
int server_side, PyObject *hostname_obj,
|
||||||
|
PyObject *owner, PyObject *session);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
_ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
static const char * const _keywords[] = {"sock", "server_side", "server_hostname", NULL};
|
static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL};
|
||||||
static _PyArg_Parser _parser = {"O!i|O:_wrap_socket", _keywords, 0};
|
static _PyArg_Parser _parser = {"O!i|O$OO:_wrap_socket", _keywords, 0};
|
||||||
PyObject *sock;
|
PyObject *sock;
|
||||||
int server_side;
|
int server_side;
|
||||||
PyObject *hostname_obj = Py_None;
|
PyObject *hostname_obj = Py_None;
|
||||||
|
PyObject *owner = Py_None;
|
||||||
|
PyObject *session = Py_None;
|
||||||
|
|
||||||
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
|
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
|
||||||
PySocketModule.Sock_Type, &sock, &server_side, &hostname_obj)) {
|
PySocketModule.Sock_Type, &sock, &server_side, &hostname_obj, &owner, &session)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj);
|
return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj, owner, session);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
|
@ -571,7 +588,7 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__,
|
PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__,
|
||||||
"_wrap_bio($self, /, incoming, outgoing, server_side,\n"
|
"_wrap_bio($self, /, incoming, outgoing, server_side,\n"
|
||||||
" server_hostname=None)\n"
|
" server_hostname=None, *, owner=None, session=None)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
|
@ -581,24 +598,27 @@ PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
|
_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming,
|
||||||
PySSLMemoryBIO *outgoing, int server_side,
|
PySSLMemoryBIO *outgoing, int server_side,
|
||||||
PyObject *hostname_obj);
|
PyObject *hostname_obj, PyObject *owner,
|
||||||
|
PyObject *session);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
_ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", NULL};
|
static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL};
|
||||||
static _PyArg_Parser _parser = {"O!O!i|O:_wrap_bio", _keywords, 0};
|
static _PyArg_Parser _parser = {"O!O!i|O$OO:_wrap_bio", _keywords, 0};
|
||||||
PySSLMemoryBIO *incoming;
|
PySSLMemoryBIO *incoming;
|
||||||
PySSLMemoryBIO *outgoing;
|
PySSLMemoryBIO *outgoing;
|
||||||
int server_side;
|
int server_side;
|
||||||
PyObject *hostname_obj = Py_None;
|
PyObject *hostname_obj = Py_None;
|
||||||
|
PyObject *owner = Py_None;
|
||||||
|
PyObject *session = Py_None;
|
||||||
|
|
||||||
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
|
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
|
||||||
&PySSLMemoryBIO_Type, &incoming, &PySSLMemoryBIO_Type, &outgoing, &server_side, &hostname_obj)) {
|
&PySSLMemoryBIO_Type, &incoming, &PySSLMemoryBIO_Type, &outgoing, &server_side, &hostname_obj, &owner, &session)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj);
|
return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj, owner, session);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
|
@ -1155,4 +1175,4 @@ exit:
|
||||||
#ifndef _SSL_ENUM_CRLS_METHODDEF
|
#ifndef _SSL_ENUM_CRLS_METHODDEF
|
||||||
#define _SSL_ENUM_CRLS_METHODDEF
|
#define _SSL_ENUM_CRLS_METHODDEF
|
||||||
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
|
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
|
||||||
/*[clinic end generated code: output=84e1fd89aff9b0f7 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=d987411caeb106e7 input=a9049054013a1b77]*/
|
||||||
|
|
Loading…
Reference in New Issue