mirror of
https://gitee.com/fantix/kloop.git
synced 2025-02-17 12:25:22 +00:00
Initially added TLSTransport
Refs #I5ANZH
This commit is contained in:
parent
47636fbf04
commit
665647013b
4 changed files with 71 additions and 41 deletions
|
@ -516,9 +516,20 @@ cdef class KLoopImpl:
|
||||||
cdef:
|
cdef:
|
||||||
int fd
|
int fd
|
||||||
|
|
||||||
|
if ssl is False:
|
||||||
|
ssl = None
|
||||||
|
elif ssl is not None:
|
||||||
|
from . import tls
|
||||||
|
if ssl is True:
|
||||||
|
import ssl as ssl_mod
|
||||||
|
ssl = ssl_mod.create_default_context()
|
||||||
fd = await tcp_connect(self, host, port)
|
fd = await tcp_connect(self, host, port)
|
||||||
protocol = protocol_factory()
|
protocol = protocol_factory()
|
||||||
return TCPTransport.new(fd, protocol, self), protocol
|
if ssl is not None:
|
||||||
|
transport = tls.TLSTransport.new(fd, protocol, self, ssl)
|
||||||
|
else:
|
||||||
|
transport = TCPTransport.new(fd, protocol, self)
|
||||||
|
return transport, protocol
|
||||||
|
|
||||||
|
|
||||||
class KLoop(KLoopImpl, asyncio.AbstractEventLoop):
|
class KLoop(KLoopImpl, asyncio.AbstractEventLoop):
|
||||||
|
|
|
@ -9,5 +9,15 @@
|
||||||
# See the Mulan PSL v2 for more details.
|
# See the Mulan PSL v2 for more details.
|
||||||
|
|
||||||
|
|
||||||
cdef struct BIO:
|
from .includes.openssl cimport bio
|
||||||
int data
|
from .loop cimport KLoopImpl
|
||||||
|
|
||||||
|
|
||||||
|
cdef class TLSTransport:
|
||||||
|
cdef:
|
||||||
|
KLoopImpl loop
|
||||||
|
int fd
|
||||||
|
bio.BIO* bio
|
||||||
|
object protocol
|
||||||
|
object sslctx
|
||||||
|
object sslobj
|
||||||
|
|
|
@ -63,52 +63,61 @@ cdef long bio_ctrl(bio.BIO* b, int cmd, long num, void* ptr) nogil:
|
||||||
|
|
||||||
|
|
||||||
cdef int bio_create(bio.BIO* b) nogil:
|
cdef int bio_create(bio.BIO* b) nogil:
|
||||||
cdef BIO* obj = <BIO*>PyMem_RawMalloc(sizeof(BIO))
|
|
||||||
if obj == NULL:
|
|
||||||
return 0
|
|
||||||
string.memset(obj, 0, sizeof(BIO))
|
|
||||||
bio.set_data(b, <void*>obj)
|
|
||||||
bio.set_init(b, 1)
|
bio.set_init(b, 1)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
cdef int bio_destroy(bio.BIO* b) nogil:
|
cdef int bio_destroy(bio.BIO* b) nogil:
|
||||||
cdef void* obj = bio.get_data(b)
|
|
||||||
if obj != NULL:
|
|
||||||
PyMem_RawFree(obj)
|
|
||||||
bio.set_shutdown(b, 1)
|
bio.set_shutdown(b, 1)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
cdef object wrap_bio(
|
cdef class TLSTransport:
|
||||||
bio.BIO* b,
|
@staticmethod
|
||||||
object ssl_context,
|
def new(
|
||||||
bint server_side=False,
|
int fd,
|
||||||
object server_hostname=None,
|
protocol,
|
||||||
object session=None,
|
KLoopImpl loop,
|
||||||
):
|
sslctx,
|
||||||
cdef pyssl.PySSLMemoryBIO* c_bio
|
server_side=False,
|
||||||
py_bio = ssl.MemoryBIO()
|
server_hostname=None,
|
||||||
c_bio = <pyssl.PySSLMemoryBIO*>py_bio
|
session=None,
|
||||||
c_bio.bio, b = b, c_bio.bio
|
):
|
||||||
rv = ssl_context.wrap_bio(
|
cdef:
|
||||||
py_bio, py_bio, server_side, server_hostname, session
|
TLSTransport rv = TLSTransport.__new__(TLSTransport)
|
||||||
)
|
pyssl.PySSLMemoryBIO* c_bio
|
||||||
c_bio.bio, b = b, c_bio.bio
|
|
||||||
ssl_h.set_options(
|
|
||||||
(<pyssl.PySSLSocket*>rv._sslobj).ssl, ssl_h.OP_ENABLE_KTLS
|
|
||||||
)
|
|
||||||
return rv
|
|
||||||
|
|
||||||
|
py_bio = ssl.MemoryBIO()
|
||||||
|
c_bio = <pyssl.PySSLMemoryBIO*>py_bio
|
||||||
|
c_bio.bio, rv.bio = rv.bio, c_bio.bio
|
||||||
|
try:
|
||||||
|
rv.sslobj = sslctx.wrap_bio(
|
||||||
|
py_bio, py_bio, server_side, server_hostname, session
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
c_bio.bio, rv.bio = rv.bio, c_bio.bio
|
||||||
|
del py_bio
|
||||||
|
|
||||||
def test():
|
ssl_h.set_options(
|
||||||
cdef BIO* b
|
(<pyssl.PySSLSocket*>rv.sslobj).ssl, ssl_h.OP_ENABLE_KTLS
|
||||||
with nogil:
|
)
|
||||||
b = bio.new(KTLS_BIO_METHOD)
|
rv.fd = fd
|
||||||
if b == NULL:
|
rv.protocol = protocol
|
||||||
raise fromOpenSSLError(RuntimeError)
|
rv.loop = loop
|
||||||
ctx = ssl.create_default_context()
|
rv.sslctx = sslctx
|
||||||
return wrap_bio(b, ctx)
|
|
||||||
|
try:
|
||||||
|
rv.sslobj.do_handshake()
|
||||||
|
except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
|
||||||
|
pass
|
||||||
|
return rv
|
||||||
|
|
||||||
|
def __cinit__(self):
|
||||||
|
self.bio = bio.new(KTLS_BIO_METHOD)
|
||||||
|
bio.set_data(self.bio, <void*>self)
|
||||||
|
|
||||||
|
def __dealloc__(self):
|
||||||
|
bio.free(self.bio)
|
||||||
|
|
||||||
|
|
||||||
cdef bio.Method* KTLS_BIO_METHOD = bio.meth_new(
|
cdef bio.Method* KTLS_BIO_METHOD = bio.meth_new(
|
||||||
|
|
|
@ -38,9 +38,9 @@ class TestLoop(unittest.TestCase):
|
||||||
|
|
||||||
def test_connect(self):
|
def test_connect(self):
|
||||||
ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
|
ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
|
||||||
ctx.check_hostname = False
|
# ctx.check_hostname = False
|
||||||
ctx.verify_mode = ssl.CERT_NONE
|
# ctx.verify_mode = ssl.CERT_NONE
|
||||||
ctx.minimum_version = ssl.TLSVersion.TLSv1_3
|
# ctx.minimum_version = ssl.TLSVersion.TLSv1_3
|
||||||
host = "www.google.com"
|
host = "www.google.com"
|
||||||
r, w = self.loop.run_until_complete(
|
r, w = self.loop.run_until_complete(
|
||||||
# asyncio.open_connection("127.0.0.1", 8080, ssl=ctx)
|
# asyncio.open_connection("127.0.0.1", 8080, ssl=ctx)
|
||||||
|
|
Loading…
Reference in a new issue