Added SSL wrapper support

This commit is contained in:
Jiri Lunacek 2016-06-29 14:39:15 +02:00
parent 9d7d97aaba
commit 921d4cb64b
3 changed files with 62 additions and 4 deletions

6
README
View File

@ -12,6 +12,12 @@ called rfoo.marsh which extends the Python built in marshal module by
eliminating serialization of code objects and protecting against bad input.
The result is a safe to use ultra fast serializer.
SSL wrapper support added by
Jiri Lunacek of Hosting90 Systems s.r.o.
Email: jiri.lunacek@hosting90.cz
Website: http://www.hosting90.cz
SSL patch version: 0
Example server code:
> class MyHandler(rfoo.BaseHandler):
> def echo(self, str):

View File

@ -176,6 +176,14 @@ class BaseHandler(object):
members = inspect.getmembers(self, inspect.ismethod)
return [m[0] for m in members if not m[0].startswith('_')]
class SSLHandler(BaseHandler):
"""
Handler for SSL server. This handler has access to SSL Socket object of the connection
"""
def __init__(self,conn,addr,context=None):
"""docstring for __init__"""
super(SSLHandler,self).__init__(addr,context)
self._conn = conn
def restrict_local(foo):
"""Decorator to restrict handler method to local proxies only."""
@ -264,7 +272,21 @@ class InetConnection(Connection):
self._conn.connect((host, port))
return self
class SSLConnection(Connection):
"""Connection type for SSL wrapped INET sockets."""
def __init__(self,ssl_context=None):
import ssl
if ssl_context == None:
ssl_context = ssl.create_default_context()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_conn = ssl_context.wrap_socket(s)
#s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
Connection.__init__(self, ssl_conn)
def connect(self, host=LOOPBACK, port=DEFAULT_PORT):
self._conn.connect((host, port))
return self
class UnixConnection(Connection):
"""Connection type for Unix sockets."""
@ -417,10 +439,11 @@ def run_in_thread(foo):
class Server(object):
"""Serve calls over connection."""
def __init__(self, handler_type, handler_context=None, conn=None):
def __init__(self, handler_type, handler_context=None, conn=None, ssl_context=None):
self._handler_context = handler_context
self._handler_type = handler_type
self._conn = conn
self._ssl_context = ssl_context
def close(self):
if self._conn is not None:
@ -443,6 +466,13 @@ class Server(object):
while True:
conn, addr = self._conn.accept()
conn.settimeout(None)
if self._ssl_context != None:
try:
conn = self._ssl_context.wrap_socket(conn, server_side=True)
except Exception as e:
logging.warning(str(e))
conn.close()
continue
self._on_accept(conn, addr)
finally:
@ -463,7 +493,12 @@ class Server(object):
# Instantiate handler for the lifetime of the connection,
# making it possible to manage a state between calls.
#
handler = self._handler_type(addr, self._handler_context)
if SSLHandler in self._handler_type.__bases__:
# if SSL connection is used, pass both SSL socket and addr to handler
# this is needed so that the handler can use SSL extension functions
handler = self._handler_type(conn,addr, self._handler_context)
else:
handler = self._handler_type(addr, self._handler_context)
try:
while True:
@ -520,7 +555,24 @@ class InetServer(Server):
_on_accept = run_in_thread(Server._on_accept)
class SSLServer(Server):
"""Serve calls over SSL wrapped INET sockets."""
def __init__(self, handler_type, handler_context=None, ssl_context=None,certfile=None,keyfile=None):
import ssl
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.settimeout(None)
if ssl_context == None and certfile != None and keyfile != None:
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=certfile, keyfile=keyfile)
Server.__init__(self, handler_type, handler_context, s, ssl_context)
def start(self, host=LOOPBACK, port=DEFAULT_PORT):
self._conn.bind((host, port))
Server.start(self)
_on_accept = run_in_thread(Server._on_accept)
class UnixServer(Server):
"""Serve calls over Unix sockets."""

View File

@ -74,7 +74,7 @@ ext_modules = [Extension("rfoo.marsh", ["rfoo/marsh.pyx"])]
setup(
name = 'rfoo',
version = '1.3.0',
version = '1.3.0-ssl-0',
description = 'Fast RPC client/server module.',
author = 'Nir Aides',
author_email = 'nir@winpdb.org',