Skip to content

Commit

Permalink
Merge pull request #1199 from libp2p/protect-nonsensical-expiration
Browse files Browse the repository at this point in the history
reject circuitv2 reservations with nonsensical expiration times
  • Loading branch information
marten-seemann authored Sep 24, 2021
2 parents 8a70f70 + 7ecefa8 commit 4650ccd
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 2 deletions.
8 changes: 6 additions & 2 deletions p2p/protocol/circuitv2/client/reservation.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,13 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation,

result := &Reservation{}
result.Expiration = time.Unix(int64(rsvp.GetExpire()), 0)
if result.Expiration.Before(time.Now()) {
return nil, fmt.Errorf("received reservation with expiration date in the past: %s", result.Expiration)
}

for _, ab := range rsvp.GetAddrs() {
addrs := rsvp.GetAddrs()
result.Addrs = make([]ma.Multiaddr, 0, len(addrs))
for _, ab := range addrs {
a, err := ma.NewMultiaddrBytes(ab)
if err != nil {
log.Warnf("ignoring unparsable relay address: %s", err)
Expand All @@ -108,7 +113,6 @@ func Reserve(ctx context.Context, h host.Host, ai peer.AddrInfo) (*Reservation,
if !ok {
return nil, fmt.Errorf("unexpected voucher record type: %+T", rec)
}

result.Voucher = voucher
}

Expand Down
105 changes: 105 additions & 0 deletions p2p/protocol/circuitv2/client/reservation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package client_test

import (
"context"
"math"
"testing"
"time"

"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util"

"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"

"github.com/stretchr/testify/require"
)

func TestReservationFailures(t *testing.T) {
type testcase struct {
name string
streamHandler network.StreamHandler
err string
}
testcases := []testcase{
{
name: "unsupported protocol",
streamHandler: nil,
err: "protocol not supported",
},
{
name: "wrong message type",
streamHandler: func(s network.Stream) {
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_RESERVE.Enum(),
})
},
err: "unexpected relay response: not a status message",
},
{
name: "unknown status",
streamHandler: func(s network.Stream) {
status := pbv2.Status(1337)
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_STATUS.Enum(),
Status: &status,
})
},
err: "reservation failed",
},
{
name: "invalid time",
streamHandler: func(s network.Stream) {
status := pbv2.Status_OK
expire := uint64(math.MaxUint64)
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_STATUS.Enum(),
Status: &status,
Reservation: &pbv2.Reservation{Expire: &expire},
})
},
err: "received reservation with expiration date in the past",
},
{
name: "invalid voucher",
streamHandler: func(s network.Stream) {
status := pbv2.Status_OK
expire := uint64(time.Now().Add(time.Hour).UnixNano())
util.NewDelimitedWriter(s).WriteMsg(&pbv2.HopMessage{
Type: pbv2.HopMessage_STATUS.Enum(),
Status: &status,
Reservation: &pbv2.Reservation{
Expire: &expire,
Voucher: []byte("foobar"),
},
})
},
err: "error consuming voucher envelope: failed when unmarshalling the envelope",
},
}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
host, err := libp2p.New()
require.NoError(t, err)
defer host.Close()
if tc.streamHandler != nil {
host.SetStreamHandler(proto.ProtoIDv2Hop, tc.streamHandler)
}

cl, err := libp2p.New()
require.NoError(t, err)
defer cl.Close()
_, err = client.Reserve(context.Background(), cl, peer.AddrInfo{ID: host.ID(), Addrs: host.Addrs()})
if tc.err == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.err)
}
})
}
}

0 comments on commit 4650ccd

Please sign in to comment.