Skip to content

Commit

Permalink
changed the "connection" argument for "security", release 0.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
yannbouteiller committed Nov 14, 2022
1 parent 2bea328 commit a28ed84
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 36 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ re = Relay(
port=3000, # this must be the same on your Relay and Endpoints
password="VerySecurePassword", # this must be the same on Relay and Endpoints, AND be strong
local_com_port=3001, # this needs to be non-overlapping if Relays/Endpoints live on the same machine
connection="TLS" # this is the default; replace by "TCP" if you do not want to use TLS
security="TLS" # this is the default; replace by "TCP" if you do not want to use TLS
)
```
As soon as your `Relay` is created, it is up and running.
Expand All @@ -230,7 +230,7 @@ prod = Endpoint(
password="VerySecurePassword", # must be same (strong) password as the Relay
groups="producers", # this endpoint is part of the group "producers"
local_com_port=3002, # must be unique
connection="TLS" # this is the default; replace by "TCP" if you do not want to use TLS
security="TLS" # this is the default; replace by "TCP" if you do not want to use TLS
)

# Initialize consumer endpoints
Expand All @@ -241,7 +241,7 @@ cons_1 = Endpoint(
password="VerySecurePassword",
groups="consumers", # this endpoint is part of group "consumers"
local_com_port=3003, # must be unique
connection="TLS"
security="TLS"
)

cons_2 = Endpoint(
Expand All @@ -250,7 +250,7 @@ cons_2 = Endpoint(
password="VerySecurePassword",
groups="consumers", # this endpoint is part of group "consumers"
local_com_port=3004, # must be unique
connection="TLS"
security="TLS"
)
```
A nice thing about `tlspyo` is that all communication is handled behind the scenes.
Expand Down Expand Up @@ -359,7 +359,7 @@ By default, `tlspyo` uses `pickle` for serialization and relies on TLS to preven
In advanced application, you may want to use another serialization protocol instead.
For instance, you may want to transfer non-picklable objects, or further optimize the security of your application.

**In particular, in `connection="TCP"` mode (i.e., with TLS disabled) over a public network, using your own secure serialization protocol is critical.**
**In particular, in `security="TCP"` mode (i.e., with TLS disabled) over a public network, using your own secure serialization protocol is critical.**

`tlspyo` makes this easy.
All you need to do is code your own serialization protocol following the `pickle.dumps`/`pickle.loads` signature, and pass it to the `serializer`/`deserializer` arguments of both your `Relay` and `Endpoints`.
Expand Down Expand Up @@ -402,7 +402,7 @@ if __name__ == '__main__':
port=3000,
password="VerySecurePassword",
local_com_port=3001,
connection="TLS",
security="TLS",
serializer=my_custom_serializer,
deserializer=my_custom_deserializer
)
Expand All @@ -413,7 +413,7 @@ if __name__ == '__main__':
password="VerySecurePassword",
groups="group1",
local_com_port=3002,
connection="TLS",
security="TLS",
serializer=my_custom_serializer,
deserializer=my_custom_deserializer
)
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

setup(name='tlspyo',
packages=[package for package in find_packages()],
version='0.2.0',
download_url='https://github.com/MISTLab/tls-python-object/archive/refs/tags/v0.2.0.tar.gz',
version='0.2.1',
download_url='https://github.com/MISTLab/tls-python-object/archive/refs/tags/v0.2.1.tar.gz',
license='MIT',
description='Secure transport of python objects using TLS encryption',
long_description=long_description,
Expand Down
5 changes: 1 addition & 4 deletions test/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

NUM_OBJECTS = 10


class TestAPI(unittest.TestCase):

# Set up the server and all endpoints for all tests
Expand Down Expand Up @@ -39,7 +40,6 @@ def test_read_with_pop(self):
self.assertRaises(AssertionError, lambda : cons.pop(max_items=-1, blocking=False))
self.assertRaises(AssertionError, lambda : cons.pop(max_items=0, blocking=False))


def test_produce_notify_broadcast(self):
sr = self.ht.spawn_relay
se = self.ht.spawn_endpoint
Expand Down Expand Up @@ -99,7 +99,6 @@ def test_produce_notify_broadcast(self):
self.assertRaises(AssertionError, lambda: prod1.send_object("TEST", 42))
self.assertRaises(AssertionError, lambda: prod1.send_object("TEST", {}))


def test_read_with_receive(self):
'''
Checks receive all functionality with broadcast.
Expand Down Expand Up @@ -128,7 +127,6 @@ def test_read_with_receive(self):
for i in range(NUM_OBJECTS):
self.assertEqual(res[i], f"object {i}")


def test_read_with_get_last(self):
'''
Checks get_last functionality with broadcast.
Expand All @@ -148,7 +146,6 @@ def test_read_with_get_last(self):

# Checks that we have received all objects in the right order
self.assertEqual(res[-1], "object 9")


def tearDown(self):
self.ht.clear()
Expand Down
34 changes: 21 additions & 13 deletions tlspyo/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from tlspyo.utils import get_from_queue


DEFAULT_CONNECTION = "TLS"
DEFAULT_SECURITY = "TLS"
DEFAULT_SERIALIZER = pkl.dumps
DEFAULT_DESERIALIZER = pkl.loads

Expand All @@ -23,7 +23,7 @@ def __init__(self,
accepted_groups=None,
local_com_port: int = 2096,
header_size: int = 10,
connection: str = DEFAULT_CONNECTION,
security: str = DEFAULT_SECURITY,
keys_dir: str = None,
serializer=None,
deserializer=None):
Expand All @@ -45,14 +45,18 @@ def __init__(self,
- 'max_consumables': max number of pending consumables in the group (None for unlimited)
:param local_com_port: int: local port used for internal communication with Twisted.
:param header_size: int: bytes to read at once from socket buffers (the default should work for most cases)
:param connection: str: one of ("TCP", "TLS")
:param security: str: one of (None, "TLS");
None disables TLS, do not use None on a public network unless you know what you are doing!
:param serializer: callable: custom serializer that outputs a bytestring from a python object
:param serializer: callable: custom deserializer that outputs a python object from a bytestring
"""

if connection == "SSL":
connection = "TLS"
assert connection in ("TCP", "TLS"), f"Unsupported connection: {connection}"
assert security in (None, "TLS"), f"Unsupported security: {security}"

if security is None:
security = "TCP"
elif security == "SSL":
security = "TLS"

assert accepted_groups is None or isinstance(accepted_groups, dict), "Invalid format for accepted_groups."

Expand All @@ -75,7 +79,7 @@ def __init__(self,
accepted_groups=accepted_groups,
local_com_port=local_com_port,
header_size=header_size,
connection=connection,
security=security,
keys_dir=keys_dir)
self._p = Process(target=self._server.run, args=())
self._p.start()
Expand Down Expand Up @@ -110,7 +114,7 @@ def __init__(self,
local_com_port: int = 2097,
header_size: int = 10,
max_buf_len: int = 4096,
connection: str = DEFAULT_CONNECTION,
security: str = DEFAULT_SECURITY,
keys_dir: str = None,
hostname: str = "default",
serializer=None,
Expand All @@ -131,14 +135,18 @@ def __init__(self,
:param local_com_port: local port used for internal communication with Twisted
:param header_size: int: number of bytes used for the header (the default should be OK for most cases)
:param max_buf_len: int: max bytes to read at once from socket buffers (the default should be OK for most cases)
:param connection: str: one of ("TCP", "TLS")
:param security: str: one of (None, "TLS");
None disables TLS, do not use None on a public network unless you know what you are doing!
:param serializer: callable: custom serializer that outputs a bytestring from a python object
:param serializer: callable: custom deserializer that outputs a python object from a bytestring
"""

if connection == "SSL":
connection = "TLS"
assert connection in ("TCP", "TLS"), f"Unsupported connection: {connection}"
assert security in (None, "TLS"), f"Unsupported security: {security}"

if security is None:
security = "TCP"
elif security == "SSL":
security = "TLS"

self._stopped = False

Expand Down Expand Up @@ -168,7 +176,7 @@ def __init__(self,
groups=groups,
local_com_port=local_com_port,
header_size=header_size,
connection=connection,
security=security,
keys_dir=keys_dir,
hostname=hostname)

Expand Down
10 changes: 5 additions & 5 deletions tlspyo/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def __init__(self,
header_size=10,
groups=None,
local_com_port=2097,
connection="TLS",
security="TLS",
keys_dir=None,
hostname='default'):

Expand All @@ -151,7 +151,7 @@ def __init__(self,
self.store = []
self.ack_stamp = 0
self.pending_acks = {} # this contains copies of sent commands until corresponding ACKs are received
self._connection = connection
self._security = security
self._keys_dir = keys_dir
self._hostname = hostname

Expand All @@ -168,9 +168,9 @@ def run(self):
reactor.connectTCP(host='127.0.0.1', port=self._local_com_port, factory=LocalProtocolForClientFactory(self))

# Initialize the Internet connection
if self._connection == "TCP":
if self._security == "TCP":
reactor.connectTCP(host=self._ip_server, port=self._port_server, factory=TLSClientFactory(client=self))
elif self._connection == "TLS":
elif self._security == "TLS":
# Use default keys if none are provided
self_signed = os.path.join(self._keys_dir, 'certificate.pem') if self._keys_dir is not None else os.path.join(get_default_keys_folder(), 'certificate.pem')
# Authenticates the server to all potential clients for TLS communication
Expand All @@ -188,7 +188,7 @@ def run(self):
contextFactory=ssl.optionsForClientTLS(hostname=self._hostname, trustRoot=authority)
)
else:
logger.warning(f"Unsupported connection: {self._connection}")
logger.warning(f"Unsupported connection: {self._security}")

# Start the reactor
self._reactor = reactor
Expand Down
10 changes: 5 additions & 5 deletions tlspyo/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ def __init__(self,
accepted_groups=None,
header_size=10,
local_com_port=2097,
connection="TLS",
security="TLS",
keys_dir=None):

self.serializer = serializer
Expand All @@ -235,7 +235,7 @@ def __init__(self,
self.pending_acks = {} # this contains copies of sent commands until corresponding ACKs are received
self._reactor = None
self._listener = None
self._connection = connection
self._security = security
self._keys_dir = keys_dir

def run(self):
Expand All @@ -252,10 +252,10 @@ def run(self):

# Start relay server
factory = ServerProtocolFactory(self)
if self._connection == "TCP":
if self._security == "TCP":
logger.info(f"Listening on TCP to port {self._port}")
reactor.listenTCP(self._port, factory)
elif self._connection == "TLS":
elif self._security == "TLS":
# Use default keys if none are provided
private_key = os.path.join(self._keys_dir, 'key.pem') if self._keys_dir is not None else os.path.join(get_default_keys_folder(), 'key.pem')
self_signed = os.path.join(self._keys_dir, 'certificate.pem') if self._keys_dir is not None else os.path.join(get_default_keys_folder(), 'certificate.pem')
Expand All @@ -269,7 +269,7 @@ def run(self):
logger.info(f"Listening on TLS to port {self._port}, with credentials {private_key} and {self_signed}")
reactor.listenSSL(self._port, factory, context)
else:
logger.warning(f"Unsupported connection: {self._connection}")
logger.warning(f"Unsupported connection: {self._security}")
return

self._reactor = reactor
Expand Down

0 comments on commit a28ed84

Please sign in to comment.