From 9e5fef8c09a5ef962e9adda73f3d66519f121bcc Mon Sep 17 00:00:00 2001 From: roos Date: Fri, 4 Oct 2019 12:33:29 +0200 Subject: [PATCH] TrustStore: Implement recurser Adds: - Recurser that decides whether recursion is allowed for a given client. - ASLocalRecurser allows all clients in the local AS. - LocalOnlyRecurser allows only the local application. --- go/lib/infra/modules/trust/v2/BUILD.bazel | 3 + go/lib/infra/modules/trust/v2/recurser.go | 37 +++++++- .../infra/modules/trust/v2/recurser_test.go | 85 +++++++++++++++++++ 3 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 go/lib/infra/modules/trust/v2/recurser_test.go diff --git a/go/lib/infra/modules/trust/v2/BUILD.bazel b/go/lib/infra/modules/trust/v2/BUILD.bazel index 3f20b4eee1..a8b59c507a 100644 --- a/go/lib/infra/modules/trust/v2/BUILD.bazel +++ b/go/lib/infra/modules/trust/v2/BUILD.bazel @@ -23,6 +23,7 @@ go_library( "//go/lib/scrypto:go_default_library", "//go/lib/scrypto/trc/v2:go_default_library", "//go/lib/serrors:go_default_library", + "//go/lib/snet:go_default_library", "@org_golang_x_xerrors//:go_default_library", ], ) @@ -33,6 +34,7 @@ go_test( "export_test.go", "main_test.go", "provider_test.go", + "recurser_test.go", "resolver_test.go", ], data = [ @@ -48,6 +50,7 @@ go_test( "//go/lib/scrypto:go_default_library", "//go/lib/scrypto/trc/v2:go_default_library", "//go/lib/serrors:go_default_library", + "//go/lib/snet:go_default_library", "//go/lib/util:go_default_library", "//go/lib/xtest:go_default_library", "@com_github_golang_mock//gomock:go_default_library", diff --git a/go/lib/infra/modules/trust/v2/recurser.go b/go/lib/infra/modules/trust/v2/recurser.go index 8c736abd47..42919dfb77 100644 --- a/go/lib/infra/modules/trust/v2/recurser.go +++ b/go/lib/infra/modules/trust/v2/recurser.go @@ -16,8 +16,15 @@ package trust import ( "net" + + "github.com/scionproto/scion/go/lib/addr" + "github.com/scionproto/scion/go/lib/serrors" + "github.com/scionproto/scion/go/lib/snet" ) +// ErrRecursionNotAllowed indicates that recursion is not allowed. +var ErrRecursionNotAllowed = serrors.New("recursion not allowed") + // Recurser decides whether a recursive request is permitted for a given peer. // For infra services use either ASLocalRecurser or LocalOnlyRecurser. type Recurser interface { @@ -31,10 +38,32 @@ type Recurser interface { // ASLocalRecurser allows AS local addresses to start recursive requests. type ASLocalRecurser struct { - // TODO(roosd): implement + IA addr.IA } -// LocalOnlyRecurser only allows requests from the application to recurse. -type LocalOnlyRecurser struct { - // TODO(roosd): implement +// AllowRecursion returns an error if address is not part of the local AS (or if +// the check cannot be made). +func (r *ASLocalRecurser) AllowRecursion(peer net.Addr) error { + if peer != nil { + switch saddr, ok := peer.(*snet.Addr); { + case !ok: + return serrors.WrapStr("unable to determine AS of peer", ErrRecursionNotAllowed, + "addr", peer) + case !r.IA.Equal(saddr.IA): + return serrors.WrapStr("client outside local AS", ErrRecursionNotAllowed, + "addr", peer) + } + } + return nil +} + +// LocalOnlyRecurser returns an error if the address is not nil. +type LocalOnlyRecurser struct{} + +// AllowRecursion returns an error if the address is not nil. +func (r LocalOnlyRecurser) AllowRecursion(peer net.Addr) error { + if peer != nil { + return serrors.WrapStr("client not host-local", ErrRecursionNotAllowed, "addr", peer) + } + return nil } diff --git a/go/lib/infra/modules/trust/v2/recurser_test.go b/go/lib/infra/modules/trust/v2/recurser_test.go new file mode 100644 index 0000000000..60be28549e --- /dev/null +++ b/go/lib/infra/modules/trust/v2/recurser_test.go @@ -0,0 +1,85 @@ +// Copyright 2019 Anapaya Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package trust_test + +import ( + "net" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/scionproto/scion/go/lib/infra/modules/trust/v2" + "github.com/scionproto/scion/go/lib/snet" +) + +func TestASLocalRecurserAllowRecursion(t *testing.T) { + tests := map[string]struct { + Addr net.Addr + Assertion assert.ErrorAssertionFunc + }{ + "host local": { + Assertion: assert.NoError, + }, + "AS local": { + Addr: &snet.Addr{IA: ia110}, + Assertion: assert.NoError, + }, + "remote AS": { + Addr: &snet.Addr{IA: ia120}, + Assertion: assert.Error, + }, + "invalid Address": { + Addr: &net.IPAddr{IP: net.IP{127, 0, 0, 1}}, + Assertion: assert.Error, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + r := trust.ASLocalRecurser{IA: ia110} + err := r.AllowRecursion(test.Addr) + test.Assertion(t, err) + }) + } +} + +func TestLocalOnlyRecurserAllowRecursion(t *testing.T) { + tests := map[string]struct { + Addr net.Addr + Assertion assert.ErrorAssertionFunc + }{ + "host local": { + Assertion: assert.NoError, + }, + "AS local": { + Addr: &snet.Addr{IA: ia110}, + Assertion: assert.Error, + }, + "remote AS": { + Addr: &snet.Addr{IA: ia120}, + Assertion: assert.Error, + }, + "invalid Address": { + Addr: &net.IPAddr{IP: net.IP{127, 0, 0, 1}}, + Assertion: assert.Error, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + r := trust.LocalOnlyRecurser{} + err := r.AllowRecursion(test.Addr) + test.Assertion(t, err) + }) + } +}