Compatibility Updates for Python 2.7.12

* dtls/openssl.py: support reading directly into given buffer instead
                     of forcing buffer copy (for ssl module compatibility)
	* dtls/sslconnection.py: in-situ receive support, as above
	* dtls/patch.py: various changes for compatibility with the ssl module
                   of Python 2.7.12; note that the ssl module's new
                   SSLContext is not supported
	* dtls/test/unit.py: changes to support the updated ssl module,
                       including fix of deprecation warnings
	* setup.py: increase version to 1.0.2
incoming
Ray 2017-02-27 22:37:50 -08:00
parent 34dc9ca9cd
commit 622f58358e
7 changed files with 49 additions and 18 deletions

View File

@ -1,3 +1,11 @@
2017-02-27 Ray Brown <code@liquibits.com>
* dtls/openssl.py: support reading directly into given buffer instead of forcing buffer copy (for ssl module compatibility)
* dtls/sslconnection.py: in-situ receive support, as above
* dtls/patch.py: various changes for compatibility with the ssl module of Python 2.7.12; note that the ssl module's new SSLContext is not supported
* dtls/test/unit.py: changes to support the updated ssl module, including fix of deprecation warnings
* setup.py: increase version to 1.0.2
2014-01-18 Ray Brown <code@liquibits.com>
* setup.py: Increase version to 1.0.1 for release to PyPI

View File

@ -96,8 +96,8 @@ def raise_ssl_error(code, nested=None):
"""Raise an SSL error with the given error code"""
err_string = str(code) + ": " + _ssl_errors[code]
if nested:
raise SSLError(err_string, nested)
raise SSLError(err_string)
raise SSLError(code, err_string + str(nested))
raise SSLError(code, err_string)
_ssl_errors = {
ERR_NO_CERTS: "No root certificates specified for verification " + \

View File

@ -735,9 +735,15 @@ def DTLSv1_listen(ssl):
errcheck_ord(ret, _SSL_ctrl, (ssl, DTLS_CTRL_LISTEN, 0, byref(su)))
return addr_tuple_from_sockaddr_u(su)
def SSL_read(ssl, length):
buf = create_string_buffer(length)
res_len = _SSL_read(ssl, buf, sizeof(buf))
def SSL_read(ssl, length, buffer):
if buffer:
length = min(length, len(buffer))
buf = (c_char * length).from_buffer(buffer)
else:
buf = create_string_buffer(length)
res_len = _SSL_read(ssl, buf, length)
if buffer:
return res_len
return buf.raw[:res_len]
def SSL_write(ssl, data):

View File

@ -35,7 +35,7 @@ has the following effects:
"""
from socket import SOCK_DGRAM, socket, _delegate_methods, error as socket_error
from socket import AF_INET, SOCK_DGRAM, getaddrinfo
from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM, getaddrinfo
from sslconnection import SSLConnection, PROTOCOL_DTLSv1, CERT_NONE
from sslconnection import DTLS_OPENSSL_VERSION_NUMBER, DTLS_OPENSSL_VERSION
from sslconnection import DTLS_OPENSSL_VERSION_INFO
@ -62,10 +62,9 @@ def do_patch():
ssl.get_server_certificate = _get_server_certificate
raise_as_ssl_module_error()
PROTOCOL_SSLv3 = 1
PROTOCOL_SSLv23 = 2
def _get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None):
def _get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
"""Retrieve a server certificate
Retrieve the certificate from the server at the specified address,
@ -90,11 +89,14 @@ def _get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None):
s.close()
return ssl.DER_cert_to_PEM_cert(dercert)
def _SSLSocket_init(self, sock, keyfile=None, certfile=None,
def _SSLSocket_init(self, sock=None, keyfile=None, certfile=None,
server_side=False, cert_reqs=CERT_NONE,
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
do_handshake_on_connect=True,
suppress_ragged_eofs=True, ciphers=None):
family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
server_hostname=None,
_context=None):
is_connection = is_datagram = False
if isinstance(sock, SSLConnection):
is_connection = True
@ -102,11 +104,19 @@ def _SSLSocket_init(self, sock, keyfile=None, certfile=None,
is_datagram = True
if not is_connection and not is_datagram:
# Non-DTLS code path
return _orig_SSLSocket_init(self, sock, keyfile, certfile,
server_side, cert_reqs,
ssl_version, ca_certs,
return _orig_SSLSocket_init(self, sock=sock, keyfile=keyfile,
certfile=certfile, server_side=server_side,
cert_reqs=cert_reqs,
ssl_version=ssl_version, ca_certs=ca_certs,
do_handshake_on_connect=
do_handshake_on_connect,
suppress_ragged_eofs, ciphers)
family=family, type=type, proto=proto,
fileno=fileno,
suppress_ragged_eofs=suppress_ragged_eofs,
npn_protocols=npn_protocols,
ciphers=ciphers,
server_hostname=server_hostname,
_context=_context)
# DTLS code paths: datagram socket and newly accepted DTLS connection
if is_datagram:
socket.__init__(self, _sock=sock._sock)
@ -140,8 +150,13 @@ def _SSLSocket_init(self, sock, keyfile=None, certfile=None,
do_handshake_on_connect,
suppress_ragged_eofs, ciphers)
else:
self._connected = True
self._sslobj = sock
class FakeContext(object):
check_hostname = False
self._context = FakeContext()
self.keyfile = keyfile
self.certfile = certfile
self.cert_reqs = cert_reqs

View File

@ -514,7 +514,7 @@ class SSLConnection(object):
self._handshake_done = True
_logger.debug("...completed handshake")
def read(self, len=1024):
def read(self, len=1024, buffer=None):
"""Read data from connection
Read up to len bytes and return them.
@ -526,7 +526,7 @@ class SSLConnection(object):
"""
return self._wrap_socket_library_call(
lambda: SSL_read(self._ssl.value, len), ERR_READ_TIMEOUT)
lambda: SSL_read(self._ssl.value, len, buffer), ERR_READ_TIMEOUT)
def write(self, data):
"""Write data to connection

View File

@ -78,7 +78,6 @@ class BasicSocketTests(unittest.TestCase):
def test_constants(self):
ssl.PROTOCOL_SSLv23
ssl.PROTOCOL_SSLv3
ssl.PROTOCOL_TLSv1
ssl.PROTOCOL_DTLSv1 # added
ssl.CERT_NONE
@ -574,6 +573,9 @@ class AsyncoreEchoServer(threading.Thread):
# Complete the handshake
self.handle_read_event()
def __hash__(self):
return hash(self.socket)
def readable(self):
while self.socket.pending() > 0:
self.handle_read_event()

View File

@ -33,7 +33,7 @@ for scheme in INSTALL_SCHEMES.values():
scheme['data'] = scheme['purelib']
NAME = "Dtls"
VERSION = "1.0.1"
VERSION = "1.0.2"
DIST_DIR = "dist"
FORMAT_TO_SUFFIX = { "zip": ".zip",