mirror of
https://github.com/varun-r-mallya/py-libp2p.git
synced 2026-02-08 22:20:53 +00:00
Integrate security selectin into libp2p system
This commit is contained in:
@ -10,6 +10,7 @@ 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():
|
||||
@ -71,7 +72,9 @@ def initialize_default_swarm(
|
||||
transport = [multiaddr.Multiaddr(t) for t in transport_opt]
|
||||
# TODO wire muxer up with swarm
|
||||
# muxer = muxer_opt or ["mplex/6.7.0"]
|
||||
sec = sec_opt or ["secio"]
|
||||
|
||||
# Use passed in security option or the default insecure option
|
||||
sec = sec_opt or {"/insecure/1.0.0": InsecureTransport("insecure")}
|
||||
peerstore = peerstore_opt or PeerStore()
|
||||
upgrader = TransportUpgrader(sec, transport)
|
||||
swarm_opt = Swarm(id_opt, peerstore, upgrader)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
from .raw_connection_interface import IRawConnection
|
||||
|
||||
|
||||
@ -12,6 +13,19 @@ class RawConnection(IRawConnection):
|
||||
self._next_id = 0 if initiator else 1
|
||||
self.initiator = initiator
|
||||
|
||||
async def write(self, data):
|
||||
self.writer.write(data)
|
||||
self.writer.write("\n".encode())
|
||||
await self.writer.drain()
|
||||
|
||||
async def read(self):
|
||||
line = await self.reader.readline()
|
||||
adjusted_line = line.decode().rstrip('\n')
|
||||
|
||||
# TODO: figure out a way to remove \n without going back and forth with
|
||||
# encoding and decoding
|
||||
return adjusted_line.encode()
|
||||
|
||||
def close(self):
|
||||
self.writer.close()
|
||||
|
||||
|
||||
@ -69,8 +69,10 @@ class Swarm(INetwork):
|
||||
# Transport dials peer (gets back a raw conn)
|
||||
raw_conn = await self.transport.dial(multiaddr, self.self_id)
|
||||
|
||||
# Use upgrader to upgrade raw conn to muxed conn
|
||||
muxed_conn = self.upgrader.upgrade_connection(raw_conn, \
|
||||
# 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, True)
|
||||
muxed_conn = self.upgrader.upgrade_connection(secured_conn, \
|
||||
self.generic_protocol_handler, peer_id)
|
||||
|
||||
# Store muxed connection in connections
|
||||
@ -145,7 +147,11 @@ 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)
|
||||
muxed_conn = self.upgrader.upgrade_connection(raw_conn, \
|
||||
|
||||
# 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)
|
||||
muxed_conn = self.upgrader.upgrade_connection(secured_conn, \
|
||||
self.generic_protocol_handler, peer_id)
|
||||
|
||||
# Store muxed_conn with peer id
|
||||
|
||||
@ -45,7 +45,6 @@ class MultiselectClient(IMultiselectClient):
|
||||
:param stream: stream to communicate with multiselect over
|
||||
:return: selected protocol
|
||||
"""
|
||||
|
||||
# Create a communicator to handle all communication across the stream
|
||||
communicator = MultiselectCommunicator(stream)
|
||||
|
||||
|
||||
44
libp2p/security/insecure_security.py
Normal file
44
libp2p/security/insecure_security.py
Normal file
@ -0,0 +1,44 @@
|
||||
from libp2p.security.secure_transport_interface import ISecureTransport
|
||||
from libp2p.security.secure_conn_interface import ISecureConn
|
||||
|
||||
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,
|
||||
for an inbound connection (i.e. we are not the initiator)
|
||||
:return: secure connection object (that implements secure_conn_interface)
|
||||
"""
|
||||
insecure_conn = InsecureConn(conn, self.transport_id)
|
||||
return insecure_conn
|
||||
|
||||
async def secure_outbound(self, conn, peer_id):
|
||||
"""
|
||||
Secure the connection, either locally or by communicating with opposing node via conn,
|
||||
for an inbound connection (i.e. we are the initiator)
|
||||
:return: secure connection object (that implements secure_conn_interface)
|
||||
"""
|
||||
insecure_conn = InsecureConn(conn, self.transport_id)
|
||||
return insecure_conn
|
||||
|
||||
class InsecureConn(ISecureConn):
|
||||
|
||||
def __init__(self, conn, conn_id):
|
||||
self.conn = conn
|
||||
self.details = {}
|
||||
self.details["id"] = conn_id
|
||||
|
||||
def get_conn(self):
|
||||
"""
|
||||
:return: connection object that has been made secure
|
||||
"""
|
||||
return self.conn
|
||||
|
||||
def get_security_details(self):
|
||||
"""
|
||||
:return: map containing details about the connections security
|
||||
"""
|
||||
return self.details
|
||||
@ -12,7 +12,7 @@ Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interfa
|
||||
"""
|
||||
class SecurityMultistream(ABC):
|
||||
|
||||
def __init__():
|
||||
def __init__(self):
|
||||
# Map protocol to secure transport
|
||||
self.transports = {}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ class Mplex(IMuxedConn):
|
||||
reference: https://github.com/libp2p/go-mplex/blob/master/multiplex.go
|
||||
"""
|
||||
|
||||
def __init__(self, conn, generic_protocol_handler, peer_id):
|
||||
def __init__(self, secured_conn, generic_protocol_handler, peer_id):
|
||||
"""
|
||||
create a new muxed connection
|
||||
:param conn: an instance of raw connection
|
||||
@ -19,10 +19,11 @@ class Mplex(IMuxedConn):
|
||||
for new muxed streams
|
||||
:param peer_id: peer_id of peer the connection is to
|
||||
"""
|
||||
super(Mplex, self).__init__(conn, generic_protocol_handler, peer_id)
|
||||
super(Mplex, self).__init__(secured_conn, generic_protocol_handler, peer_id)
|
||||
|
||||
self.raw_conn = conn
|
||||
self.initiator = conn.initiator
|
||||
self.secured_conn = secured_conn
|
||||
self.raw_conn = secured_conn.get_conn()
|
||||
self.initiator = self.raw_conn.initiator
|
||||
|
||||
# Store generic protocol handler
|
||||
self.generic_protocol_handler = generic_protocol_handler
|
||||
|
||||
@ -10,7 +10,7 @@ class IMuxedConn(ABC):
|
||||
def __init__(self, conn, generic_protocol_handler, peer_id):
|
||||
"""
|
||||
create a new muxed connection
|
||||
:param conn: an instance of raw connection
|
||||
:param conn: an instance of secured connection
|
||||
:param generic_protocol_handler: generic protocol handler
|
||||
for new muxed streams
|
||||
:param peer_id: peer_id of peer the connection is to
|
||||
|
||||
@ -82,9 +82,10 @@ class TCP(ITransport):
|
||||
await writer.drain()
|
||||
|
||||
# Await ack for peer id
|
||||
ack = (await reader.read(1024)).decode()
|
||||
expected_ack_str = "received peer id"
|
||||
ack = (await reader.read(len(expected_ack_str))).decode()
|
||||
|
||||
if ack != "received peer id":
|
||||
if ack != expected_ack_str:
|
||||
raise Exception("Receiver did not receive peer id")
|
||||
|
||||
return RawConnection(host, port, reader, writer, True)
|
||||
|
||||
@ -1,11 +1,17 @@
|
||||
from libp2p.stream_muxer.mplex.mplex import Mplex
|
||||
from libp2p.security.security_multistream import SecurityMultistream
|
||||
|
||||
|
||||
class TransportUpgrader:
|
||||
# pylint: disable=no-self-use
|
||||
|
||||
def __init__(self, secOpt, muxerOpt):
|
||||
self.sec = secOpt
|
||||
# Store security option
|
||||
self.security_multistream = SecurityMultistream()
|
||||
for key in secOpt:
|
||||
self.security_multistream.add_transport(key, secOpt[key])
|
||||
|
||||
# Store muxer option
|
||||
self.muxer = muxerOpt
|
||||
|
||||
def upgrade_listener(self, transport, listeners):
|
||||
@ -13,12 +19,14 @@ class TransportUpgrader:
|
||||
Upgrade multiaddr listeners to libp2p-transport listeners
|
||||
"""
|
||||
|
||||
def upgrade_security(self, conn, peer_id):
|
||||
async def upgrade_security(self, raw_conn, peer_id, initiator):
|
||||
"""
|
||||
Upgrade conn to be a secured connection
|
||||
"""
|
||||
# TODO: Do exchange to determine security module
|
||||
pass
|
||||
if initiator:
|
||||
return await self.security_multistream.secure_outbound(raw_conn, peer_id)
|
||||
else:
|
||||
return await self.security_multistream.secure_inbound(raw_conn)
|
||||
|
||||
def upgrade_connection(self, conn, generic_protocol_handler, peer_id):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user