Update the ISecureConn interface following the reference and simplify accordingly

This commit is contained in:
Alex Stokes 2019-08-02 16:04:46 -07:00
parent ab7653526f
commit 1e5357a1e1
No known key found for this signature in database
GPG Key ID: 51CE1721B245C086
7 changed files with 45 additions and 98 deletions

View File

@ -92,8 +92,10 @@ def initialize_default_swarm(
# TODO TransportUpgrader is not doing anything really # TODO TransportUpgrader is not doing anything really
# TODO parse muxer and sec to pass into TransportUpgrader # TODO parse muxer and sec to pass into TransportUpgrader
muxer = muxer_opt or ["mplex/6.7.0"] muxer = muxer_opt or ["mplex/6.7.0"]
sec = sec_opt or {TProtocol("insecure/1.0.0"): InsecureTransport("insecure")} security_transports_by_protocol = sec_opt or {
upgrader = TransportUpgrader(sec, muxer) TProtocol("insecure/1.0.0"): InsecureTransport()
}
upgrader = TransportUpgrader(security_transports_by_protocol, muxer)
peerstore = peerstore_opt or PeerStore() peerstore = peerstore_opt or PeerStore()
# TODO: Initialize discovery if not presented # TODO: Initialize discovery if not presented

View File

@ -1,10 +1,7 @@
from typing import cast
from libp2p.network.connection.raw_connection_interface import IRawConnection from libp2p.network.connection.raw_connection_interface import IRawConnection
from libp2p.peer.id import ID from libp2p.peer.id import ID
from libp2p.security.secure_conn_interface import ISecureConn from libp2p.security.secure_conn_interface import ISecureConn
from libp2p.security.secure_transport_interface import ISecureTransport from libp2p.security.secure_transport_interface import ISecureTransport
from libp2p.security.typing import TSecurityDetails
class InsecureTransport(ISecureTransport): class InsecureTransport(ISecureTransport):
@ -13,19 +10,13 @@ class InsecureTransport(ISecureTransport):
i.e. the upgraded transport does not add any additional security. i.e. the upgraded transport does not add any additional security.
""" """
transport_id: str
def __init__(self, transport_id: str) -> None:
self.transport_id = transport_id
async def secure_inbound(self, conn: IRawConnection) -> ISecureConn: async def secure_inbound(self, conn: IRawConnection) -> ISecureConn:
""" """
Secure the connection, either locally or by communicating with opposing node via conn, Secure the connection, either locally or by communicating with opposing node via conn,
for an inbound connection (i.e. we are not the initiator) for an inbound connection (i.e. we are not the initiator)
:return: secure connection object (that implements secure_conn_interface) :return: secure connection object (that implements secure_conn_interface)
""" """
insecure_conn = InsecureConn(conn, self.transport_id) return conn
return insecure_conn
async def secure_outbound(self, conn: IRawConnection, peer_id: ID) -> ISecureConn: async def secure_outbound(self, conn: IRawConnection, peer_id: ID) -> ISecureConn:
""" """
@ -33,27 +24,4 @@ class InsecureTransport(ISecureTransport):
for an inbound connection (i.e. we are the initiator) for an inbound connection (i.e. we are the initiator)
:return: secure connection object (that implements secure_conn_interface) :return: secure connection object (that implements secure_conn_interface)
""" """
insecure_conn = InsecureConn(conn, self.transport_id) return conn
return insecure_conn
class InsecureConn(ISecureConn):
conn: IRawConnection
details: TSecurityDetails
def __init__(self, conn: IRawConnection, conn_id: str) -> None:
self.conn = conn
self.details = cast(TSecurityDetails, {})
self.details["id"] = conn_id
def get_conn(self) -> IRawConnection:
"""
:return: connection object that has been made secure
"""
return self.conn
def get_security_details(self) -> TSecurityDetails:
"""
:return: map containing details about the connections security
"""
return self.details

View File

@ -1,7 +1,7 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from libp2p.peer.id import ID
from libp2p.network.connection.raw_connection_interface import IRawConnection from libp2p.network.connection.raw_connection_interface import IRawConnection
from libp2p.security.typing import TSecurityDetails
""" """
@ -12,15 +12,23 @@ Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interfa
""" """
class ISecureConn(ABC): class AbstractSecureConn(ABC):
@abstractmethod @abstractmethod
def get_conn(self) -> IRawConnection: def get_local_peer(self) -> ID:
""" pass
:return: the underlying raw connection
"""
@abstractmethod @abstractmethod
def get_security_details(self) -> TSecurityDetails: def get_local_private_key(self) -> bytes:
""" pass
:return: map containing details about the connections security
""" @abstractmethod
def get_remote_peer(self) -> ID:
pass
@abstractmethod
def get_remote_public_key(self) -> bytes:
pass
class ISecureConn(AbstractSecureConn, IRawConnection):
pass

View File

@ -23,11 +23,14 @@ class SecurityMultistream(ABC):
multiselect: Multiselect multiselect: Multiselect
multiselect_client: MultiselectClient multiselect_client: MultiselectClient
def __init__(self) -> None: def __init__(self, secure_transports_by_protocol) -> None:
self.transports = {} self.transports = {}
self.multiselect = Multiselect() self.multiselect = Multiselect()
self.multiselect_client = MultiselectClient() self.multiselect_client = MultiselectClient()
for protocol, transport in secure_transports_by_protocol.items():
self.add_transport(protocol, transport)
def add_transport(self, protocol: TProtocol, transport: ISecureTransport) -> None: def add_transport(self, protocol: TProtocol, transport: ISecureTransport) -> None:
self.transports[protocol] = transport self.transports[protocol] = transport

View File

@ -1,11 +1,9 @@
import asyncio import asyncio
from typing import cast
from libp2p.network.connection.raw_connection_interface import IRawConnection from libp2p.network.connection.raw_connection_interface import IRawConnection
from libp2p.peer.id import ID from libp2p.peer.id import ID
from libp2p.security.secure_conn_interface import ISecureConn from libp2p.security.secure_conn_interface import ISecureConn
from libp2p.security.secure_transport_interface import ISecureTransport from libp2p.security.secure_transport_interface import ISecureTransport
from libp2p.security.typing import TSecurityDetails
class SimpleSecurityTransport(ISecureTransport): class SimpleSecurityTransport(ISecureTransport):
@ -28,8 +26,7 @@ class SimpleSecurityTransport(ISecureTransport):
"Key phrase differed between nodes. Expected " + self.key_phrase "Key phrase differed between nodes. Expected " + self.key_phrase
) )
secure_conn = SimpleSecureConn(conn, self.key_phrase) return conn
return secure_conn
async def secure_outbound(self, conn: IRawConnection, peer_id: ID) -> ISecureConn: async def secure_outbound(self, conn: IRawConnection, peer_id: ID) -> ISecureConn:
""" """
@ -49,28 +46,4 @@ class SimpleSecurityTransport(ISecureTransport):
"Key phrase differed between nodes. Expected " + self.key_phrase "Key phrase differed between nodes. Expected " + self.key_phrase
) )
secure_conn = SimpleSecureConn(conn, self.key_phrase) return conn
return secure_conn
class SimpleSecureConn(ISecureConn):
conn: IRawConnection
key_phrase: str
details: TSecurityDetails
def __init__(self, conn: IRawConnection, key_phrase: str) -> None:
self.conn = conn
self.details = cast(TSecurityDetails, {})
self.details["key_phrase"] = key_phrase
def get_conn(self) -> IRawConnection:
"""
:return: connection object that has been made secure
"""
return self.conn
def get_security_details(self) -> TSecurityDetails:
"""
:return: map containing details about the connections security
"""
return self.details

View File

@ -1,13 +1,12 @@
import asyncio import asyncio
from typing import Dict, Tuple from typing import Dict, Tuple
from multiaddr import Multiaddr
from libp2p.network.connection.raw_connection_interface import IRawConnection from libp2p.network.connection.raw_connection_interface import IRawConnection
from libp2p.network.typing import GenericProtocolHandlerFn from libp2p.network.typing import GenericProtocolHandlerFn
from libp2p.peer.id import ID from libp2p.peer.id import ID
from libp2p.security.secure_conn_interface import ISecureConn from libp2p.security.secure_conn_interface import ISecureConn
from libp2p.stream_muxer.abc import IMuxedConn, IMuxedStream from libp2p.stream_muxer.abc import IMuxedConn, IMuxedStream
from multiaddr import Multiaddr
from .constants import HeaderTags from .constants import HeaderTags
from .mplex_stream import MplexStream from .mplex_stream import MplexStream
@ -39,11 +38,8 @@ class Mplex(IMuxedConn):
for new muxed streams for new muxed streams
:param peer_id: peer_id of peer the connection is to :param peer_id: peer_id of peer the connection is to
""" """
super().__init__(secured_conn, generic_protocol_handler, peer_id) self.conn = secured_conn
self.initiator = self.conn.initiator
self.secured_conn = secured_conn
self.raw_conn = secured_conn.get_conn()
self.initiator = self.raw_conn.initiator
# Store generic protocol handler # Store generic protocol handler
self.generic_protocol_handler = generic_protocol_handler self.generic_protocol_handler = generic_protocol_handler
@ -63,7 +59,7 @@ class Mplex(IMuxedConn):
""" """
close the stream muxer and underlying raw connection close the stream muxer and underlying raw connection
""" """
self.raw_conn.close() self.conn.close()
def is_closed(self) -> bool: def is_closed(self) -> bool:
""" """
@ -99,7 +95,7 @@ class Mplex(IMuxedConn):
:param multi_addr: multi_addr that stream connects to :param multi_addr: multi_addr that stream connects to
:return: a new stream :return: a new stream
""" """
stream_id = self.raw_conn.next_stream_id() stream_id = self.conn.next_stream_id()
stream = MplexStream(stream_id, multi_addr, self) stream = MplexStream(stream_id, multi_addr, self)
self.buffers[stream_id] = asyncio.Queue() self.buffers[stream_id] = asyncio.Queue()
await self.send_message(HeaderTags.NewStream, None, stream_id) await self.send_message(HeaderTags.NewStream, None, stream_id)
@ -139,8 +135,8 @@ class Mplex(IMuxedConn):
:param _bytes: byte array to write :param _bytes: byte array to write
:return: length written :return: length written
""" """
self.raw_conn.writer.write(_bytes) self.conn.writer.write(_bytes)
await self.raw_conn.writer.drain() await self.conn.writer.drain()
return len(_bytes) return len(_bytes)
async def handle_incoming(self) -> None: async def handle_incoming(self) -> None:
@ -177,10 +173,10 @@ class Mplex(IMuxedConn):
# loop in handle_incoming # loop in handle_incoming
timeout = 0.1 timeout = 0.1
try: try:
header = await decode_uvarint_from_stream(self.raw_conn.reader, timeout) header = await decode_uvarint_from_stream(self.conn.reader, timeout)
length = await decode_uvarint_from_stream(self.raw_conn.reader, timeout) length = await decode_uvarint_from_stream(self.conn.reader, timeout)
message = await asyncio.wait_for( message = await asyncio.wait_for(
self.raw_conn.reader.read(length), timeout=timeout self.conn.reader.read(length), timeout=timeout
) )
except asyncio.TimeoutError: except asyncio.TimeoutError:
return None, None, None return None, None, None

View File

@ -18,14 +18,11 @@ class TransportUpgrader:
muxer: Sequence[str] muxer: Sequence[str]
def __init__( def __init__(
self, secOpt: Mapping[TProtocol, ISecureTransport], muxerOpt: Sequence[str] self,
) -> None: secure_transports_by_protocol: Mapping[TProtocol, ISecureTransport],
# Store security option muxerOpt: Sequence[str],
self.security_multistream = SecurityMultistream() ):
for key in secOpt: self.security_multistream = SecurityMultistream(secure_transports_by_protocol)
self.security_multistream.add_transport(key, secOpt[key])
# Store muxer option
self.muxer = muxerOpt self.muxer = muxerOpt
def upgrade_listener(self, transport: ITransport, listeners: IListener) -> None: def upgrade_listener(self, transport: ITransport, listeners: IListener) -> None: