From 6df75729b55d690a6d5acc54087d60fde49c53e6 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 17 Jan 2018 22:07:04 -0800 Subject: [PATCH 01/14] initial commit --- p2p/net/conn-security-multistream/ssms.go | 85 +++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 p2p/net/conn-security-multistream/ssms.go diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go new file mode 100644 index 0000000000..2b6b4666b6 --- /dev/null +++ b/p2p/net/conn-security-multistream/ssms.go @@ -0,0 +1,85 @@ +package ssms + +import ( + "context" + "fmt" + "net" + + peer "github.com/libp2p/go-libp2p-peer" + ss "github.com/libp2p/go-stream-security" + mss "github.com/multiformats/go-multistream" +) + +// SSMuxer is a multistream stream security transport multiplexer. +// +// SSMuxer is safe to use without initialization. However, it's not safe to move +// after use. +type SSMuxer struct { + mux mss.MultistreamMuxer + tpts map[string]ss.Transport + OrderPreference []string +} + +// AddTransport adds a stream security transport to this multistream muxer. +// +// This method is *not* thread-safe. It should be called only when initializing +// the SSMuxer. +func (sm *SSMuxer) AddTransport(path string, transport ss.Transport) { + if sm.tpts == nil { + sm.tpts = make(map[string]ss.Transport, 1) + } + + sm.mux.AddHandler(path, nil) + sm.tpts[path] = transport + sm.OrderPreference = append(sm.OrderPreference, path) +} + +// SecureInbound secures an inbound connection using this multistream +// multiplexed stream security transport. +func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (ss.Conn, error) { + tpt, err := sm.selectProto(ctx, insecure, true) + if err != nil { + return nil, err + } + return tpt.SecureInbound(ctx, insecure) +} + +// SecureOutbound secures an outbound connection using this multistream +// multiplexed stream security transport. +func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (ss.Conn, error) { + tpt, err := sm.selectProto(ctx, insecure, false) + if err != nil { + return nil, err + } + return tpt.SecureOutbound(ctx, insecure, p) +} + +func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (ss.Transport, error) { + var proto string + var err error + done := make(chan struct{}) + go func() { + defer close(done) + if server { + proto, _, err = sm.mux.Negotiate(insecure) + } else { + proto, err = mss.SelectOneOf(sm.OrderPreference, insecure) + } + }() + + select { + case <-done: + if err != nil { + return nil, err + } + if tpt, ok := sm.tpts[proto]; ok { + return tpt, nil + } + return nil, fmt.Errorf("selected unknown security transport") + case <-ctx.Done(): + // We *must* do this. We have outstanding work on the connection + // and it's no longer safe to use. + insecure.Close() + return nil, ctx.Err() + } +} From 58590694774217460d1e6e863f8e1f0803b6642b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 18 Jan 2018 11:24:21 -0800 Subject: [PATCH 02/14] type assert transport --- p2p/net/conn-security-multistream/ssms.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index 2b6b4666b6..0adbe0f7a8 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -20,6 +20,8 @@ type SSMuxer struct { OrderPreference []string } +var _ ss.Transport = (*SSMuxer)(nil) + // AddTransport adds a stream security transport to this multistream muxer. // // This method is *not* thread-safe. It should be called only when initializing From cae12315981846556c42fa3b64d7ceaa2db0f6e1 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 18 Jan 2018 11:45:08 -0800 Subject: [PATCH 03/14] add tests --- .../conn-security-multistream/ssms_test.go | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 p2p/net/conn-security-multistream/ssms_test.go diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go new file mode 100644 index 0000000000..faa1c87dfd --- /dev/null +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -0,0 +1,55 @@ +package ssms + +import ( + "context" + "net" + "sync" + "testing" + + ss "github.com/libp2p/go-stream-security" + sst "github.com/libp2p/go-stream-security/test" +) + +func TestCommonProto(t *testing.T) { + var at, bt SSMuxer + atInsecure := ss.InsecureTransport("peerA") + btInsecure := ss.InsecureTransport("peerB") + at.AddTransport("/plaintext/1.0.0", &atInsecure) + bt.AddTransport("/plaintext/1.1.0", &btInsecure) + bt.AddTransport("/plaintext/1.0.0", &btInsecure) + sst.SubtestRW(t, &at, &bt, "peerA", "peerB") +} + +func TestNoCommonProto(t *testing.T) { + var at, bt SSMuxer + atInsecure := ss.InsecureTransport("peerA") + btInsecure := ss.InsecureTransport("peerB") + + at.AddTransport("/plaintext/1.0.0", &atInsecure) + bt.AddTransport("/plaintext/1.1.0", &btInsecure) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + a, b := net.Pipe() + + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + defer a.Close() + _, err := at.SecureInbound(ctx, a) + if err == nil { + t.Fatal("conection should have failed") + } + }() + + go func() { + defer wg.Done() + defer b.Close() + _, err := bt.SecureOutbound(ctx, b, "peerA") + if err == nil { + t.Fatal("connection should have failed") + } + }() + wg.Wait() +} From fc8c4a8fbf05e9787057c82c5b0e5da26a3b8b33 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Sun, 28 Jan 2018 18:04:12 -0800 Subject: [PATCH 04/14] complete rename --- p2p/net/conn-security-multistream/ssms.go | 18 +++++++++--------- p2p/net/conn-security-multistream/ssms_test.go | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index 0adbe0f7a8..75bbb10f44 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -1,4 +1,4 @@ -package ssms +package csms import ( "context" @@ -6,7 +6,7 @@ import ( "net" peer "github.com/libp2p/go-libp2p-peer" - ss "github.com/libp2p/go-stream-security" + connsec "github.com/libp2p/go-conn-security" mss "github.com/multiformats/go-multistream" ) @@ -16,19 +16,19 @@ import ( // after use. type SSMuxer struct { mux mss.MultistreamMuxer - tpts map[string]ss.Transport + tpts map[string]connsec.Transport OrderPreference []string } -var _ ss.Transport = (*SSMuxer)(nil) +var _ connsec.Transport = (*SSMuxer)(nil) // AddTransport adds a stream security transport to this multistream muxer. // // This method is *not* thread-safe. It should be called only when initializing // the SSMuxer. -func (sm *SSMuxer) AddTransport(path string, transport ss.Transport) { +func (sm *SSMuxer) AddTransport(path string, transport connsec.Transport) { if sm.tpts == nil { - sm.tpts = make(map[string]ss.Transport, 1) + sm.tpts = make(map[string]connsec.Transport, 1) } sm.mux.AddHandler(path, nil) @@ -38,7 +38,7 @@ func (sm *SSMuxer) AddTransport(path string, transport ss.Transport) { // SecureInbound secures an inbound connection using this multistream // multiplexed stream security transport. -func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (ss.Conn, error) { +func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (connsec.Conn, error) { tpt, err := sm.selectProto(ctx, insecure, true) if err != nil { return nil, err @@ -48,7 +48,7 @@ func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (ss.Con // SecureOutbound secures an outbound connection using this multistream // multiplexed stream security transport. -func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (ss.Conn, error) { +func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (connsec.Conn, error) { tpt, err := sm.selectProto(ctx, insecure, false) if err != nil { return nil, err @@ -56,7 +56,7 @@ func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer return tpt.SecureOutbound(ctx, insecure, p) } -func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (ss.Transport, error) { +func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (connsec.Transport, error) { var proto string var err error done := make(chan struct{}) diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index faa1c87dfd..5d72458562 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -1,4 +1,4 @@ -package ssms +package csms import ( "context" @@ -6,14 +6,14 @@ import ( "sync" "testing" - ss "github.com/libp2p/go-stream-security" - sst "github.com/libp2p/go-stream-security/test" + connsec "github.com/libp2p/go-conn-security" + sst "github.com/libp2p/go-conn-security/test" ) func TestCommonProto(t *testing.T) { var at, bt SSMuxer - atInsecure := ss.InsecureTransport("peerA") - btInsecure := ss.InsecureTransport("peerB") + atInsecure := connsec.InsecureTransport("peerA") + btInsecure := connsec.InsecureTransport("peerB") at.AddTransport("/plaintext/1.0.0", &atInsecure) bt.AddTransport("/plaintext/1.1.0", &btInsecure) bt.AddTransport("/plaintext/1.0.0", &btInsecure) @@ -22,8 +22,8 @@ func TestCommonProto(t *testing.T) { func TestNoCommonProto(t *testing.T) { var at, bt SSMuxer - atInsecure := ss.InsecureTransport("peerA") - btInsecure := ss.InsecureTransport("peerB") + atInsecure := connsec.InsecureTransport("peerA") + btInsecure := connsec.InsecureTransport("peerB") at.AddTransport("/plaintext/1.0.0", &atInsecure) bt.AddTransport("/plaintext/1.1.0", &btInsecure) From e8586130fba9ca0c6a326cc74f5eb6d5ca2ea096 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 14 Mar 2018 15:54:59 -0700 Subject: [PATCH 05/14] go fmt --- p2p/net/conn-security-multistream/ssms.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index 75bbb10f44..312b775cd3 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -5,8 +5,8 @@ import ( "fmt" "net" - peer "github.com/libp2p/go-libp2p-peer" connsec "github.com/libp2p/go-conn-security" + peer "github.com/libp2p/go-libp2p-peer" mss "github.com/multiformats/go-multistream" ) From 5a60c83e50de398cab169951149e07fec3791c52 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 14 Mar 2018 15:55:05 -0700 Subject: [PATCH 06/14] fix tests for go-conn-security refactor --- .../conn-security-multistream/ssms_test.go | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index 5d72458562..457c1ce644 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -6,27 +6,27 @@ import ( "sync" "testing" - connsec "github.com/libp2p/go-conn-security" + insecure "github.com/libp2p/go-conn-security/insecure" sst "github.com/libp2p/go-conn-security/test" ) func TestCommonProto(t *testing.T) { var at, bt SSMuxer - atInsecure := connsec.InsecureTransport("peerA") - btInsecure := connsec.InsecureTransport("peerB") - at.AddTransport("/plaintext/1.0.0", &atInsecure) - bt.AddTransport("/plaintext/1.1.0", &btInsecure) - bt.AddTransport("/plaintext/1.0.0", &btInsecure) + atInsecure := insecure.New("peerA") + btInsecure := insecure.New("peerB") + at.AddTransport("/plaintext/1.0.0", atInsecure) + bt.AddTransport("/plaintext/1.1.0", btInsecure) + bt.AddTransport("/plaintext/1.0.0", btInsecure) sst.SubtestRW(t, &at, &bt, "peerA", "peerB") } func TestNoCommonProto(t *testing.T) { var at, bt SSMuxer - atInsecure := connsec.InsecureTransport("peerA") - btInsecure := connsec.InsecureTransport("peerB") + atInsecure := insecure.New("peerA") + btInsecure := insecure.New("peerB") - at.AddTransport("/plaintext/1.0.0", &atInsecure) - bt.AddTransport("/plaintext/1.1.0", &btInsecure) + at.AddTransport("/plaintext/1.0.0", atInsecure) + bt.AddTransport("/plaintext/1.1.0", btInsecure) ctx, cancel := context.WithCancel(context.Background()) defer cancel() From 085f98ae8fd9f2b0c38c9cf5f87d584895fa3425 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 25 Apr 2019 19:25:53 -0700 Subject: [PATCH 07/14] block while writing Make sure to wait until we're done writing before returning. The close should interrupt this process but we should still wait. might be related to https://github.com/ipfs/go-ipfs/issues/6197 --- p2p/net/conn-security-multistream/ssms.go | 1 + 1 file changed, 1 insertion(+) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index 312b775cd3..b74b749938 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -82,6 +82,7 @@ func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bo // We *must* do this. We have outstanding work on the connection // and it's no longer safe to use. insecure.Close() + <-done // wait to stop using the connection. return nil, ctx.Err() } } From c86093dbed349fe347566c6ee64eefe49ccf5abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Sat, 25 May 2019 13:01:32 +0100 Subject: [PATCH 08/14] migrate to consolidated types (#12) --- p2p/net/conn-security-multistream/ssms.go | 18 +++++++++--------- p2p/net/conn-security-multistream/ssms_test.go | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index b74b749938..219ee6fcff 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -5,8 +5,8 @@ import ( "fmt" "net" - connsec "github.com/libp2p/go-conn-security" - peer "github.com/libp2p/go-libp2p-peer" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" mss "github.com/multiformats/go-multistream" ) @@ -16,19 +16,19 @@ import ( // after use. type SSMuxer struct { mux mss.MultistreamMuxer - tpts map[string]connsec.Transport + tpts map[string]sec.SecureTransport OrderPreference []string } -var _ connsec.Transport = (*SSMuxer)(nil) +var _ sec.SecureTransport = (*SSMuxer)(nil) // AddTransport adds a stream security transport to this multistream muxer. // // This method is *not* thread-safe. It should be called only when initializing // the SSMuxer. -func (sm *SSMuxer) AddTransport(path string, transport connsec.Transport) { +func (sm *SSMuxer) AddTransport(path string, transport sec.SecureTransport) { if sm.tpts == nil { - sm.tpts = make(map[string]connsec.Transport, 1) + sm.tpts = make(map[string]sec.SecureTransport, 1) } sm.mux.AddHandler(path, nil) @@ -38,7 +38,7 @@ func (sm *SSMuxer) AddTransport(path string, transport connsec.Transport) { // SecureInbound secures an inbound connection using this multistream // multiplexed stream security transport. -func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (connsec.Conn, error) { +func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { tpt, err := sm.selectProto(ctx, insecure, true) if err != nil { return nil, err @@ -48,7 +48,7 @@ func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (connse // SecureOutbound secures an outbound connection using this multistream // multiplexed stream security transport. -func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (connsec.Conn, error) { +func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { tpt, err := sm.selectProto(ctx, insecure, false) if err != nil { return nil, err @@ -56,7 +56,7 @@ func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer return tpt.SecureOutbound(ctx, insecure, p) } -func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (connsec.Transport, error) { +func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (sec.SecureTransport, error) { var proto string var err error done := make(chan struct{}) diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index 457c1ce644..c10830f0f5 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -6,8 +6,8 @@ import ( "sync" "testing" - insecure "github.com/libp2p/go-conn-security/insecure" - sst "github.com/libp2p/go-conn-security/test" + "github.com/libp2p/go-libp2p-core/sec/insecure" + sst "github.com/libp2p/go-libp2p-testing/suites/sec" ) func TestCommonProto(t *testing.T) { From 3dade04a277560949ec1bb49a3181187240891cc Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 6 Dec 2019 20:24:16 -0500 Subject: [PATCH 09/14] chore(dep): update --- .../conn-security-multistream/ssms_test.go | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index c10830f0f5..43bf7be738 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -7,23 +7,31 @@ import ( "testing" "github.com/libp2p/go-libp2p-core/sec/insecure" + tnet "github.com/libp2p/go-libp2p-testing/net" sst "github.com/libp2p/go-libp2p-testing/suites/sec" ) func TestCommonProto(t *testing.T) { + idA := tnet.RandIdentityOrFatal(t) + idB := tnet.RandIdentityOrFatal(t) + var at, bt SSMuxer - atInsecure := insecure.New("peerA") - btInsecure := insecure.New("peerB") + + atInsecure := insecure.NewWithIdentity(idA.ID(), idA.PrivateKey()) + btInsecure := insecure.NewWithIdentity(idB.ID(), idB.PrivateKey()) at.AddTransport("/plaintext/1.0.0", atInsecure) bt.AddTransport("/plaintext/1.1.0", btInsecure) bt.AddTransport("/plaintext/1.0.0", btInsecure) - sst.SubtestRW(t, &at, &bt, "peerA", "peerB") + sst.SubtestRW(t, &at, &bt, idA.ID(), idB.ID()) } func TestNoCommonProto(t *testing.T) { + idA := tnet.RandIdentityOrFatal(t) + idB := tnet.RandIdentityOrFatal(t) + var at, bt SSMuxer - atInsecure := insecure.New("peerA") - btInsecure := insecure.New("peerB") + atInsecure := insecure.NewWithIdentity(idA.ID(), idA.PrivateKey()) + btInsecure := insecure.NewWithIdentity(idB.ID(), idB.PrivateKey()) at.AddTransport("/plaintext/1.0.0", atInsecure) bt.AddTransport("/plaintext/1.1.0", btInsecure) @@ -46,7 +54,7 @@ func TestNoCommonProto(t *testing.T) { go func() { defer wg.Done() defer b.Close() - _, err := bt.SecureOutbound(ctx, b, "peerA") + _, err := bt.SecureOutbound(ctx, b, idA.ID()) if err == nil { t.Fatal("connection should have failed") } From bd0110c946f8f356596cd38d0d02e6250627cb36 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 17 Feb 2021 09:16:44 +0200 Subject: [PATCH 10/14] Implement support for simultaneous open (#14) * implement simultaneous open Co-authored-by: aarshkshah1992 --- p2p/net/conn-security-multistream/ssms.go | 49 +++++++++++++------ .../conn-security-multistream/ssms_test.go | 22 +++++++-- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index 219ee6fcff..ad1e84f1ee 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -20,7 +20,7 @@ type SSMuxer struct { OrderPreference []string } -var _ sec.SecureTransport = (*SSMuxer)(nil) +var _ sec.SecureMuxer = (*SSMuxer)(nil) // AddTransport adds a stream security transport to this multistream muxer. // @@ -38,51 +38,70 @@ func (sm *SSMuxer) AddTransport(path string, transport sec.SecureTransport) { // SecureInbound secures an inbound connection using this multistream // multiplexed stream security transport. -func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { - tpt, err := sm.selectProto(ctx, insecure, true) +func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, bool, error) { + tpt, _, err := sm.selectProto(ctx, insecure, true) if err != nil { - return nil, err + return nil, false, err } - return tpt.SecureInbound(ctx, insecure) + sconn, err := tpt.SecureInbound(ctx, insecure) + return sconn, true, err } // SecureOutbound secures an outbound connection using this multistream // multiplexed stream security transport. -func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { - tpt, err := sm.selectProto(ctx, insecure, false) +func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, bool, error) { + tpt, server, err := sm.selectProto(ctx, insecure, false) if err != nil { - return nil, err + return nil, false, err } - return tpt.SecureOutbound(ctx, insecure, p) + + var sconn sec.SecureConn + if server { + sconn, err = tpt.SecureInbound(ctx, insecure) + if err != nil { + return nil, false, fmt.Errorf("failed to secure inbound connection: %s", err) + } + // ensure the correct peer connected to us + if sconn.RemotePeer() != p { + sconn.Close() + return nil, false, fmt.Errorf("Unexpected peer") + } + } else { + sconn, err = tpt.SecureOutbound(ctx, insecure, p) + } + + return sconn, server, err } -func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (sec.SecureTransport, error) { +func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (sec.SecureTransport, bool, error) { var proto string var err error + var iamserver bool done := make(chan struct{}) go func() { defer close(done) if server { + iamserver = true proto, _, err = sm.mux.Negotiate(insecure) } else { - proto, err = mss.SelectOneOf(sm.OrderPreference, insecure) + proto, iamserver, err = mss.SelectWithSimopenOrFail(sm.OrderPreference, insecure) } }() select { case <-done: if err != nil { - return nil, err + return nil, false, err } if tpt, ok := sm.tpts[proto]; ok { - return tpt, nil + return tpt, iamserver, nil } - return nil, fmt.Errorf("selected unknown security transport") + return nil, false, fmt.Errorf("selected unknown security transport") case <-ctx.Done(): // We *must* do this. We have outstanding work on the connection // and it's no longer safe to use. insecure.Close() <-done // wait to stop using the connection. - return nil, ctx.Err() + return nil, false, ctx.Err() } } diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index 43bf7be738..7b8b8f3a25 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -6,11 +6,27 @@ import ( "sync" "testing" + "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p-core/sec" "github.com/libp2p/go-libp2p-core/sec/insecure" tnet "github.com/libp2p/go-libp2p-testing/net" sst "github.com/libp2p/go-libp2p-testing/suites/sec" ) +type TransportAdapter struct { + mux *SSMuxer +} + +func (sm *TransportAdapter) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { + sconn, _, err := sm.mux.SecureInbound(ctx, insecure) + return sconn, err +} + +func (sm *TransportAdapter) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + sconn, _, err := sm.mux.SecureOutbound(ctx, insecure, p) + return sconn, err +} + func TestCommonProto(t *testing.T) { idA := tnet.RandIdentityOrFatal(t) idB := tnet.RandIdentityOrFatal(t) @@ -22,7 +38,7 @@ func TestCommonProto(t *testing.T) { at.AddTransport("/plaintext/1.0.0", atInsecure) bt.AddTransport("/plaintext/1.1.0", btInsecure) bt.AddTransport("/plaintext/1.0.0", btInsecure) - sst.SubtestRW(t, &at, &bt, idA.ID(), idB.ID()) + sst.SubtestRW(t, &TransportAdapter{mux: &at}, &TransportAdapter{mux: &bt}, idA.ID(), idB.ID()) } func TestNoCommonProto(t *testing.T) { @@ -45,7 +61,7 @@ func TestNoCommonProto(t *testing.T) { go func() { defer wg.Done() defer a.Close() - _, err := at.SecureInbound(ctx, a) + _, _, err := at.SecureInbound(ctx, a) if err == nil { t.Fatal("conection should have failed") } @@ -54,7 +70,7 @@ func TestNoCommonProto(t *testing.T) { go func() { defer wg.Done() defer b.Close() - _, err := bt.SecureOutbound(ctx, b, idA.ID()) + _, _, err := bt.SecureOutbound(ctx, b, "peerA") if err == nil { t.Fatal("connection should have failed") } From f70302adffaba42dec5a807596adc3fec822118a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 1 Jul 2021 18:40:10 -0700 Subject: [PATCH 11/14] fix go vet --- p2p/net/conn-security-multistream/ssms_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index 7b8b8f3a25..45470da210 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -63,7 +63,7 @@ func TestNoCommonProto(t *testing.T) { defer a.Close() _, _, err := at.SecureInbound(ctx, a) if err == nil { - t.Fatal("conection should have failed") + t.Error("conection should have failed") } }() @@ -72,7 +72,7 @@ func TestNoCommonProto(t *testing.T) { defer b.Close() _, _, err := bt.SecureOutbound(ctx, b, "peerA") if err == nil { - t.Fatal("connection should have failed") + t.Error("connection should have failed") } }() wg.Wait() From 37795144c88bc4cf10dc392343a604afb6d13ca4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 1 Jul 2021 18:40:17 -0700 Subject: [PATCH 12/14] fix staticcheck --- p2p/net/conn-security-multistream/ssms.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index ad1e84f1ee..6e56ad21ec 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -64,7 +64,7 @@ func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer // ensure the correct peer connected to us if sconn.RemotePeer() != p { sconn.Close() - return nil, false, fmt.Errorf("Unexpected peer") + return nil, false, fmt.Errorf("unexpected peer") } } else { sconn, err = tpt.SecureOutbound(ctx, insecure, p) From b63c8ff0231d58c1c8add0af2bf96cd4ae5d2534 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 8 Sep 2021 17:15:37 +0100 Subject: [PATCH 13/14] use the new SecureTransport and SecureMuxer interfaces (#36) * use the new SecureTransport and SecureMuxer interfaces * restore sanity check for the remote peer's ID, add log statement --- p2p/net/conn-security-multistream/ssms.go | 8 +++++--- p2p/net/conn-security-multistream/ssms_test.go | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index 6e56ad21ec..46bb334a88 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -3,6 +3,7 @@ package csms import ( "context" "fmt" + "log" "net" "github.com/libp2p/go-libp2p-core/peer" @@ -38,12 +39,12 @@ func (sm *SSMuxer) AddTransport(path string, transport sec.SecureTransport) { // SecureInbound secures an inbound connection using this multistream // multiplexed stream security transport. -func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, bool, error) { +func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, bool, error) { tpt, _, err := sm.selectProto(ctx, insecure, true) if err != nil { return nil, false, err } - sconn, err := tpt.SecureInbound(ctx, insecure) + sconn, err := tpt.SecureInbound(ctx, insecure, p) return sconn, true, err } @@ -57,13 +58,14 @@ func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer var sconn sec.SecureConn if server { - sconn, err = tpt.SecureInbound(ctx, insecure) + sconn, err = tpt.SecureInbound(ctx, insecure, p) if err != nil { return nil, false, fmt.Errorf("failed to secure inbound connection: %s", err) } // ensure the correct peer connected to us if sconn.RemotePeer() != p { sconn.Close() + log.Printf("Handshake failed to properly authenticate peer. Authenticated %s, expected %s.", sconn.RemotePeer(), p) return nil, false, fmt.Errorf("unexpected peer") } } else { diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index 45470da210..cee925a36a 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -17,8 +17,8 @@ type TransportAdapter struct { mux *SSMuxer } -func (sm *TransportAdapter) SecureInbound(ctx context.Context, insecure net.Conn) (sec.SecureConn, error) { - sconn, _, err := sm.mux.SecureInbound(ctx, insecure) +func (sm *TransportAdapter) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + sconn, _, err := sm.mux.SecureInbound(ctx, insecure, p) return sconn, err } @@ -61,9 +61,9 @@ func TestNoCommonProto(t *testing.T) { go func() { defer wg.Done() defer a.Close() - _, _, err := at.SecureInbound(ctx, a) + _, _, err := at.SecureInbound(ctx, a, "") if err == nil { - t.Error("conection should have failed") + t.Error("connection should have failed") } }() From de5875fd9caa165cd29f8a3af64f9f00046ba49f Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 26 Apr 2022 13:23:15 +0100 Subject: [PATCH 14/14] switch from github.com/libp2p/go-conn-security-multistream to p2p/net/conn-security-multistream --- config/security.go | 4 ++-- go.mod | 1 - p2p/net/swarm/dial_worker_test.go | 2 +- p2p/net/swarm/testing/testing.go | 2 +- p2p/transport/tcp/tcp_test.go | 2 +- p2p/transport/websocket/websocket_test.go | 3 ++- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config/security.go b/config/security.go index 0f6c78871a..bac3eb2185 100644 --- a/config/security.go +++ b/config/security.go @@ -3,13 +3,13 @@ package config import ( "fmt" + csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" + "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/sec" "github.com/libp2p/go-libp2p-core/sec/insecure" - - csms "github.com/libp2p/go-conn-security-multistream" ) // SecC is a security transport constructor. diff --git a/go.mod b/go.mod index fed40f9e17..a3539c7331 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,6 @@ require ( github.com/ipfs/go-log/v2 v2.5.1 github.com/klauspost/compress v1.15.1 github.com/libp2p/go-buffer-pool v0.0.2 - github.com/libp2p/go-conn-security-multistream v0.3.0 github.com/libp2p/go-eventbus v0.2.1 github.com/libp2p/go-libp2p-asn-util v0.1.0 github.com/libp2p/go-libp2p-circuit v0.6.0 diff --git a/p2p/net/swarm/dial_worker_test.go b/p2p/net/swarm/dial_worker_test.go index a7cc1e8d8f..0219a63a85 100644 --- a/p2p/net/swarm/dial_worker_test.go +++ b/p2p/net/swarm/dial_worker_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" + csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" quic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" @@ -16,7 +17,6 @@ import ( "github.com/libp2p/go-libp2p-core/sec/insecure" "github.com/libp2p/go-libp2p-core/transport" - csms "github.com/libp2p/go-conn-security-multistream" "github.com/libp2p/go-libp2p-peerstore/pstoremem" tnet "github.com/libp2p/go-libp2p-testing/net" tptu "github.com/libp2p/go-libp2p-transport-upgrader" diff --git a/p2p/net/swarm/testing/testing.go b/p2p/net/swarm/testing/testing.go index 0b75205e4e..6e56112f97 100644 --- a/p2p/net/swarm/testing/testing.go +++ b/p2p/net/swarm/testing/testing.go @@ -5,6 +5,7 @@ import ( "time" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" + csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" "github.com/libp2p/go-libp2p/p2p/net/swarm" quic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" @@ -19,7 +20,6 @@ import ( "github.com/libp2p/go-libp2p-core/sec/insecure" "github.com/libp2p/go-libp2p-core/transport" - csms "github.com/libp2p/go-conn-security-multistream" "github.com/libp2p/go-libp2p-peerstore/pstoremem" tnet "github.com/libp2p/go-libp2p-testing/net" tptu "github.com/libp2p/go-libp2p-transport-upgrader" diff --git a/p2p/transport/tcp/tcp_test.go b/p2p/transport/tcp/tcp_test.go index 8e48a99136..3976d76fdc 100644 --- a/p2p/transport/tcp/tcp_test.go +++ b/p2p/transport/tcp/tcp_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" + csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/network" @@ -14,7 +15,6 @@ import ( "github.com/libp2p/go-libp2p-core/sec/insecure" "github.com/libp2p/go-libp2p-core/transport" - csms "github.com/libp2p/go-conn-security-multistream" mocknetwork "github.com/libp2p/go-libp2p-testing/mocks/network" ttransport "github.com/libp2p/go-libp2p-testing/suites/transport" tptu "github.com/libp2p/go-libp2p-transport-upgrader" diff --git a/p2p/transport/websocket/websocket_test.go b/p2p/transport/websocket/websocket_test.go index 01ced160c3..db80277adb 100644 --- a/p2p/transport/websocket/websocket_test.go +++ b/p2p/transport/websocket/websocket_test.go @@ -15,6 +15,8 @@ import ( "testing" "time" + csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" + "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" @@ -24,7 +26,6 @@ import ( "github.com/libp2p/go-libp2p-core/transport" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" - csms "github.com/libp2p/go-conn-security-multistream" ttransport "github.com/libp2p/go-libp2p-testing/suites/transport" tptu "github.com/libp2p/go-libp2p-transport-upgrader"