| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package test |
| |
| import ( |
| "fmt" |
| "reflect" |
| "strings" |
| "sync" |
| "testing" |
| "time" |
| |
| "v.io/v23" |
| "v.io/v23/context" |
| "v.io/v23/security" |
| "v.io/v23/uniqueid" |
| "v.io/v23/vdl" |
| "v.io/v23/verror" |
| "v.io/x/ref/lib/security/bcrypter" |
| "v.io/x/ref/test/testutil" |
| ) |
| |
| var errMethod = verror.New(verror.ErrAborted, nil) |
| var fakeTimeCaveat = security.CaveatDescriptor{ |
| Id: uniqueid.Id{0x18, 0xba, 0x6f, 0x84, 0xd5, 0xec, 0xdb, 0x9b, 0xf2, 0x32, 0x19, 0x5b, 0x53, 0x92, 0x80, 0x0}, |
| ParamType: vdl.TypeOf(int64(0)), |
| } |
| |
| func init() { |
| security.RegisterCaveatValidator(fakeTimeCaveat, func(_ *context.T, _ security.Call, t int64) error { |
| if now := clock.Now(); now > t { |
| return fmt.Errorf("fakeTimeCaveat expired: now=%d > then=%d", now, t) |
| } |
| return nil |
| }) |
| } |
| |
| var clock = new(fakeClock) |
| |
| type fakeClock struct { |
| sync.Mutex |
| time int64 |
| } |
| |
| func (c *fakeClock) Now() int64 { |
| c.Lock() |
| defer c.Unlock() |
| return c.time |
| } |
| |
| func (c *fakeClock) Advance(steps uint) { |
| c.Lock() |
| c.time += int64(steps) |
| c.Unlock() |
| } |
| |
| // singleBlessingStore implements security.BlessingStore. It is a |
| // BlessingStore that marks the last blessing that was set on it as |
| // shareable with any peer. It does not care about the public key that |
| // blessing being set is bound to. |
| type singleBlessingStore struct { |
| pk security.PublicKey |
| b security.Blessings |
| def security.Blessings |
| } |
| |
| func (s *singleBlessingStore) Set(b security.Blessings, _ security.BlessingPattern) (security.Blessings, error) { |
| s.b = b |
| return security.Blessings{}, nil |
| } |
| func (s *singleBlessingStore) ForPeer(...string) security.Blessings { |
| return s.b |
| } |
| func (s *singleBlessingStore) SetDefault(b security.Blessings) error { |
| s.def = b |
| return nil |
| } |
| func (s *singleBlessingStore) Default() (security.Blessings, <-chan struct{}) { |
| return s.def, nil |
| } |
| func (s *singleBlessingStore) PublicKey() security.PublicKey { |
| return s.pk // This may be inconsistent with s.b & s.def, by design, for tests. |
| } |
| func (*singleBlessingStore) DebugString() string { |
| return "" |
| } |
| func (*singleBlessingStore) PeerBlessings() map[security.BlessingPattern]security.Blessings { |
| return nil |
| } |
| func (*singleBlessingStore) CacheDischarge(security.Discharge, security.Caveat, security.DischargeImpetus) { |
| return |
| } |
| func (*singleBlessingStore) ClearDischarges(...security.Discharge) { |
| return |
| } |
| func (*singleBlessingStore) Discharge(security.Caveat, security.DischargeImpetus) (security.Discharge, time.Time) { |
| return security.Discharge{}, time.Time{} |
| } |
| |
| func extractKey(t *testing.T, rootCtx *context.T, root *bcrypter.Root, blessing string) *bcrypter.PrivateKey { |
| key, err := root.Extract(rootCtx, blessing) |
| if err != nil { |
| t.Fatal(err) |
| } |
| return key |
| } |
| |
| func withPrincipal(t *testing.T, ctx *context.T, name string, caveats ...security.Caveat) *context.T { |
| idp := testutil.IDProviderFromPrincipal(v23.GetPrincipal(ctx)) |
| p := testutil.NewPrincipal() |
| if err := idp.Bless(p, name, caveats...); err != nil { |
| t.Fatal(err) |
| } |
| ctx, err := v23.WithPrincipal(ctx, p) |
| if err != nil { |
| t.Fatal(err) |
| } |
| return ctx |
| } |
| |
| func bless(t *testing.T, pctx, whoctx *context.T, extension string, cavs ...security.Caveat) security.Blessings { |
| idp := testutil.IDProviderFromPrincipal(v23.GetPrincipal(pctx)) |
| b, err := idp.NewBlessings(v23.GetPrincipal(whoctx), extension, cavs...) |
| if err != nil { |
| t.Fatal(err) |
| } |
| return b |
| } |
| |
| func mkCaveat(cav security.Caveat, err error) security.Caveat { |
| if err != nil { |
| panic(err) |
| } |
| return cav |
| } |
| |
| func mkThirdPartyCaveat(discharger security.PublicKey, location string, c security.Caveat) security.Caveat { |
| tpc, err := security.NewPublicKeyCaveat(discharger, location, security.ThirdPartyRequirements{}, c) |
| if err != nil { |
| panic(err) |
| } |
| return tpc |
| } |
| |
| func matchesErrorPattern(err error, id verror.IDAction, pattern string) bool { |
| if len(pattern) > 0 && err != nil && strings.Index(err.Error(), pattern) < 0 { |
| return false |
| } |
| if err == nil && id.ID == "" { |
| return true |
| } |
| return verror.ErrorID(err) == id.ID |
| } |
| |
| func waitForNames(t *testing.T, ctx *context.T, exist bool, names ...string) { |
| for _, n := range names { |
| for { |
| me, err := v23.GetNamespace(ctx).Resolve(ctx, n) |
| if err == nil && exist && len(me.Names()) > 0 { |
| break |
| } |
| if (err != nil && !exist) || (err == nil && len(me.Names()) == 0) { |
| break |
| } |
| ctx.Infof("Still waiting for %v, %v: %#v, %v", exist, n, me, err) |
| time.Sleep(10 * time.Millisecond) |
| } |
| } |
| } |
| |
| func makeResultPtrs(ins []interface{}) []interface{} { |
| outs := make([]interface{}, len(ins)) |
| for ix, in := range ins { |
| typ := reflect.TypeOf(in) |
| if typ == nil { |
| // Nil indicates interface{}. |
| var empty interface{} |
| typ = reflect.ValueOf(&empty).Elem().Type() |
| } |
| outs[ix] = reflect.New(typ).Interface() |
| } |
| return outs |
| } |
| |
| func checkResultPtrs(t *testing.T, name string, gotptrs, want []interface{}) { |
| for ix, res := range gotptrs { |
| got := reflect.ValueOf(res).Elem().Interface() |
| want := want[ix] |
| switch g := got.(type) { |
| case verror.E: |
| w, ok := want.(verror.E) |
| // don't use reflect deep equal on verror's since they contain |
| // a list of stack PCs which will be different. |
| if !ok { |
| t.Errorf("%s result %d got type %T, want %T", name, ix, g, w) |
| } |
| if verror.ErrorID(g) != w.ID { |
| t.Errorf("%s result %d got %v, want %v", name, ix, g, w) |
| } |
| default: |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("%s result %d got %v, want %v", name, ix, got, want) |
| } |
| } |
| } |
| } |