diff --git a/libp2p/__init__.py b/libp2p/__init__.py index 0c660e7..5924bcc 100644 --- a/libp2p/__init__.py +++ b/libp2p/__init__.py @@ -2,6 +2,7 @@ import asyncio import multiaddr from Crypto.PublicKey import RSA +from libp2p.security.insecure_security import InsecureTransport from .peer.peerstore import PeerStore from .peer.id import id_from_public_key from .network.swarm import Swarm @@ -10,7 +11,6 @@ from .kademlia.routed_host import RoutedHost from .transport.upgrader import TransportUpgrader from .transport.tcp.tcp import TCP from .kademlia.network import KademliaServer -from libp2p.security.insecure_security import InsecureTransport async def cleanup_done_tasks(): diff --git a/libp2p/network/connection/raw_connection.py b/libp2p/network/connection/raw_connection.py index 66ef1f0..23cb551 100644 --- a/libp2p/network/connection/raw_connection.py +++ b/libp2p/network/connection/raw_connection.py @@ -1,7 +1,5 @@ -import asyncio from .raw_connection_interface import IRawConnection - class RawConnection(IRawConnection): def __init__(self, ip, port, reader, writer, initiator): diff --git a/libp2p/network/swarm.py b/libp2p/network/swarm.py index 644554c..80c21d9 100644 --- a/libp2p/network/swarm.py +++ b/libp2p/network/swarm.py @@ -147,7 +147,7 @@ class Swarm(INetwork): # to appropriate stream handler (using multiaddr) raw_conn = RawConnection(multiaddr.value_for_protocol('ip4'), multiaddr.value_for_protocol('tcp'), reader, writer, False) - + # Per, https://discuss.libp2p.io/t/multistream-security/130, we first secure # the conn and then mux the conn secured_conn = await self.upgrader.upgrade_security(raw_conn, peer_id, False) diff --git a/libp2p/security/insecure_security.py b/libp2p/security/insecure_security.py index 0c5debe..dfa80a7 100644 --- a/libp2p/security/insecure_security.py +++ b/libp2p/security/insecure_security.py @@ -5,7 +5,7 @@ class InsecureTransport(ISecureTransport): def __init__(self, transport_id): self.transport_id = transport_id - + async def secure_inbound(self, conn): """ Secure the connection, either locally or by communicating with opposing node via conn, diff --git a/libp2p/security/secure_conn_interface.py b/libp2p/security/secure_conn_interface.py index 3b5bb5c..e8433a2 100644 --- a/libp2p/security/secure_conn_interface.py +++ b/libp2p/security/secure_conn_interface.py @@ -1,5 +1,7 @@ from abc import ABC, abstractmethod +# pylint: disable=W0105 + """ Represents a secured connection object, which includes a connection and details about the security involved in the secured connection @@ -19,4 +21,3 @@ class ISecureConn(ABC): """ :return: map containing details about the connections security """ - diff --git a/libp2p/security/secure_transport_interface.py b/libp2p/security/secure_transport_interface.py index 3e49719..54ca8b1 100644 --- a/libp2p/security/secure_transport_interface.py +++ b/libp2p/security/secure_transport_interface.py @@ -1,9 +1,9 @@ -import asyncio - from abc import ABC, abstractmethod +# pylint: disable=W0105 + """ -Transport that is used to secure a connection. This transport is +Transport that is used to secure a connection. This transport is chosen by a security transport multistream module. Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interface.go diff --git a/libp2p/security/security_multistream.py b/libp2p/security/security_multistream.py index 94d2934..c8d2f88 100644 --- a/libp2p/security/security_multistream.py +++ b/libp2p/security/security_multistream.py @@ -1,9 +1,9 @@ -import asyncio - -from abc import ABC, abstractmethod +from abc import ABC from libp2p.protocol_muxer.multiselect_client import MultiselectClient from libp2p.protocol_muxer.multiselect import Multiselect +# pylint: disable=W0105 + """ Represents a secured connection object, which includes a connection and details about the security involved in the secured connection @@ -13,7 +13,7 @@ Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interfa class SecurityMultistream(ABC): def __init__(self): - # Map protocol to secure transport + # Map protocol to secure transport self.transports = {} # Create multiselect @@ -31,7 +31,7 @@ class SecurityMultistream(ABC): # we only care about selecting the protocol, not any handler function self.multiselect.add_handler(protocol, None) - + async def secure_inbound(self, conn): """ Secure the connection, either locally or by communicating with opposing node via conn, @@ -66,19 +66,21 @@ class SecurityMultistream(ABC): async def select_transport(self, conn, initiator): """ - Select a transport that both us and the node on the + Select a transport that both us and the node on the other end of conn support and agree on :param conn: conn to choose a transport over :param initiator: true if we are the initiator, false otherwise :return: selected secure transport """ - # TODO: Is conn acceptable to multiselect/multiselect_client instead of stream? In go repo, - # they pass in a raw conn (https://raw.githubusercontent.com/libp2p/go-conn-security-multistream/master/ssms.go) - + # TODO: Is conn acceptable to multiselect/multiselect_client + # instead of stream? In go repo, they pass in a raw conn + # (https://raw.githubusercontent.com/libp2p/go-conn-security-multistream/master/ssms.go) + protocol = None if initiator: # Select protocol if initiator - protocol = await self.multiselect_client.select_one_of(list(self.transports.keys()), conn) + protocol = \ + await self.multiselect_client.select_one_of(list(self.transports.keys()), conn) else: # Select protocol if non-initiator protocol, _ = await self.multiselect.negotiate(conn) diff --git a/libp2p/transport/upgrader.py b/libp2p/transport/upgrader.py index 68f3762..2ccce24 100644 --- a/libp2p/transport/upgrader.py +++ b/libp2p/transport/upgrader.py @@ -25,8 +25,8 @@ class TransportUpgrader: """ if initiator: return await self.security_multistream.secure_outbound(raw_conn, peer_id) - else: - return await self.security_multistream.secure_inbound(raw_conn) + + return await self.security_multistream.secure_inbound(raw_conn) def upgrade_connection(self, conn, generic_protocol_handler, peer_id): """ diff --git a/tests/security/simple_security.py b/tests/security/simple_security.py index 5df5811..62f5666 100644 --- a/tests/security/simple_security.py +++ b/tests/security/simple_security.py @@ -6,7 +6,7 @@ class SimpleSecurityTransport(ISecureTransport): def __init__(self, key_phrase): self.key_phrase = key_phrase - + async def secure_inbound(self, conn): """ Secure the connection, either locally or by communicating with opposing node via conn, diff --git a/tests/security/test_security_multistream.py b/tests/security/test_security_multistream.py index 1fcc8bc..ed2ccde 100644 --- a/tests/security/test_security_multistream.py +++ b/tests/security/test_security_multistream.py @@ -4,9 +4,8 @@ import pytest from libp2p import new_node from libp2p.peer.peerinfo import info_from_p2p_addr -from tests.utils import cleanup, set_up_nodes_by_transport_opt -from libp2p.security.security_multistream import SecurityMultistream -from libp2p.security.insecure_security import InsecureConn, InsecureTransport +from libp2p.security.insecure_security import InsecureTransport +from tests.utils import cleanup from simple_security import SimpleSecurityTransport # TODO: Add tests for multiple streams being opened on different @@ -25,8 +24,9 @@ async def connect(node1, node2): info = info_from_p2p_addr(addr) await node1.connect(info) -async def perform_simple_test(assertion_func, transports_for_initiator, transports_for_noninitiator): - +async def perform_simple_test(assertion_func, \ + transports_for_initiator, transports_for_noninitiator): + # Create libp2p nodes and connect them, then secure the connection, then check # the proper security was chosen # TODO: implement -- note we need to introduce the notion of communicating over a raw connection @@ -43,9 +43,9 @@ async def perform_simple_test(assertion_func, transports_for_initiator, transpor await connect(node1, node2) - # Wait a very short period to allow conns to be stored (since the functions + # Wait a very short period to allow conns to be stored (since the functions # storing the conns are async, they may happen at slightly different times - # on each node) + # on each node) await asyncio.sleep(0.1) # Get conns @@ -84,7 +84,7 @@ async def test_single_simple_test_security_transport_succeeds(): @pytest.mark.asyncio async def test_two_simple_test_security_transport_for_initiator_succeeds(): - transports_for_initiator = {"tacos": SimpleSecurityTransport("tacos"), + transports_for_initiator = {"tacos": SimpleSecurityTransport("tacos"), "shleep": SimpleSecurityTransport("shleep")} transports_for_noninitiator = {"shleep": SimpleSecurityTransport("shleep")} @@ -93,4 +93,3 @@ async def test_two_simple_test_security_transport_for_initiator_succeeds(): await perform_simple_test(assertion_func, transports_for_initiator, transports_for_noninitiator) -