py-libp2p/tests/security/test_security_multistream.py

194 lines
6.0 KiB
Python
Raw Normal View History

import asyncio
2019-08-03 13:36:19 +08:00
import multiaddr
import pytest
from libp2p import new_node
2019-08-16 09:36:50 +08:00
from libp2p.crypto.rsa import create_new_key_pair
from libp2p.peer.peerinfo import info_from_p2p_addr
2019-05-02 05:13:01 +08:00
from libp2p.protocol_muxer.multiselect_client import MultiselectClientError
2019-08-03 09:36:58 +08:00
from libp2p.security.insecure.transport import InsecureSession, InsecureTransport
from libp2p.security.simple.transport import SimpleSecurityTransport
2019-08-16 09:36:50 +08:00
from tests.utils import cleanup, connect
2019-04-30 06:05:49 +08:00
# TODO: Add tests for multiple streams being opened on different
# protocols through the same connection
2019-08-01 06:00:12 +08:00
def peer_id_for_node(node):
addr = node.get_addrs()[0]
info = info_from_p2p_addr(addr)
return info.peer_id
2019-08-01 06:00:12 +08:00
2019-08-16 09:36:50 +08:00
initiator_key_pair = create_new_key_pair()
2019-08-03 09:36:58 +08:00
2019-08-16 09:36:50 +08:00
noninitiator_key_pair = create_new_key_pair()
2019-08-03 09:36:58 +08:00
2019-08-01 06:00:12 +08:00
async def perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
):
2019-05-02 01:54:19 +08:00
2019-04-30 06:05:49 +08:00
# 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
# for testing, we do NOT want to communicate over a stream so we can't just create two nodes
# and use their conn because our mplex will internally relay messages to a stream
2019-05-01 04:07:26 +08:00
sec_opt1 = transports_for_initiator
sec_opt2 = transports_for_noninitiator
2019-04-30 06:05:49 +08:00
node1 = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/0"], sec_opt=sec_opt1)
node2 = await new_node(transport_opt=["/ip4/127.0.0.1/tcp/0"], sec_opt=sec_opt2)
2019-04-30 06:05:49 +08:00
await node1.get_network().listen(multiaddr.Multiaddr("/ip4/127.0.0.1/tcp/0"))
await node2.get_network().listen(multiaddr.Multiaddr("/ip4/127.0.0.1/tcp/0"))
2019-04-30 06:05:49 +08:00
await connect(node1, node2)
2019-04-30 06:05:49 +08:00
2019-05-02 01:54:19 +08:00
# 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
2019-05-02 01:54:19 +08:00
# on each node)
await asyncio.sleep(0.1)
2019-04-30 06:05:49 +08:00
# Get conns
node1_conn = node1.get_network().connections[peer_id_for_node(node2)]
node2_conn = node2.get_network().connections[peer_id_for_node(node1)]
2019-04-30 06:05:49 +08:00
# Perform assertion
2019-08-03 09:36:58 +08:00
assertion_func(node1_conn.conn)
assertion_func(node2_conn.conn)
2019-04-30 06:05:49 +08:00
# Success, terminate pending tasks.
2019-04-30 06:05:49 +08:00
await cleanup()
@pytest.mark.asyncio
async def test_single_insecure_security_transport_succeeds():
2019-08-16 09:36:50 +08:00
transports_for_initiator = {"foo": InsecureTransport(initiator_key_pair)}
transports_for_noninitiator = {"foo": InsecureTransport(noninitiator_key_pair)}
2019-04-30 06:05:49 +08:00
2019-08-03 09:36:58 +08:00
def assertion_func(conn):
assert isinstance(conn, InsecureSession)
2019-04-30 06:05:49 +08:00
await perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
)
2019-08-01 06:00:12 +08:00
2019-04-30 06:05:49 +08:00
@pytest.mark.asyncio
async def test_single_simple_test_security_transport_succeeds():
2019-08-03 09:36:58 +08:00
transports_for_initiator = {
2019-08-16 09:36:50 +08:00
"tacos": SimpleSecurityTransport(initiator_key_pair, "tacos")
2019-08-03 09:36:58 +08:00
}
transports_for_noninitiator = {
2019-08-16 09:36:50 +08:00
"tacos": SimpleSecurityTransport(noninitiator_key_pair, "tacos")
2019-08-03 09:36:58 +08:00
}
2019-08-03 09:36:58 +08:00
def assertion_func(conn):
assert conn.key_phrase == "tacos"
await perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
)
2019-08-01 06:00:12 +08:00
2019-05-01 04:07:26 +08:00
@pytest.mark.asyncio
async def test_two_simple_test_security_transport_for_initiator_succeeds():
2019-08-01 06:00:12 +08:00
transports_for_initiator = {
2019-08-16 09:36:50 +08:00
"tacos": SimpleSecurityTransport(initiator_key_pair, "tacos"),
"shleep": SimpleSecurityTransport(initiator_key_pair, "shleep"),
2019-08-03 09:36:58 +08:00
}
transports_for_noninitiator = {
2019-08-16 09:36:50 +08:00
"shleep": SimpleSecurityTransport(noninitiator_key_pair, "shleep")
2019-08-01 06:00:12 +08:00
}
2019-05-01 04:07:26 +08:00
2019-08-03 09:36:58 +08:00
def assertion_func(conn):
assert conn.key_phrase == "shleep"
2019-05-01 04:07:26 +08:00
await perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
)
2019-08-01 06:00:12 +08:00
2019-05-02 05:13:01 +08:00
@pytest.mark.asyncio
async def test_two_simple_test_security_transport_for_noninitiator_succeeds():
2019-08-03 09:36:58 +08:00
transports_for_initiator = {
2019-08-16 09:36:50 +08:00
"tacos": SimpleSecurityTransport(initiator_key_pair, "tacos")
2019-08-03 09:36:58 +08:00
}
2019-08-01 06:00:12 +08:00
transports_for_noninitiator = {
2019-08-16 09:36:50 +08:00
"shleep": SimpleSecurityTransport(noninitiator_key_pair, "shleep"),
"tacos": SimpleSecurityTransport(noninitiator_key_pair, "tacos"),
2019-08-01 06:00:12 +08:00
}
2019-05-02 05:13:01 +08:00
2019-08-03 09:36:58 +08:00
def assertion_func(conn):
assert conn.key_phrase == "tacos"
2019-05-02 05:13:01 +08:00
await perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
)
2019-05-02 05:13:01 +08:00
@pytest.mark.asyncio
async def test_two_simple_test_security_transport_for_both_succeeds():
2019-08-01 06:00:12 +08:00
transports_for_initiator = {
2019-08-16 09:36:50 +08:00
"a": SimpleSecurityTransport(initiator_key_pair, "a"),
"b": SimpleSecurityTransport(initiator_key_pair, "b"),
2019-08-01 06:00:12 +08:00
}
transports_for_noninitiator = {
2019-08-16 09:36:50 +08:00
"b": SimpleSecurityTransport(noninitiator_key_pair, "b"),
"c": SimpleSecurityTransport(noninitiator_key_pair, "c"),
2019-08-01 06:00:12 +08:00
}
2019-05-02 05:13:01 +08:00
2019-08-03 09:36:58 +08:00
def assertion_func(conn):
assert conn.key_phrase == "b"
2019-05-02 05:13:01 +08:00
await perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
)
2019-08-01 06:00:12 +08:00
2019-05-02 05:13:01 +08:00
@pytest.mark.asyncio
async def test_multiple_security_none_the_same_fails():
2019-08-01 06:00:12 +08:00
transports_for_initiator = {
2019-08-16 09:36:50 +08:00
"a": SimpleSecurityTransport(initiator_key_pair, "a"),
"b": SimpleSecurityTransport(initiator_key_pair, "b"),
2019-08-01 06:00:12 +08:00
}
transports_for_noninitiator = {
2019-08-16 09:36:50 +08:00
"d": SimpleSecurityTransport(noninitiator_key_pair, "d"),
"c": SimpleSecurityTransport(noninitiator_key_pair, "c"),
2019-08-01 06:00:12 +08:00
}
2019-05-02 05:13:01 +08:00
def assertion_func(_):
assert False
with pytest.raises(MultiselectClientError):
2019-08-01 06:00:12 +08:00
await perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
)
2019-05-02 05:13:01 +08:00
await cleanup()
2019-08-01 06:00:12 +08:00
2019-05-02 05:13:01 +08:00
@pytest.mark.asyncio
async def test_default_insecure_security():
transports_for_initiator = None
transports_for_noninitiator = None
2019-08-03 09:36:58 +08:00
conn1 = None
conn2 = None
2019-05-02 05:13:01 +08:00
2019-08-03 09:36:58 +08:00
def assertion_func(conn):
nonlocal conn1
nonlocal conn2
if not conn1:
conn1 = conn
elif not conn2:
conn2 = conn
2019-05-02 05:13:01 +08:00
else:
2019-08-03 09:36:58 +08:00
assert conn1 == conn2
2019-05-02 05:13:01 +08:00
await perform_simple_test(
assertion_func, transports_for_initiator, transports_for_noninitiator
)