Merge "ipc/benchmark: change the directory structure."
diff --git a/lib/testutil/security/util.go b/lib/testutil/security/util.go
index 148e70e..3901177 100644
--- a/lib/testutil/security/util.go
+++ b/lib/testutil/security/util.go
@@ -71,9 +71,8 @@
// initialize a Runtime.
func NewCredentials(requiredName string, otherNames ...string) (string, security.Principal) {
dir, p := newCredentials()
- if def := selfBlessings(p, append([]string{requiredName}, otherNames...)...); def != nil {
- SetDefaultBlessings(p, def)
- }
+ def := selfBlessings(p, append([]string{requiredName}, otherNames...)...)
+ SetDefaultBlessings(p, def)
return dir, p
}
@@ -107,9 +106,7 @@
panic(err)
}
}
- if def != nil {
- SetDefaultBlessings(p, def)
- }
+ SetDefaultBlessings(p, def)
return dir, p
}
@@ -123,9 +120,8 @@
if err != nil {
panic(err)
}
- if def := selfBlessings(p, defaultBlessings...); def != nil {
- SetDefaultBlessings(p, def)
- }
+ def := selfBlessings(p, defaultBlessings...)
+ SetDefaultBlessings(p, def)
return p
}
@@ -203,11 +199,7 @@
if len(caveats) == 0 {
caveats = append(caveats, security.UnconstrainedUse())
}
- blessings, err := idp.p.Bless(p.PublicKey(), idp.b, extension, caveats[0], caveats[1:]...)
- if err != nil {
- return nil, err
- }
- return blessings, nil
+ return idp.p.Bless(p.PublicKey(), idp.b, extension, caveats[0], caveats[1:]...)
}
// PublicKey is the public key of the identity provider.
diff --git a/lib/testutil/security/util_test.go b/lib/testutil/security/util_test.go
index b8bd2d9..1cf1853 100644
--- a/lib/testutil/security/util_test.go
+++ b/lib/testutil/security/util_test.go
@@ -105,10 +105,10 @@
}
def := p.BlessingStore().Default()
peers := p.BlessingStore().ForPeer("anyone_else")
- if def == nil {
+ if def.IsZero() {
t.Errorf("BlessingStore should have a default blessing")
}
- if peers != def {
+ if !reflect.DeepEqual(peers, def) {
t.Errorf("ForPeer(...) returned %v, want %v", peers, def)
}
// TODO(ashankar): Implement a security.Context and test the string
diff --git a/lib/vdl/codegen/golang/gen.go b/lib/vdl/codegen/golang/gen.go
index 2650102..5e3c77a 100644
--- a/lib/vdl/codegen/golang/gen.go
+++ b/lib/vdl/codegen/golang/gen.go
@@ -97,6 +97,7 @@
var nativeTypePackageWhitelist = map[string]bool{
"time": true,
"v.io/core/veyron/lib/vdl/testdata/nativetest": true,
+ "v.io/v23/security": true,
}
func validateGoConfig(file *compile.File, env *compile.Env) {
diff --git a/profiles/fake/fake.go b/profiles/fake/fake.go
index 0837993..58ce2c8 100644
--- a/profiles/fake/fake.go
+++ b/profiles/fake/fake.go
@@ -3,8 +3,6 @@
import (
"v.io/v23"
"v.io/v23/context"
-
- "v.io/core/veyron/runtimes/fake"
)
func init() {
@@ -12,5 +10,5 @@
}
func Init(ctx *context.T) (v23.Runtime, *context.T, v23.Shutdown, error) {
- return fake.Init(ctx)
+ return new(ctx)
}
diff --git a/runtimes/fake/fake_test.go b/profiles/fake/fake_test.go
similarity index 100%
rename from runtimes/fake/fake_test.go
rename to profiles/fake/fake_test.go
diff --git a/runtimes/fake/ipc.go b/profiles/fake/ipc.go
similarity index 100%
rename from runtimes/fake/ipc.go
rename to profiles/fake/ipc.go
diff --git a/runtimes/fake/naming.go b/profiles/fake/naming.go
similarity index 100%
rename from runtimes/fake/naming.go
rename to profiles/fake/naming.go
diff --git a/runtimes/fake/runtime.go b/profiles/fake/runtime.go
similarity index 95%
rename from runtimes/fake/runtime.go
rename to profiles/fake/runtime.go
index 94ed44f..19640e5 100644
--- a/runtimes/fake/runtime.go
+++ b/profiles/fake/runtime.go
@@ -22,7 +22,7 @@
type Runtime struct{}
-func Init(ctx *context.T) (*Runtime, *context.T, v23.Shutdown, error) {
+func new(ctx *context.T) (*Runtime, *context.T, v23.Shutdown, error) {
ctx = context.WithValue(ctx, principalKey, tsecurity.NewPrincipal())
return &Runtime{}, ctx, func() {}, nil
}
diff --git a/runtimes/google/ipc/blessings_cache.go b/runtimes/google/ipc/blessings_cache.go
index ac71eee..204715a 100644
--- a/runtimes/google/ipc/blessings_cache.go
+++ b/runtimes/google/ipc/blessings_cache.go
@@ -133,10 +133,10 @@
}
func (c *serverBlessingsCache) getOrInsert(req ipc.BlessingsRequest, stats *ipcStats) (security.Blessings, error) {
- // In the case that the key sent is 0, we are running in VCSecurityNone and should
- // return nil for the client Blessings.
+ // In the case that the key sent is 0, we are running in VCSecurityNone
+ // and should return the zero value.
if req.Key == 0 {
- return nil, nil
+ return security.Blessings{}, nil
}
if req.Blessings == nil {
// Fastpath, lookup based on the key.
@@ -144,7 +144,7 @@
cached, exists := c.m[req.Key]
c.RUnlock()
if !exists {
- return nil, fmt.Errorf("ipc: key was not in the cache")
+ return security.Blessings{}, fmt.Errorf("ipc: key was not in the cache")
}
stats.recordBlessingCache(true)
return cached, nil
@@ -155,14 +155,14 @@
// the same as what's in the cache.
recv, err := security.NewBlessings(*req.Blessings)
if err != nil {
- return nil, fmt.Errorf("ipc: create new client blessings failed: %v", err)
+ return security.Blessings{}, fmt.Errorf("ipc: create new client blessings failed: %v", err)
}
c.Lock()
defer c.Unlock()
if cached, exists := c.m[req.Key]; exists {
// TODO(suharshs): Replace this reflect.DeepEqual() with a less expensive check.
if !reflect.DeepEqual(cached, recv) {
- return nil, fmt.Errorf("client sent invalid Blessings")
+ return security.Blessings{}, fmt.Errorf("client sent invalid Blessings")
}
return cached, nil
}
diff --git a/runtimes/google/ipc/client.go b/runtimes/google/ipc/client.go
index b107f56..6c0936d 100644
--- a/runtimes/google/ipc/client.go
+++ b/runtimes/google/ipc/client.go
@@ -647,8 +647,8 @@
// server that are authorized for this purpose and any blessings that are to be granted to
// the server (via ipc.Granter implementations in opts.)
func (c *client) authorizeServer(ctx *context.T, flow stream.Flow, name, method string, serverPatterns []string, opts []ipc.CallOpt) (serverBlessings []string, grantedBlessings security.Blessings, err error) {
- if flow.RemoteBlessings() == nil {
- return nil, nil, verror.New(errNoBlessings, ctx)
+ if flow.RemoteBlessings().IsZero() {
+ return nil, security.Blessings{}, verror.New(errNoBlessings, ctx)
}
ctxt := security.NewContext(&security.ContextParams{
LocalPrincipal: flow.LocalPrincipal(),
@@ -666,7 +666,7 @@
switch v := o.(type) {
case options.ServerPublicKey:
if remoteKey, key := flow.RemoteBlessings().PublicKey(), v.PublicKey; !reflect.DeepEqual(remoteKey, key) {
- return nil, nil, verror.New(errAuthServerKeyNotAllowed, ctx, remoteKey, key)
+ return nil, security.Blessings{}, verror.New(errAuthServerKeyNotAllowed, ctx, remoteKey, key)
}
case options.AllowedServersPolicy:
allowed := false
@@ -677,15 +677,15 @@
}
}
if !allowed {
- return nil, nil, verror.New(errAuthServerNotAllowed, ctx, v, serverBlessings)
+ return nil, security.Blessings{}, verror.New(errAuthServerNotAllowed, ctx, v, serverBlessings)
}
case options.SkipResolveAuthorization:
ignorePatterns = true
case ipc.Granter:
if b, err := v.Grant(flow.RemoteBlessings()); err != nil {
- return nil, nil, verror.New(errBlessingGrant, ctx, serverBlessings, err)
+ return nil, security.Blessings{}, verror.New(errBlessingGrant, ctx, serverBlessings, err)
} else if grantedBlessings, err = security.UnionOfBlessings(grantedBlessings, b); err != nil {
- return nil, nil, verror.New(errBlessingAdd, ctx, serverBlessings, err)
+ return nil, security.Blessings{}, verror.New(errBlessingAdd, ctx, serverBlessings, err)
}
}
}
@@ -698,11 +698,11 @@
}
}
if !matched {
- return nil, nil, verror.New(errAuthNoPatternMatch, ctx, serverBlessings, serverPatterns, rejectedBlessings)
+ return nil, security.Blessings{}, verror.New(errAuthNoPatternMatch, ctx, serverBlessings, serverPatterns, rejectedBlessings)
}
} else if enableSecureServerAuth && !ignorePatterns {
if err := (defaultAuthorizer{}).Authorize(ctxt); err != nil {
- return nil, nil, verror.New(errDefaultAuthDenied, ctx, serverBlessings)
+ return nil, security.Blessings{}, verror.New(errDefaultAuthDenied, ctx, serverBlessings)
}
}
return serverBlessings, grantedBlessings, nil
@@ -789,7 +789,7 @@
func (fc *flowClient) start(suffix, method string, args []interface{}, timeout time.Duration, blessings security.Blessings) error {
// Fetch any discharges for third-party caveats on the client's blessings
// if this client owns a discharge-client.
- if self := fc.flow.LocalBlessings(); self != nil && fc.dc != nil {
+ if self := fc.flow.LocalBlessings(); fc.dc != nil {
impetus, err := mkDischargeImpetus(fc.server, method, args)
if err != nil {
// TODO(toddw): Fix up the internal error.
diff --git a/runtimes/google/ipc/default_authorizer_test.go b/runtimes/google/ipc/default_authorizer_test.go
index 72351f9..fba7c85 100644
--- a/runtimes/google/ipc/default_authorizer_test.go
+++ b/runtimes/google/ipc/default_authorizer_test.go
@@ -25,12 +25,12 @@
// bless(ali, bob, "friend") will generate a blessing for ali, calling him "bob/friend".
bless = func(target, extend security.Blessings, extension string) security.Blessings {
var p security.Principal
- switch extend {
- case ali:
+ switch extend.PublicKey() {
+ case ali.PublicKey():
p = pali
- case bob:
+ case bob.PublicKey():
p = pbob
- case che:
+ case che.PublicKey():
p = pche
default:
panic(extend)
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 9bab076..5c5e3fb 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -539,8 +539,8 @@
t.Errorf(`%s: client.StartCall: got error "%v", want to match "%v"`, name, err, test.err)
} else if call != nil {
blessings, proof := call.RemoteBlessings()
- if proof == nil {
- t.Errorf("%s: Returned nil for remote blessings", name)
+ if proof.IsZero() {
+ t.Errorf("%s: Returned zero value for remote blessings", name)
}
// Currently all tests are configured so that the only
// blessings presented by the server that are
@@ -778,7 +778,7 @@
startErrID, finishErrID verror.IDAction
blessing, starterr, finisherr string
}{
- {blessing: "<nil>"},
+ {blessing: ""},
{granter: granter{b: bless(pclient, pserver, "blessed")}, blessing: "client/blessed"},
{granter: granter{err: errors.New("hell no")}, startErrID: verror.ErrNotTrusted, starterr: "hell no"},
{granter: granter{b: pclient.BlessingStore().Default()}, finishErrID: verror.ErrNoAccess, finisherr: "blessing granted not bound to this server"},
@@ -1086,7 +1086,7 @@
// own blessings to share.
pclient.AddToRoots(pserver.BlessingStore().Default())
// tsecurity.NewPrincipal sets up a principal that shares blessings with all servers, undo that.
- pclient.BlessingStore().Set(nil, security.AllPrincipals)
+ pclient.BlessingStore().Set(security.Blessings{}, security.AllPrincipals)
for _, test := range tests {
name := fmt.Sprintf("%q.%s(%v) by %v", test.name, test.method, test.args, test.blessings)
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 09b70b3..06c6404 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -210,11 +210,10 @@
s.listenerOpts = append(s.listenerOpts, dc)
s.listenerOpts = append(s.listenerOpts, vc.DialContext{ctx})
blessingsStatsName := naming.Join(statsPrefix, "security", "blessings")
- if blessings != nil {
- // TODO(caprita): revist printing the blessings with %s, and
- // instead expose them as a list.
- stats.NewString(blessingsStatsName).Set(fmt.Sprintf("%s", blessings))
- } else if principal != nil { // principal should have been passed in, but just in case.
+ // TODO(caprita): revist printing the blessings with %s, and
+ // instead expose them as a list.
+ stats.NewString(blessingsStatsName).Set(fmt.Sprintf("%s", blessings))
+ if principal != nil { // principal should have been passed in, but just in case.
stats.NewStringFunc(blessingsStatsName, func() string {
return fmt.Sprintf("%s (default)", principal.BlessingStore().Default())
})
@@ -1162,7 +1161,7 @@
// the server's identity as the blessing. Figure out what we want to do about
// this - should servers be able to assume that a blessing is something that
// does not have the authorizations that the server's own identity has?
- if blessings != nil && !reflect.DeepEqual(blessings.PublicKey(), fs.flow.LocalPrincipal().PublicKey()) {
+ if blessings.PublicKey() != nil && !reflect.DeepEqual(blessings.PublicKey(), fs.flow.LocalPrincipal().PublicKey()) {
return verror.New(verror.ErrNoAccess, fs.T, fmt.Sprintf("blessing granted not bound to this server(%v vs %v)", blessings.PublicKey(), fs.flow.LocalPrincipal().PublicKey()))
}
fs.clientBlessings, err = serverDecodeBlessings(fs.flow.VCDataCache(), req.Blessings, fs.server.stats)
@@ -1174,9 +1173,7 @@
fs.server.streamMgr.ShutdownEndpoint(fs.RemoteEndpoint())
return verror.New(verror.ErrBadProtocol, fs.T, newErrBadBlessingsCache(fs.T, err))
}
- if fs.clientBlessings != nil {
- fs.ackBlessings = true
- }
+ fs.ackBlessings = true
for _, d := range req.Discharges {
dis := security.NewDischarge(d)
@@ -1291,7 +1288,7 @@
}
func (fs *flowServer) RemoteBlessings() security.Blessings {
//nologcall
- if fs.clientBlessings != nil {
+ if !fs.clientBlessings.IsZero() {
return fs.clientBlessings
}
return fs.flow.RemoteBlessings()
diff --git a/runtimes/google/ipc/stream/vc/auth.go b/runtimes/google/ipc/stream/vc/auth.go
index e7c12f2..b8d8bfa 100644
--- a/runtimes/google/ipc/stream/vc/auth.go
+++ b/runtimes/google/ipc/stream/vc/auth.go
@@ -33,8 +33,8 @@
// returns the blessings used to authenticate the client.
func AuthenticateAsServer(conn io.ReadWriteCloser, principal security.Principal, server security.Blessings, dc DischargeClient, crypter crypto.Crypter, v version.IPCVersion) (client security.Blessings, clientDischarges map[string]security.Discharge, err error) {
defer conn.Close()
- if server == nil {
- return nil, nil, errors.New("no blessings to present as a server")
+ if server.IsZero() {
+ return security.Blessings{}, nil, errors.New("no blessings to present as a server")
}
var discharges []security.Discharge
if tpcavs := server.ThirdPartyCaveats(); len(tpcavs) > 0 && dc != nil {
@@ -76,8 +76,9 @@
Context: ctx,
}))
client = principal.BlessingStore().ForPeer(serverB...)
- if client == nil {
- return nil, nil, nil, NewErrNoBlessingsForPeer(ctx, serverB, invalidB)
+ if client.IsZero() {
+ err = NewErrNoBlessingsForPeer(ctx, serverB, invalidB)
+ return
}
var discharges []security.Discharge
if dc != nil {
@@ -132,21 +133,22 @@
func readBlessings(r io.Reader, tag []byte, crypter crypto.Crypter, v version.IPCVersion) (security.Blessings, map[string]security.Discharge, error) {
var msg []byte
+ var noBlessings security.Blessings
dec, err := vom.NewDecoder(r)
if err != nil {
- return nil, nil, fmt.Errorf("failed to create new decoder: %v", err)
+ return noBlessings, nil, fmt.Errorf("failed to create new decoder: %v", err)
}
if err := dec.Decode(&msg); err != nil {
- return nil, nil, fmt.Errorf("failed to read handshake message: %v", err)
+ return noBlessings, nil, fmt.Errorf("failed to read handshake message: %v", err)
}
buf, err := crypter.Decrypt(iobuf.NewSlice(msg))
if err != nil {
- return nil, nil, err
+ return noBlessings, nil, err
}
defer buf.Release()
dec, err = vom.NewDecoder(bytes.NewReader(buf.Contents))
if err != nil {
- return nil, nil, fmt.Errorf("failed to create new decoder: %v", err)
+ return noBlessings, nil, fmt.Errorf("failed to create new decoder: %v", err)
}
var (
@@ -154,16 +156,16 @@
sig security.Signature
)
if err = dec.Decode(&sig); err != nil {
- return nil, nil, err
+ return noBlessings, nil, err
}
if err = dec.Decode(&wireb); err != nil {
- return nil, nil, err
+ return noBlessings, nil, err
}
var discharges map[string]security.Discharge
if v >= version.IPCVersion7 {
var wired []security.WireDischarge
if err = dec.Decode(&wired); err != nil {
- return nil, nil, err
+ return noBlessings, nil, err
}
if len(wired) > 0 {
discharges = make(map[string]security.Discharge)
@@ -175,7 +177,7 @@
} else if v >= version.IPCVersion5 {
var list []security.Discharge
if err = dec.Decode(&list); err != nil {
- return nil, nil, err
+ return noBlessings, nil, err
}
if len(list) > 0 {
discharges = make(map[string]security.Discharge)
@@ -186,13 +188,10 @@
}
blessings, err := security.NewBlessings(wireb)
if err != nil {
- return nil, nil, err
- }
- if blessings == nil {
- return nil, nil, errNoCertificatesReceived
+ return noBlessings, nil, err
}
if !sig.Verify(blessings.PublicKey(), append(tag, crypter.ChannelBinding()...)) {
- return nil, nil, errInvalidSignatureInMessage
+ return noBlessings, nil, errInvalidSignatureInMessage
}
return blessings, discharges, nil
}
diff --git a/runtimes/google/ipc/stream/vc/init.go b/runtimes/google/ipc/stream/vc/init.go
index efa0cab..bf322fa 100644
--- a/runtimes/google/ipc/stream/vc/init.go
+++ b/runtimes/google/ipc/stream/vc/init.go
@@ -35,7 +35,7 @@
}
func (s *anonymousBlessingStore) Set(security.Blessings, security.BlessingPattern) (security.Blessings, error) {
- return nil, fmt.Errorf("cannot store blessings with an anonymous principal")
+ return security.Blessings{}, fmt.Errorf("cannot store blessings with an anonymous principal")
}
func (s *anonymousBlessingStore) ForPeer(...string) security.Blessings {
diff --git a/runtimes/google/ipc/stream/vc/listener_test.go b/runtimes/google/ipc/stream/vc/listener_test.go
index 6cabc70..1d81edd 100644
--- a/runtimes/google/ipc/stream/vc/listener_test.go
+++ b/runtimes/google/ipc/stream/vc/listener_test.go
@@ -22,8 +22,8 @@
// Other stream.Flow methods
func (*noopFlow) LocalPrincipal() security.Principal { return nil }
-func (*noopFlow) LocalBlessings() security.Blessings { return nil }
-func (*noopFlow) RemoteBlessings() security.Blessings { return nil }
+func (*noopFlow) LocalBlessings() security.Blessings { return security.Blessings{} }
+func (*noopFlow) RemoteBlessings() security.Blessings { return security.Blessings{} }
func (*noopFlow) RemoteDischarges() map[string]security.Discharge { return nil }
func (*noopFlow) SetDeadline(<-chan struct{}) {}
func (*noopFlow) VCDataCache() stream.VCDataCache { return nil }
diff --git a/runtimes/google/ipc/stream/vc/vc.go b/runtimes/google/ipc/stream/vc/vc.go
index 5c45530..5c36305 100644
--- a/runtimes/google/ipc/stream/vc/vc.go
+++ b/runtimes/google/ipc/stream/vc/vc.go
@@ -511,7 +511,7 @@
if principal == nil {
principal = AnonymousPrincipal
}
- if lBlessings == nil {
+ if lBlessings.IsZero() {
lBlessings = principal.BlessingStore().Default()
}
case options.VCSecurityNone:
diff --git a/runtimes/google/ipc/stream/vc/vc_test.go b/runtimes/google/ipc/stream/vc/vc_test.go
index ef35895..5baf9d5 100644
--- a/runtimes/google/ipc/stream/vc/vc_test.go
+++ b/runtimes/google/ipc/stream/vc/vc_test.go
@@ -87,10 +87,10 @@
if err != nil {
t.Fatal(err)
}
- if flow.RemoteBlessings() != nil {
+ if !flow.RemoteBlessings().IsZero() {
t.Errorf("Server sent blessing %v over insecure transport", flow.RemoteBlessings())
}
- if flow.LocalBlessings() != nil {
+ if !flow.LocalBlessings().IsZero() {
t.Errorf("Client sent blessing %v over insecure transport", flow.LocalBlessings())
}
}
@@ -131,7 +131,7 @@
if err != nil {
t.Fatal(err)
}
- client.BlessingStore().Set(nil, security.AllPrincipals)
+ client.BlessingStore().Set(security.Blessings{}, security.AllPrincipals)
client.BlessingStore().Set(forServer1, security.BlessingPattern("server1"))
client.BlessingStore().Set(forServer2, security.BlessingPattern("server2"))
@@ -526,3 +526,4 @@
func (e endpoint) RoutingID() naming.RoutingID { return naming.RoutingID(e) }
func (e endpoint) Addr() net.Addr { return nil }
func (e endpoint) ServesMountTable() bool { return false }
+func (e endpoint) BlessingNames() []string { return nil }
diff --git a/runtimes/google/ipc/stream/vif/auth.go b/runtimes/google/ipc/stream/vif/auth.go
index f02d085..c280ebd 100644
--- a/runtimes/google/ipc/stream/vif/auth.go
+++ b/runtimes/google/ipc/stream/vif/auth.go
@@ -208,7 +208,7 @@
if principal == nil {
principal = vc.AnonymousPrincipal
}
- if lBlessings == nil {
+ if lBlessings.IsZero() {
lBlessings = principal.BlessingStore().Default()
}
case options.VCSecurityNone:
diff --git a/runtimes/google/naming/endpoint.go b/runtimes/google/naming/endpoint.go
index daba3b1..1300684 100644
--- a/runtimes/google/naming/endpoint.go
+++ b/runtimes/google/naming/endpoint.go
@@ -4,6 +4,7 @@
"errors"
"fmt"
"net"
+ "regexp"
"strconv"
"strings"
@@ -12,11 +13,15 @@
)
const (
- separator = "@"
- suffix = "@@"
+ separator = "@"
+ suffix = "@@"
+ blessingsSeparator = ","
)
-var errInvalidEndpointString = errors.New("invalid endpoint string")
+var (
+ errInvalidEndpointString = errors.New("invalid endpoint string")
+ hostportEP = regexp.MustCompile("^(?:(.*)@)?([^@]+)$")
+)
// Network is the string returned by naming.Endpoint.Network implementations
// defined in this package.
@@ -29,6 +34,7 @@
RID naming.RoutingID
MinIPCVersion version.IPCVersion
MaxIPCVersion version.IPCVersion
+ Blessings []string
IsMountTable bool
}
@@ -39,15 +45,19 @@
// We have to guess this is a mount table if we don't know.
ep.IsMountTable = true
- // The prefix and suffix are optional.
- input = strings.TrimPrefix(strings.TrimSuffix(input, suffix), separator)
-
- parts := strings.Split(input, separator)
- if len(parts) == 1 {
- err := ep.parseHostPort(parts[0])
+ // If the endpoint does not end in a @, it must be in [blessing@]host:port format.
+ if parts := hostportEP.FindStringSubmatch(input); len(parts) > 0 {
+ hostport := parts[len(parts)-1]
+ var blessing string
+ if len(parts) > 2 {
+ blessing = parts[1]
+ }
+ err := ep.parseHostPort(blessing, hostport)
return ep, err
}
-
+ // Trim the prefix and suffix and parse the rest.
+ input = strings.TrimPrefix(strings.TrimSuffix(input, suffix), separator)
+ parts := strings.Split(input, separator)
version, err := strconv.ParseUint(parts[0], 10, 16)
if err != nil {
return nil, fmt.Errorf("invalid version: %v", err)
@@ -60,21 +70,25 @@
err = ep.parseV2(parts)
case 3:
err = ep.parseV3(parts)
+ case 4:
+ err = ep.parseV4(parts)
default:
err = errInvalidEndpointString
}
return ep, err
}
-func (ep *Endpoint) parseHostPort(input string) error {
+func (ep *Endpoint) parseHostPort(blessing, hostport string) error {
// Could be in host:port format.
- if _, _, err := net.SplitHostPort(input); err != nil {
+ if _, _, err := net.SplitHostPort(hostport); err != nil {
return errInvalidEndpointString
}
ep.Protocol = naming.UnknownProtocol
- ep.Address = input
+ ep.Address = hostport
ep.RID = naming.NullRoutingID
-
+ if len(blessing) > 0 {
+ ep.Blessings = []string{blessing}
+ }
return nil
}
@@ -166,6 +180,20 @@
return nil
}
+func (ep *Endpoint) parseV4(parts []string) error {
+ if len(parts) < 7 {
+ return errInvalidEndpointString
+ }
+ if err := ep.parseV3(parts[:7]); err != nil {
+ return err
+ }
+ // Join the remaining and re-split.
+ if str := strings.Join(parts[7:], separator); len(str) > 0 {
+ ep.Blessings = strings.Split(str, blessingsSeparator)
+ }
+ return nil
+}
+
func (ep *Endpoint) RoutingID() naming.RoutingID {
//nologcall
return ep.RID
@@ -175,7 +203,7 @@
return Network
}
-var defaultVersion = 3
+var defaultVersion = 3 // TODO(ashankar): Change to 4?
func (ep *Endpoint) VersionedString(version int) string {
switch version {
@@ -196,12 +224,27 @@
ep.Protocol, ep.Address, ep.RID,
printIPCVersion(ep.MinIPCVersion), printIPCVersion(ep.MaxIPCVersion),
mt)
+ case 4:
+ mt := "s"
+ blessings := strings.Join(ep.Blessings, blessingsSeparator)
+ if ep.IsMountTable {
+ mt = "m"
+ }
+ return fmt.Sprintf("@4@%s@%s@%s@%s@%s@%s@%s@@",
+ ep.Protocol, ep.Address, ep.RID,
+ printIPCVersion(ep.MinIPCVersion), printIPCVersion(ep.MaxIPCVersion),
+ mt, blessings)
}
}
func (ep *Endpoint) String() string {
//nologcall
- return ep.VersionedString(defaultVersion)
+ // Use version 4 if blessings are present, otherwise there is a loss of information.
+ v := defaultVersion
+ if len(ep.Blessings) > 0 && v < 4 {
+ v = 4
+ }
+ return ep.VersionedString(v)
}
func (ep *Endpoint) Name() string {
@@ -219,6 +262,11 @@
return ep.IsMountTable
}
+func (ep *Endpoint) BlessingNames() []string {
+ //nologcall
+ return ep.Blessings
+}
+
type addr struct {
network, address string
}
diff --git a/runtimes/google/naming/endpoint_test.go b/runtimes/google/naming/endpoint_test.go
index 303d3fe..de13f54 100644
--- a/runtimes/google/naming/endpoint_test.go
+++ b/runtimes/google/naming/endpoint_test.go
@@ -10,6 +10,10 @@
)
func TestEndpoint(t *testing.T) {
+ defver := defaultVersion
+ defer func() {
+ defaultVersion = defver
+ }()
v1 := &Endpoint{
Protocol: naming.UnknownProtocol,
Address: "batman.com:1234",
@@ -64,6 +68,25 @@
MaxIPCVersion: 3,
IsMountTable: false,
}
+ v4 := &Endpoint{
+ Protocol: "tcp",
+ Address: "batman.com:2345",
+ RID: naming.FixedRoutingID(0xba77),
+ MinIPCVersion: 4,
+ MaxIPCVersion: 5,
+ IsMountTable: true,
+ Blessings: []string{"dev.v.io/foo@bar.com", "dev.v.io/bar@bar.com/delegate"},
+ }
+ v4b := &Endpoint{
+ Protocol: "tcp",
+ Address: "batman.com:2345",
+ RID: naming.FixedRoutingID(0xba77),
+ MinIPCVersion: 4,
+ MaxIPCVersion: 5,
+ IsMountTable: true,
+ // Blessings that look similar to other parts of the endpoint.
+ Blessings: []string{"@@", "@s", "@m"},
+ }
testcasesA := []struct {
endpoint naming.Endpoint
@@ -80,42 +103,32 @@
}
}
- // Test v3 endpoints.
- defaultVersion = 3
+ // Test v3 & v4 endpoints.
testcasesC := []struct {
Endpoint naming.Endpoint
String string
- Input string
- min, max version.IPCVersion
- servesMT bool
+ Version int
}{
- {v3s, "@3@@batman.com:2345@00000000000000000000000000000000@2@3@s@@", "", 2, 3, false},
- {v3m, "@3@@batman.com:2345@000000000000000000000000dabbad00@2@3@m@@", "", 2, 3, true},
- {v3tcp, "@3@tcp@batman.com:2345@00000000000000000000000000000000@2@3@s@@", "", 2, 3, false},
- {v3ws6, "@3@ws6@batman.com:2345@00000000000000000000000000000000@2@3@s@@", "", 2, 3, false},
+ {v3s, "@3@@batman.com:2345@00000000000000000000000000000000@2@3@s@@", 3},
+ {v3m, "@3@@batman.com:2345@000000000000000000000000dabbad00@2@3@m@@", 3},
+ {v3tcp, "@3@tcp@batman.com:2345@00000000000000000000000000000000@2@3@s@@", 3},
+ {v3ws6, "@3@ws6@batman.com:2345@00000000000000000000000000000000@2@3@s@@", 3},
+ {v3s, "@4@@batman.com:2345@00000000000000000000000000000000@2@3@s@@@", 4},
+ {v4, "@4@tcp@batman.com:2345@0000000000000000000000000000ba77@4@5@m@dev.v.io/foo@bar.com,dev.v.io/bar@bar.com/delegate@@", 4},
+ {v4b, "@4@tcp@batman.com:2345@0000000000000000000000000000ba77@4@5@m@@@,@s,@m@@", 4},
}
for _, test := range testcasesC {
- if got, want := test.Endpoint.String(), test.String; got != want {
- t.Errorf("Got %q want %q for endpoint %T = %#v", got, want, test.Endpoint, test.Endpoint)
+ if got, want := test.Endpoint.VersionedString(test.Version), test.String; got != want {
+ t.Errorf("Got %q want %q for endpoint (v%d): %#v", got, want, test.Version, test.Endpoint)
}
- str := test.Input
- var ep naming.Endpoint
- var err error
- if str == "" {
- str = test.String
- ep, err = NewEndpoint(str)
- } else {
- ep, err = NewEndpoint(naming.FormatEndpoint("tcp", str,
- version.IPCVersionRange{test.min, test.max},
- naming.ServesMountTableOpt(test.servesMT)))
- }
+ ep, err := NewEndpoint(test.String)
if err != nil {
- t.Errorf("Endpoint(%q) failed with %v", str, err)
+ t.Errorf("Endpoint(%q) failed with %v", test.String, err)
continue
}
if !reflect.DeepEqual(ep, test.Endpoint) {
- t.Errorf("Got endpoint %T = %#v, want %T = %#v for string %q", ep, ep, test.Endpoint, test.Endpoint, str)
+ t.Errorf("Got endpoint %#v, want %#v for string %q", ep, test.Endpoint, test.String)
}
}
@@ -156,7 +169,6 @@
t.Errorf("Got endpoint %T = %#v, want %T = %#v for string %q", ep, ep, test.Endpoint, test.Endpoint, str)
}
}
- defaultVersion = 3
}
type endpointTest struct {
@@ -171,7 +183,6 @@
{"@1@@@@@", "@3@@:0@00000000000000000000000000000000@@@m@@", nil},
{"@2@@@@@@@", "@3@@:0@00000000000000000000000000000000@@@m@@", nil},
{"@1@tcp@batman:12@@@", "@3@tcp@batman:12@00000000000000000000000000000000@@@m@@", nil},
- {"@host:10@@", "@3@@host:10@00000000000000000000000000000000@@@m@@", nil},
{"@2@tcp@foo:12@@9@@@", "@3@tcp@foo:12@00000000000000000000000000000000@9@@m@@", nil},
{"@2@tcp@foo:12@@@4@@", "@3@tcp@foo:12@00000000000000000000000000000000@@4@m@@", nil},
{"@2@tcp@foo:12@@2@4@@", "@3@tcp@foo:12@00000000000000000000000000000000@2@4@m@@", nil},
@@ -202,10 +213,18 @@
}
func TestHostPortEndpoint(t *testing.T) {
+ defver := defaultVersion
+ defer func() {
+ defaultVersion = defver
+ }()
+ defaultVersion = 4
testcases := []endpointTest{
- {"localhost:10", "@3@@localhost:10@00000000000000000000000000000000@@@m@@", nil},
- {"localhost:", "@3@@localhost:@00000000000000000000000000000000@@@m@@", nil},
+ {"localhost:10", "@4@@localhost:10@00000000000000000000000000000000@@@m@@@", nil},
+ {"localhost:", "@4@@localhost:@00000000000000000000000000000000@@@m@@@", nil},
{"localhost", "", errInvalidEndpointString},
+ {"dev.v.io/service/mounttabled@ns.dev.v.io:8101", "@4@@ns.dev.v.io:8101@00000000000000000000000000000000@@@m@dev.v.io/service/mounttabled@@", nil},
+ {"dev.v.io/users/foo@bar.com@ns.dev.v.io:8101", "@4@@ns.dev.v.io:8101@00000000000000000000000000000000@@@m@dev.v.io/users/foo@bar.com@@", nil},
+ {"@1@tcp@ns.dev.v.io:8101", "@4@@ns.dev.v.io:8101@00000000000000000000000000000000@@@m@@1@tcp@@", nil},
}
runEndpointTests(t, testcases)
}
diff --git a/runtimes/google/naming/namespace/mount.go b/runtimes/google/naming/namespace/mount.go
index 844baed..4d3f993 100644
--- a/runtimes/google/naming/namespace/mount.go
+++ b/runtimes/google/naming/namespace/mount.go
@@ -65,7 +65,7 @@
// process.
p := v23.GetPrincipal(ctx)
b := p.BlessingStore().Default()
- if b == nil {
+ if b.IsZero() {
return fmt.Errorf("must provide a MountedServerBlessingsOpt")
}
for str, _ := range p.BlessingsInfo(b) {
diff --git a/runtimes/google/rt/ipc_test.go b/runtimes/google/rt/ipc_test.go
index ff80214..6b582f7 100644
--- a/runtimes/google/rt/ipc_test.go
+++ b/runtimes/google/rt/ipc_test.go
@@ -225,7 +225,7 @@
// Setup up the client's blessing store so that it can talk to the server.
rootClient := mkBlessings(root.NewBlessings(pclient, "client"))
- if _, err := pclient.BlessingStore().Set(nil, security.AllPrincipals); err != nil {
+ if _, err := pclient.BlessingStore().Set(security.Blessings{}, security.AllPrincipals); err != nil {
t.Fatal(err)
}
if _, err := pclient.BlessingStore().Set(rootClient, "root/server"); err != nil {
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index 3119e49..19db102 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -41,11 +41,11 @@
if p.BlessingStore() == nil {
t.Fatalf("The principal must have a BlessingStore")
}
- if p.BlessingStore().Default() == nil {
- t.Errorf("Principal().BlessingStore().Default() should not be nil")
+ if p.BlessingStore().Default().IsZero() {
+ t.Errorf("Principal().BlessingStore().Default() should not be the zero value")
}
- if p.BlessingStore().ForPeer() == nil {
- t.Errorf("Principal().BlessingStore().ForPeer() should not be nil")
+ if p.BlessingStore().ForPeer().IsZero() {
+ t.Errorf("Principal().BlessingStore().ForPeer() should not be the zero value")
}
}
@@ -92,14 +92,10 @@
if p == nil {
return fmt.Errorf("nil principal")
}
- blessings := p.BlessingStore().Default()
- if blessings == nil {
- return fmt.Errorf("rt.Principal().BlessingStore().Default() returned nil")
- }
ctx := security.NewContext(&security.ContextParams{LocalPrincipal: p})
- validBlessings, err := blessings.ForContext(ctx)
- if n := len(validBlessings); n != 1 {
- return fmt.Errorf("rt.Principal().BlessingStore().Default() returned Blessing %v with %d recognized blessings, want exactly one recognized blessing: %v", blessings, n, err)
+ blessings, rejected := p.BlessingStore().Default().ForContext(ctx)
+ if n := len(blessings); n != 1 {
+ return fmt.Errorf("rt.Principal().BlessingStore().Default() return blessings:%v (rejected:%v), want exactly one recognized blessing", blessings, rejected)
}
return nil
}
diff --git a/runtimes/google/testing/mocks/ipc/simple_client.go b/runtimes/google/testing/mocks/ipc/simple_client.go
index 0eeae54..40442d7 100644
--- a/runtimes/google/testing/mocks/ipc/simple_client.go
+++ b/runtimes/google/testing/mocks/ipc/simple_client.go
@@ -116,7 +116,7 @@
// RemoteBlessings implements ipc.Call
func (*mockCall) RemoteBlessings() ([]string, security.Blessings) {
- return []string{}, nil
+ return []string{}, security.Blessings{}
}
//mockStream implements ipc.Stream
diff --git a/security/agent/agent_test.go b/security/agent/agent_test.go
index dbb7226..821033b 100644
--- a/security/agent/agent_test.go
+++ b/security/agent/agent_test.go
@@ -183,8 +183,8 @@
func runDefaultBenchmark(b *testing.B, p security.Principal) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- if d := p.BlessingStore().Default(); d == nil {
- b.Fatal("nil")
+ if d := p.BlessingStore().Default(); d.IsZero() {
+ b.Fatal("empty blessings")
}
}
}
diff --git a/security/agent/cache/cache_test.go b/security/agent/cache/cache_test.go
index 2093f29..9025fb2 100644
--- a/security/agent/cache/cache_test.go
+++ b/security/agent/cache/cache_test.go
@@ -191,6 +191,7 @@
func TestSet(t *testing.T) {
p := tsecurity.NewPrincipal("bob")
store, cache := createStore(p)
+ var noBlessings security.Blessings
bob := store.Default()
alice, err := p.BlessSelf("alice")
@@ -199,35 +200,31 @@
}
john := tsecurity.NewPrincipal("john").BlessingStore().Default()
- store.Set(nil, "...")
- blessings, err := cache.Set(bob, "bob")
- if err != nil {
+ store.Set(noBlessings, "...")
+ if _, err := cache.Set(bob, "bob"); err != nil {
t.Errorf("Set() failed: %v", err)
}
- if blessings != nil {
- t.Errorf("Got unexpected previous blessings %v", blessings)
- }
if got := cache.ForPeer("bob/server"); !reflect.DeepEqual(bob, got) {
t.Errorf("ForPeer(bob/server) got: %v, want: %v", got, bob)
}
- blessings, err = cache.Set(nil, "bob")
+ blessings, err := cache.Set(noBlessings, "bob")
if err != nil {
t.Errorf("Set() failed: %v", err)
}
if !reflect.DeepEqual(bob, blessings) {
t.Errorf("Previous blessings %v, wanted %v", blessings, bob)
}
- if got := cache.ForPeer("bob/server"); !reflect.DeepEqual(nil, got) {
- t.Errorf("ForPeer(bob/server) got: %v, want: %v", got, nil)
+ if got, want := cache.ForPeer("bob/server"), (security.Blessings{}); !reflect.DeepEqual(want, got) {
+ t.Errorf("ForPeer(bob/server) got: %v, want: %v", got, want)
}
blessings, err = cache.Set(john, "john")
if err == nil {
t.Errorf("No error from set")
}
- if got := cache.ForPeer("john/server"); got != nil {
+ if got := cache.ForPeer("john/server"); got.PublicKey() != nil {
t.Errorf("ForPeer(john/server) got: %v, want: %v", got, nil)
}
@@ -235,16 +232,10 @@
if err != nil {
t.Errorf("Set() failed: %v", err)
}
- if blessings != nil {
- t.Errorf("Got unexpected previous blessings %v", blessings)
- }
blessings, err = cache.Set(alice, "bob")
if err != nil {
t.Errorf("Set() failed: %v", err)
}
- if blessings != nil {
- t.Errorf("Got unexpected previous blessings %v", blessings)
- }
expected, err := security.UnionOfBlessings(bob, alice)
if err != nil {
@@ -265,7 +256,7 @@
t.Fatalf("BlessSelf failed: %v", err)
}
- store.Set(nil, "...")
+ store.Set(security.Blessings{}, "...")
store.Set(bob, "bob")
if got := cache.ForPeer("bob/server"); !reflect.DeepEqual(bob, got) {
diff --git a/security/agent/client.go b/security/agent/client.go
index e32e886..6209b7f 100644
--- a/security/agent/client.go
+++ b/security/agent/client.go
@@ -108,20 +108,18 @@
var blessings security.WireBlessings
marshalledKey, err := key.MarshalBinary()
if err != nil {
- return nil, err
+ return security.Blessings{}, err
}
- err = c.caller.call("Bless", results(&blessings), marshalledKey, security.MarshalBlessings(with), extension, caveat, additionalCaveats)
- if err != nil {
- return nil, err
+ if err = c.caller.call("Bless", results(&blessings), marshalledKey, security.MarshalBlessings(with), extension, caveat, additionalCaveats); err != nil {
+ return security.Blessings{}, err
}
return security.NewBlessings(blessings)
}
func (c *client) BlessSelf(name string, caveats ...security.Caveat) (security.Blessings, error) {
var blessings security.WireBlessings
- err := c.caller.call("BlessSelf", results(&blessings), name, caveats)
- if err != nil {
- return nil, err
+ if err := c.caller.call("BlessSelf", results(&blessings), name, caveats); err != nil {
+ return security.Blessings{}, err
}
return security.NewBlessings(blessings)
}
@@ -189,9 +187,8 @@
func (b *blessingStore) Set(blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error) {
var resultBlessings security.WireBlessings
- err := b.caller.call("BlessingStoreSet", results(&resultBlessings), security.MarshalBlessings(blessings), forPeers)
- if err != nil {
- return nil, err
+ if err := b.caller.call("BlessingStoreSet", results(&resultBlessings), security.MarshalBlessings(blessings), forPeers); err != nil {
+ return security.Blessings{}, err
}
return security.NewBlessings(resultBlessings)
}
@@ -201,12 +198,12 @@
err := b.caller.call("BlessingStoreForPeer", results(&resultBlessings), peerBlessings)
if err != nil {
vlog.Errorf("error calling BlessingStoreForPeer: %v", err)
- return nil
+ return security.Blessings{}
}
blessings, err := security.NewBlessings(resultBlessings)
if err != nil {
vlog.Errorf("error creating Blessings from WireBlessings: %v", err)
- return nil
+ return security.Blessings{}
}
return blessings
}
@@ -220,12 +217,11 @@
err := b.caller.call("BlessingStoreDefault", results(&resultBlessings))
if err != nil {
vlog.Errorf("error calling BlessingStoreDefault: %v", err)
- return nil
+ return security.Blessings{}
}
blessings, err := security.NewBlessings(resultBlessings)
if err != nil {
vlog.Errorf("error creating Blessing from WireBlessings: %v", err)
- return nil
}
return blessings
}
diff --git a/security/agent/test_principal/main.go b/security/agent/test_principal/main.go
index c5126f3..f69c3d9 100644
--- a/security/agent/test_principal/main.go
+++ b/security/agent/test_principal/main.go
@@ -85,11 +85,11 @@
errorf("Roots().Recognized: %v", err)
}
// BlessingStore: Defaults
- if err := p.BlessingStore().SetDefault(nil); err != nil {
+ if err := p.BlessingStore().SetDefault(security.Blessings{}); err != nil {
errorf("BlessingStore().SetDefault: %v", err)
}
- if def := p.BlessingStore().Default(); def != nil {
- errorf("BlessingStore().Default returned %v, want nil", def)
+ if def := p.BlessingStore().Default(); !def.IsZero() {
+ errorf("BlessingStore().Default returned %v, want empty", def)
}
if err := p.BlessingStore().SetDefault(b); err != nil {
errorf("BlessingStore().SetDefault: %v", err)
@@ -99,13 +99,13 @@
}
// BlessingStore: Set & ForPeer
// First, clear out the self-generated default of the blessing store.
- if _, err := p.BlessingStore().Set(nil, security.AllPrincipals); err != nil {
+ if _, err := p.BlessingStore().Set(security.Blessings{}, security.AllPrincipals); err != nil {
errorf("BlessingStore().Set(nil, %q): %v", security.AllPrincipals, err)
}
- if forpeer := p.BlessingStore().ForPeer("superman/friend"); forpeer != nil {
+ if forpeer := p.BlessingStore().ForPeer("superman/friend"); !forpeer.IsZero() {
errorf("BlessingStore().ForPeer unexpectedly returned %v", forpeer)
}
- if old, err := p.BlessingStore().Set(b, "superman"); old != nil || err != nil {
+ if old, err := p.BlessingStore().Set(b, "superman"); err != nil {
errorf("BlessingStore().Set returned (%v, %v)", old, err)
}
if forpeer := p.BlessingStore().ForPeer("superman/friend"); !reflect.DeepEqual(forpeer, b) {
diff --git a/security/audit/principal.go b/security/audit/principal.go
index f1095b8..abc88f3 100644
--- a/security/audit/principal.go
+++ b/security/audit/principal.go
@@ -21,10 +21,12 @@
type args []interface{}
+var noBlessings security.Blessings
+
func (p *auditingPrincipal) Bless(key security.PublicKey, with security.Blessings, extension string, caveat security.Caveat, additionalCaveats ...security.Caveat) (security.Blessings, error) {
blessings, err := p.principal.Bless(key, with, extension, caveat, additionalCaveats...)
if err = p.audit(err, "Bless", addCaveats(args{key, with, extension, caveat}, additionalCaveats...), blessings); err != nil {
- return nil, err
+ return noBlessings, err
}
return blessings, nil
}
@@ -32,7 +34,7 @@
func (p *auditingPrincipal) BlessSelf(name string, caveats ...security.Caveat) (security.Blessings, error) {
blessings, err := p.principal.BlessSelf(name, caveats...)
if err = p.audit(err, "BlessSelf", addCaveats(args{name}, caveats...), blessings); err != nil {
- return nil, err
+ return noBlessings, err
}
return blessings, nil
}
diff --git a/security/blessingstore.go b/security/blessingstore.go
index a683dd8..cb9eed5 100644
--- a/security/blessingstore.go
+++ b/security/blessingstore.go
@@ -18,26 +18,30 @@
type blessings struct {
Value security.WireBlessings
- unmarshaled security.Blessings
+ unmarshaled *security.Blessings
}
func (w *blessings) Blessings() security.Blessings {
if w == nil {
- return nil
+ return security.Blessings{}
}
- return w.unmarshaled
+ return *w.unmarshaled
}
func (w *blessings) Verify() error {
- var err error
- if w.unmarshaled == nil {
- w.unmarshaled, err = security.NewBlessings(w.Value)
+ if w.unmarshaled != nil {
+ return nil
}
- return err
+ b, err := security.NewBlessings(w.Value)
+ if err != nil {
+ return err
+ }
+ w.unmarshaled = &b
+ return nil
}
func newWireBlessings(b security.Blessings) *blessings {
- return &blessings{Value: security.MarshalBlessings(b), unmarshaled: b}
+ return &blessings{Value: security.MarshalBlessings(b), unmarshaled: &b}
}
type state struct {
@@ -62,15 +66,15 @@
func (bs *blessingStore) Set(blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error) {
if !forPeers.IsValid() {
- return nil, fmt.Errorf("%q is an invalid BlessingPattern", forPeers)
+ return security.Blessings{}, fmt.Errorf("%q is an invalid BlessingPattern", forPeers)
}
- if blessings != nil && !reflect.DeepEqual(blessings.PublicKey(), bs.publicKey) {
- return nil, errStoreAddMismatch
+ if !blessings.IsZero() && !reflect.DeepEqual(blessings.PublicKey(), bs.publicKey) {
+ return security.Blessings{}, errStoreAddMismatch
}
bs.mu.Lock()
defer bs.mu.Unlock()
old, hadold := bs.state.Store[forPeers]
- if blessings != nil {
+ if !blessings.IsZero() {
bs.state.Store[forPeers] = newWireBlessings(blessings)
} else {
delete(bs.state.Store, forPeers)
@@ -81,7 +85,7 @@
} else {
delete(bs.state.Store, forPeers)
}
- return nil, err
+ return security.Blessings{}, err
}
return old.Blessings(), nil
}
@@ -116,7 +120,7 @@
func (bs *blessingStore) SetDefault(blessings security.Blessings) error {
bs.mu.Lock()
defer bs.mu.Unlock()
- if blessings != nil && !reflect.DeepEqual(blessings.PublicKey(), bs.publicKey) {
+ if !blessings.IsZero() && !reflect.DeepEqual(blessings.PublicKey(), bs.publicKey) {
return errStoreAddMismatch
}
oldDefault := bs.state.Default
@@ -218,7 +222,7 @@
if err := wb.Verify(); err != nil {
return err
}
- if b := wb.Blessings(); b != nil && !reflect.DeepEqual(b.PublicKey(), key) {
+ if b := wb.Blessings(); !reflect.DeepEqual(b.PublicKey(), key) {
return fmt.Errorf("read Blessings: %v that are not for provided PublicKey: %v", b, key)
}
return nil
diff --git a/security/blessingstore_test.go b/security/blessingstore_test.go
index f855419..a441bf0 100644
--- a/security/blessingstore_test.go
+++ b/security/blessingstore_test.go
@@ -50,12 +50,11 @@
if got := s.Default(); !reflect.DeepEqual(got, currentDefault) {
return fmt.Errorf("Default(): got: %v, want: %v", got, currentDefault)
}
- // SetDefault(nil)
- if err := s.SetDefault(nil); err != nil {
- return fmt.Errorf("SetDefault(nil): %v", err)
+ if err := s.SetDefault(security.Blessings{}); err != nil {
+ return fmt.Errorf("SetDefault({}): %v", err)
}
- if got := s.Default(); got != nil {
- return fmt.Errorf("Default returned %v, want nil", got)
+ if got := s.Default(); !got.IsZero() {
+ return fmt.Errorf("Default returned %v, wanted empty", got)
}
if err := s.SetDefault(t.def); err != nil {
return fmt.Errorf("SetDefault(%v): %v", t.def, err)
@@ -188,6 +187,7 @@
alice = blessSelf(p, "alice")
bob = blessSelf(p, "bob")
s = p.BlessingStore()
+ empty security.Blessings
)
// {alice, bob} is shared with "alice", whilst {bob} is shared with "alice/tv"
if _, err := s.Set(alice, "alice/$"); err != nil {
@@ -205,7 +205,7 @@
// Clear out the blessing associated with "alice".
// Now, bob should be shared with both alice and alice/friend.
- if _, err := s.Set(nil, "alice/$"); err != nil {
+ if _, err := s.Set(empty, "alice/$"); err != nil {
t.Fatal(err)
}
if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
@@ -216,7 +216,7 @@
}
// Clearing out an association that doesn't exist should have no effect.
- if _, err := s.Set(nil, "alice/enemy/$"); err != nil {
+ if _, err := s.Set(empty, "alice/enemy/$"); err != nil {
t.Fatal(err)
}
if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
@@ -227,14 +227,14 @@
}
// Clear everything
- if _, err := s.Set(nil, "alice"); err != nil {
+ if _, err := s.Set(empty, "alice"); err != nil {
t.Fatal(err)
}
- if got := s.ForPeer("alice"); got != nil {
- t.Errorf("Got %v, want nil", got)
+ if got := s.ForPeer("alice"); !got.IsZero() {
+ t.Errorf("Got %v, want empty", got)
}
- if got := s.ForPeer("alice/friend"); got != nil {
- t.Errorf("Got %v, want nil", got)
+ if got := s.ForPeer("alice/friend"); !got.IsZero() {
+ t.Errorf("Got %v, want empty", got)
}
}
@@ -247,10 +247,11 @@
alice = blessSelf(p, "alice")
bob = blessSelf(p, "bob")
s = p.BlessingStore()
+ empty security.Blessings
)
- if old, err := s.Set(alice, security.AllPrincipals); old != nil || err != nil {
- t.Errorf("Got (%v, %v)", old, err)
+ if old, err := s.Set(alice, security.AllPrincipals); !reflect.DeepEqual(old, empty) || err != nil {
+ t.Errorf("Got (%v, %v), want (%v, nil)", old, err)
}
if old, err := s.Set(alice, security.AllPrincipals); !reflect.DeepEqual(old, alice) || err != nil {
t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
@@ -258,7 +259,7 @@
if old, err := s.Set(bob, security.AllPrincipals); !reflect.DeepEqual(old, alice) || err != nil {
t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
}
- if old, err := s.Set(nil, security.AllPrincipals); !reflect.DeepEqual(old, bob) || err != nil {
+ if old, err := s.Set(empty, security.AllPrincipals); !reflect.DeepEqual(old, bob) || err != nil {
t.Errorf("Got (%v, %v) want (%v, nil)", old, err, bob)
}
}
diff --git a/security/testutil_test.go b/security/testutil_test.go
index 973d753..1b07c49 100644
--- a/security/testutil_test.go
+++ b/security/testutil_test.go
@@ -26,7 +26,7 @@
panic(err)
}
if len(selfblessings) == 0 {
- return p, nil
+ return p, security.Blessings{}
}
var def security.Blessings
for _, str := range selfblessings {
diff --git a/services/mgmt/device/impl/app_service.go b/services/mgmt/device/impl/app_service.go
index 909d27b..3bea982 100644
--- a/services/mgmt/device/impl/app_service.go
+++ b/services/mgmt/device/impl/app_service.go
@@ -471,10 +471,10 @@
if err := mkdir(pkgDir); err != nil {
return "", verror.New(ErrOperationFailed, nil)
}
- // We use a nil publisher, meaning that any signatures present in the
+ // We use a zero value publisher, meaning that any signatures present in the
// package files are not verified.
// TODO(caprita): Issue warnings when signatures are present and ignored.
- if err := downloadPackages(call.Context(), nil, packages, pkgDir); err != nil {
+ if err := downloadPackages(call.Context(), security.Blessings{}, packages, pkgDir); err != nil {
return "", err
}
if _, err := newVersion(call.Context(), installationDir, envelope, ""); err != nil {
@@ -592,7 +592,7 @@
// Take the blessings conferred upon us by the Start-er, extend them
// with the app title.
grantedBlessings := call.Blessings()
- if grantedBlessings == nil {
+ if grantedBlessings.IsZero() {
return verror.New(ErrInvalidBlessing, nil)
}
// TODO(caprita): Revisit UnconstrainedUse.
diff --git a/services/mgmt/device/impl/claim.go b/services/mgmt/device/impl/claim.go
index a2af1b0..8c57d12 100644
--- a/services/mgmt/device/impl/claim.go
+++ b/services/mgmt/device/impl/claim.go
@@ -38,7 +38,7 @@
principal = ctx.LocalPrincipal()
store = principal.BlessingStore()
)
- if granted == nil {
+ if granted.IsZero() {
return verror.New(ErrInvalidBlessing, ctx.Context())
}
c.mu.Lock()
diff --git a/services/mgmt/device/impl/util.go b/services/mgmt/device/impl/util.go
index ade3572..63ecb34 100644
--- a/services/mgmt/device/impl/util.go
+++ b/services/mgmt/device/impl/util.go
@@ -29,7 +29,7 @@
)
func verifySignature(data []byte, publisher security.Blessings, sig security.Signature) error {
- if publisher != nil {
+ if !publisher.IsZero() {
h := sha256.Sum256(data)
if !sig.Verify(publisher.PublicKey(), h[:]) {
return verror.New(ErrOperationFailed, nil)
diff --git a/services/mounttable/lib/mounttable.go b/services/mounttable/lib/mounttable.go
index 0c4a192..b8e5357 100644
--- a/services/mounttable/lib/mounttable.go
+++ b/services/mounttable/lib/mounttable.go
@@ -167,15 +167,11 @@
return nil
}
// "Self-RPCs" are always authorized.
- if l, r := ctx.LocalBlessings(), ctx.RemoteBlessings(); l != nil && r != nil && reflect.DeepEqual(l.PublicKey(), r.PublicKey()) {
+ if l, r := ctx.LocalBlessings().PublicKey(), ctx.RemoteBlessings().PublicKey(); l != nil && reflect.DeepEqual(l, r) {
return nil
}
// Match client's blessings against the ACLs.
- var blessings []string
- var invalidB []security.RejectedBlessing
- if ctx.RemoteBlessings() != nil {
- blessings, invalidB = ctx.RemoteBlessings().ForContext(ctx)
- }
+ blessings, invalidB := ctx.RemoteBlessings().ForContext(ctx)
for _, tag := range tags {
if acl, exists := n.acls.GetACLForTag(string(tag)); exists && acl.Includes(blessings...) {
return nil
@@ -208,11 +204,7 @@
return nil
}
// Match client's blessings against the ACLs.
- var blessings []string
- var invalidB []security.RejectedBlessing
- if ctx.RemoteBlessings() != nil {
- blessings, invalidB = ctx.RemoteBlessings().ForContext(ctx)
- }
+ blessings, invalidB := ctx.RemoteBlessings().ForContext(ctx)
for _, tag := range tags {
if acl, exists := n.amTemplate[string(tag)]; exists && expand(&acl, name).Includes(blessings...) {
return nil
@@ -231,10 +223,7 @@
return nil
}
acls := cur.acls.Copy()
- var blessings []string
- if ctx.RemoteBlessings() != nil {
- blessings, _ = ctx.RemoteBlessings().ForContext(ctx)
- }
+ blessings, _ := ctx.RemoteBlessings().ForContext(ctx)
for _, b := range blessings {
acls.Add(security.BlessingPattern(b), string(mounttable.Admin))
}
diff --git a/services/mounttable/lib/mounttable_test.go b/services/mounttable/lib/mounttable_test.go
index b61188f..bf0cb04 100644
--- a/services/mounttable/lib/mounttable_test.go
+++ b/services/mounttable/lib/mounttable_test.go
@@ -576,7 +576,6 @@
doMount(t, rootCtx, estr, "endpoint", naming.JoinAddressName(estr, "life/on/the/mississippi"), nil, true)
doMount(t, rootCtx, estr, "hostport", "/atrampabroad:8000", nil, true)
- doMount(t, rootCtx, estr, "hostport-endpoint-platypus", "/@atrampabroad:8000@@", nil, true)
doMount(t, rootCtx, estr, "invalid/not/rooted", "atrampabroad:8000", nil, false)
doMount(t, rootCtx, estr, "invalid/no/port", "/atrampabroad", nil, false)
doMount(t, rootCtx, estr, "invalid/endpoint", "/@following the equator:8000@@@", nil, false)
diff --git a/services/wsprd/app/app.go b/services/wsprd/app/app.go
index 3ddbf3c..26d1c07 100644
--- a/services/wsprd/app/app.go
+++ b/services/wsprd/app/app.go
@@ -13,6 +13,10 @@
"time"
vsecurity "v.io/core/veyron/security"
+ "v.io/core/veyron/services/wsprd/ipc/server"
+ "v.io/core/veyron/services/wsprd/lib"
+ "v.io/core/veyron/services/wsprd/namespace"
+ "v.io/core/veyron/services/wsprd/principal"
"v.io/v23"
"v.io/v23/context"
"v.io/v23/ipc"
@@ -25,10 +29,6 @@
"v.io/v23/vlog"
"v.io/v23/vom"
"v.io/v23/vtrace"
- "v.io/core/veyron/services/wsprd/ipc/server"
- "v.io/core/veyron/services/wsprd/lib"
- "v.io/core/veyron/services/wsprd/namespace"
- "v.io/core/veyron/services/wsprd/principal"
)
// pkgPath is the prefix os errors in this package.
@@ -383,7 +383,7 @@
return nil
}
func (l *localCall) Recv(interface{}) error { return nil }
-func (l *localCall) Blessings() security.Blessings { return nil }
+func (l *localCall) Blessings() security.Blessings { return security.Blessings{} }
func (l *localCall) Server() ipc.Server { return nil }
func (l *localCall) Context() *context.T { return l.ctx }
func (l *localCall) Timestamp() (t time.Time) { return }
@@ -393,8 +393,8 @@
func (l *localCall) Suffix() string { return "" }
func (l *localCall) RemoteDischarges() map[string]security.Discharge { return nil }
func (l *localCall) LocalPrincipal() security.Principal { return nil }
-func (l *localCall) LocalBlessings() security.Blessings { return nil }
-func (l *localCall) RemoteBlessings() security.Blessings { return nil }
+func (l *localCall) LocalBlessings() security.Blessings { return security.Blessings{} }
+func (l *localCall) RemoteBlessings() security.Blessings { return security.Blessings{} }
func (l *localCall) LocalEndpoint() naming.Endpoint { return nil }
func (l *localCall) RemoteEndpoint() naming.Endpoint { return nil }
func (l *localCall) VanadiumContext() *context.T { return l.ctx }
@@ -687,7 +687,7 @@
duration time.Duration,
extension string) (int32, string, error) {
var blessee security.Blessings
- if blessee = c.blessingsStore.Get(handle); blessee == nil {
+ if blessee = c.blessingsStore.Get(handle); blessee.IsZero() {
return 0, "", verror.New(invalidBlessingsHandle, nil)
}
diff --git a/services/wsprd/browspr/browspr_account_test.go b/services/wsprd/browspr/browspr_account_test.go
index 9eb94f7..e0d128c 100644
--- a/services/wsprd/browspr/browspr_account_test.go
+++ b/services/wsprd/browspr/browspr_account_test.go
@@ -79,7 +79,7 @@
}
// Verify that principalManager has the new account
- if b, err := browspr.principalManager.BlessingsForAccount(account1.RawString()); err != nil || b == nil {
+ if b, err := browspr.principalManager.BlessingsForAccount(account1.RawString()); err != nil || b.IsZero() {
t.Fatalf("Failed to get Blessings for account %v: got %v, %v", account1, b, err)
}
@@ -111,10 +111,10 @@
}
// Verify that principalManager has both accounts
- if b, err := browspr.principalManager.BlessingsForAccount(account1.RawString()); err != nil || b == nil {
+ if b, err := browspr.principalManager.BlessingsForAccount(account1.RawString()); err != nil || b.IsZero() {
t.Fatalf("Failed to get Blessings for account %v: got %v, %v", account1, b, err)
}
- if b, err := browspr.principalManager.BlessingsForAccount(account2.RawString()); err != nil || b == nil {
+ if b, err := browspr.principalManager.BlessingsForAccount(account2.RawString()); err != nil || b.IsZero() {
t.Fatalf("Failed to get Blessings for account %v: got %v, %v", account2, b, err)
}
}
diff --git a/services/wsprd/browspr/main/main_nacl.go b/services/wsprd/browspr/main/main_nacl.go
index 683a4f9..38a976e 100644
--- a/services/wsprd/browspr/main/main_nacl.go
+++ b/services/wsprd/browspr/main/main_nacl.go
@@ -11,12 +11,12 @@
"v.io/core/veyron/lib/websocket"
_ "v.io/core/veyron/profiles/chrome"
vsecurity "v.io/core/veyron/security"
+ "v.io/core/veyron/services/wsprd/browspr"
+ "v.io/core/veyron/services/wsprd/channel/channel_nacl"
"v.io/v23"
"v.io/v23/security"
"v.io/v23/vdl"
"v.io/v23/vlog"
- "v.io/core/veyron/services/wsprd/browspr"
- "v.io/core/veyron/services/wsprd/channel/channel_nacl"
)
func main() {
@@ -70,66 +70,99 @@
const browsprDir = "/browspr/data"
+func (inst *browsprInstance) loadKeyFromStorage(browsprKeyFile string) (*ecdsa.PrivateKey, error) {
+ vlog.VI(1).Infof("Attempting to read key from file %v", browsprKeyFile)
+
+ rFile, err := inst.fs.Open(browsprKeyFile)
+ if err != nil {
+ vlog.VI(1).Infof("Key not found in file %v", browsprKeyFile)
+ return nil, err
+ }
+
+ vlog.VI(1).Infof("Attempting to load cached browspr ecdsaPrivateKey in file %v", browsprKeyFile)
+ defer rFile.Release()
+ key, err := vsecurity.LoadPEMKey(rFile, nil)
+ if err != nil {
+ return nil, fmt.Errorf("failed to load browspr key:%s", err)
+ }
+ if ecdsaKey, ok := key.(*ecdsa.PrivateKey); !ok {
+ return nil, fmt.Errorf("got key of type %T, want *ecdsa.PrivateKey", key)
+ } else {
+ return ecdsaKey, nil
+ }
+}
+
// Loads a saved key if one exists, otherwise creates a new one and persists it.
func (inst *browsprInstance) initKey() (*ecdsa.PrivateKey, error) {
- var ecdsaKey *ecdsa.PrivateKey
browsprKeyFile := browsprDir + "/privateKey.pem."
- // See whether we have any cached keys for WSPR
- if rFile, err := inst.fs.Open(browsprKeyFile); err == nil {
- fmt.Print("Opening cached browspr ecdsaPrivateKey")
- defer rFile.Release()
- key, err := vsecurity.LoadPEMKey(rFile, nil)
- if err != nil {
- return nil, fmt.Errorf("failed to load browspr key:%s", err)
- }
- var ok bool
- if ecdsaKey, ok = key.(*ecdsa.PrivateKey); !ok {
- return nil, fmt.Errorf("got key of type %T, want *ecdsa.PrivateKey", key)
- }
+ if ecdsaKey, err := inst.loadKeyFromStorage(browsprKeyFile); err == nil {
+ return ecdsaKey, nil
} else {
- fmt.Print("Generating new browspr ecdsaPrivateKey")
- // Generate new keys and store them.
- var err error
- if _, ecdsaKey, err = vsecurity.NewPrincipalKey(); err != nil {
- return nil, fmt.Errorf("failed to generate security key:%s", err)
- }
- // Persist the keys in a local file.
- wFile, err := inst.fs.Create(browsprKeyFile)
- if err != nil {
- return nil, fmt.Errorf("failed to create file to persist browspr keys:%s", err)
- }
- defer wFile.Release()
- var b bytes.Buffer
- if err = vsecurity.SavePEMKey(&b, ecdsaKey, nil); err != nil {
- return nil, fmt.Errorf("failed to save browspr key:%s", err)
- }
- if n, err := wFile.Write(b.Bytes()); n != b.Len() || err != nil {
- return nil, fmt.Errorf("failed to write browspr key:%s", err)
- }
+ vlog.VI(1).Infof("inst.loadKeyFromStorage(%v) failed: %v", browsprKeyFile, err)
+ }
+
+ vlog.VI(1).Infof("Generating new browspr ecdsaPrivateKey")
+
+ // Generate new keys and store them.
+ var ecdsaKey *ecdsa.PrivateKey
+ var err error
+ if _, ecdsaKey, err = vsecurity.NewPrincipalKey(); err != nil {
+ return nil, fmt.Errorf("failed to generate security key:%s", err)
+ }
+ // Persist the keys in a local file.
+ wFile, err := inst.fs.Create(browsprKeyFile)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create file to persist browspr keys:%s", err)
+ }
+ defer wFile.Release()
+ var b bytes.Buffer
+ if err = vsecurity.SavePEMKey(&b, ecdsaKey, nil); err != nil {
+ return nil, fmt.Errorf("failed to save browspr key:%s", err)
+ }
+ if n, err := wFile.Write(b.Bytes()); n != b.Len() || err != nil {
+ return nil, fmt.Errorf("failed to write browspr key:%s", err)
}
return ecdsaKey, nil
}
+func (inst *browsprInstance) newPrincipal(ecdsaKey *ecdsa.PrivateKey, blessingRootsData, blessingRootsSig, blessingStoreData, blessingStoreSig string) (security.Principal, error) {
+ roots, err := browspr.NewFileSerializer(blessingRootsData, blessingRootsSig, inst.fs)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create blessing roots serializer:%s", err)
+ }
+ store, err := browspr.NewFileSerializer(blessingStoreData, blessingStoreSig, inst.fs)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create blessing store serializer:%s", err)
+ }
+ state := &vsecurity.PrincipalStateSerializer{
+ BlessingRoots: roots,
+ BlessingStore: store,
+ }
+ return vsecurity.NewPrincipalFromSigner(security.NewInMemoryECDSASigner(ecdsaKey), state)
+}
+
func (inst *browsprInstance) newPersistantPrincipal(peerNames []string) (security.Principal, error) {
ecdsaKey, err := inst.initKey()
if err != nil {
return nil, fmt.Errorf("failed to initialize ecdsa key:%s", err)
}
- roots, err := browspr.NewFileSerializer(browsprDir+"/blessingroots.data", browsprDir+"/blessingroots.sig", inst.fs)
- if err != nil {
- return nil, fmt.Errorf("failed to create blessing roots serializer:%s", err)
- }
- store, err := browspr.NewFileSerializer(browsprDir+"/blessingstore.data", browsprDir+"/blessingstore.sig", inst.fs)
- if err != nil {
- return nil, fmt.Errorf("failed to create blessing store serializer:%s", err)
- }
- state := &vsecurity.PrincipalStateSerializer{
- BlessingRoots: roots,
- BlessingStore: store,
- }
+ blessingRootsData := browsprDir + "/blessingroots.data"
+ blessingRootsSig := browsprDir + "/blessingroots.sig"
+ blessingStoreData := browsprDir + "/blessingstore.data"
+ blessingStoreSig := browsprDir + "/blessingstore.sig"
- return vsecurity.NewPrincipalFromSigner(security.NewInMemoryECDSASigner(ecdsaKey), state)
+ principal, err := inst.newPrincipal(ecdsaKey, blessingRootsData, blessingRootsSig, blessingStoreData, blessingStoreSig)
+ if err != nil {
+ vlog.VI(1).Infof("inst.newPrincipal(%v, %v, %v, %v, %v) failed: %v", ecdsaKey, blessingRootsData, blessingRootsSig, blessingStoreData, blessingStoreSig)
+
+ // Delete the files and try again.
+ for _, file := range []string{blessingRootsData, blessingRootsSig, blessingStoreData, blessingStoreSig} {
+ inst.fs.Remove(file)
+ }
+ principal, err = inst.newPrincipal(ecdsaKey, blessingRootsData, blessingRootsSig, blessingStoreData, blessingStoreSig)
+ }
+ return principal, err
}
// Base64-decode and unmarshal a public key.
diff --git a/services/wsprd/ipc/server/server.go b/services/wsprd/ipc/server/server.go
index a90527a..c3dc133 100644
--- a/services/wsprd/ipc/server/server.go
+++ b/services/wsprd/ipc/server/server.go
@@ -384,7 +384,7 @@
remoteEndpoint = ctx.RemoteEndpoint().String()
}
var localBlessings principal.BlessingsHandle
- if ctx.LocalBlessings() != nil {
+ if !ctx.LocalBlessings().IsZero() {
localBlessings = s.convertBlessingsToHandle(ctx.LocalBlessings())
}
anymtags := make([]*vdl.Value, len(ctx.MethodTags()))
diff --git a/services/wsprd/lib/signature_manager_test.go b/services/wsprd/lib/signature_manager_test.go
index 89a2a7f..2cf47c5 100644
--- a/services/wsprd/lib/signature_manager_test.go
+++ b/services/wsprd/lib/signature_manager_test.go
@@ -6,8 +6,7 @@
"testing"
"v.io/core/veyron/lib/testutil"
- _ "v.io/core/veyron/profiles/fake"
- "v.io/core/veyron/runtimes/fake"
+ "v.io/core/veyron/profiles/fake"
mocks_ipc "v.io/core/veyron/runtimes/google/testing/mocks/ipc"
"v.io/v23"
"v.io/v23/context"
diff --git a/services/wsprd/principal/js_blessings_store_test.go b/services/wsprd/principal/js_blessings_store_test.go
index 8fdee60..8daa97c 100644
--- a/services/wsprd/principal/js_blessings_store_test.go
+++ b/services/wsprd/principal/js_blessings_store_test.go
@@ -15,7 +15,7 @@
}
s.Remove(h)
- if got := s.Get(h); got != nil {
+ if got := s.Get(h); !got.IsZero() {
t.Fatalf("Get after removing: got: %v, want nil", got)
}
}
diff --git a/services/wsprd/principal/principal.go b/services/wsprd/principal/principal.go
index 23b5fdc..cf46168 100644
--- a/services/wsprd/principal/principal.go
+++ b/services/wsprd/principal/principal.go
@@ -244,7 +244,7 @@
wireBlessings, found := i.state.Accounts[account]
if !found {
- return nil, verror.New(errUnknownAccount, nil, account)
+ return security.Blessings{}, verror.New(errUnknownAccount, nil, account)
}
return security.NewBlessings(wireBlessings)
}
diff --git a/services/wsprd/principal/principal_test.go b/services/wsprd/principal/principal_test.go
index 147d150..9a26460 100644
--- a/services/wsprd/principal/principal_test.go
+++ b/services/wsprd/principal/principal_test.go
@@ -114,7 +114,7 @@
return fmt.Errorf("BlessingsForAccount(%v): got: %v, %v, want: %v, nil", t.facebookAccount, got, err, t.facebookBlessings)
}
nonExistingAccount := "nonExistingAccount"
- if got, err := m.BlessingsForAccount(nonExistingAccount); got != nil {
+ if got, err := m.BlessingsForAccount(nonExistingAccount); !got.IsZero() {
return fmt.Errorf("BlessingsForAccount(%v): got: %v, want nil", nonExistingAccount, got)
} else if merr := matchesError(err, "unknown account"); merr != nil {
return fmt.Errorf("BlessingsForAccount(%v) returned error: %v", nonExistingAccount, merr)
diff --git a/tools/mgmt/device/devicex b/tools/mgmt/device/devicex
index c855d9d..fe74d56 100755
--- a/tools/mgmt/device/devicex
+++ b/tools/mgmt/device/devicex
@@ -32,6 +32,64 @@
echo "0511."
}
+###############################################################################
+# Wrapper around chown that works differently on Mac and Linux
+# Arguments:
+# arguments to chown command
+# Returns:
+# None
+###############################################################################
+portable_chown() {
+ case "$(uname)" in
+ "Darwin")
+ sudo /usr/sbin/chown "$@"
+ ;;
+ "Linux")
+ sudo chown "$@"
+ ;;
+ esac
+}
+
+###############################################################################
+# Sets up the target to be owned by root with the suid bit on.
+# Arguments:
+# path to target
+# Returns:
+# None
+###############################################################################
+make_suid() {
+ local -r target="$1"
+ local root_group="root"
+ if [[ "$(uname)" == "Darwin" ]]; then
+ # Group root not available on Darwin.
+ root_group="wheel"
+ fi
+ portable_chown "root:${root_group}" "${target}"
+ sudo chmod 4551 "${target}"
+}
+
+###############################################################################
+# Runs a command as the device manager user. Assumes VANADIUM_DEVICE_DIR exists
+# and gets the device manager user from the owner of that directory.
+# Globals:
+# VANADIUM_DEVICE_DIR
+# Arguments:
+# command to run and its arguments
+# Returns:
+# None
+###############################################################################
+run() {
+ local -r devmgr_user=$(getdevowner)
+ if [[ "${devmgr_user}" == $(whoami) ]]; then
+ "$@"
+ else
+ sudo -u "${devmgr_user}" \
+ NAMESPACE_ROOT="${NAMESPACE_ROOT}" \
+ VANADIUM_DEVICE_DIR="${VANADIUM_DEVICE_DIR}" \
+ "$@"
+ fi
+}
+
readonly BIN_NAMES=(deviced suidhelper agentd inithelper)
###############################################################################
@@ -188,48 +246,22 @@
fi
local -r SETUID_SCRIPT="${BIN_INSTALL}/suidhelper"
if [[ ${SINGLE_USER} == false ]]; then
- case "$(uname)" in
- "Darwin")
- # Group root not available on Darwin and chown
- # not in default path.
- sudo /usr/sbin/chown -R "${DEVMGR_USER}":wheel \
- "${VANADIUM_DEVICE_DIR}"
- sudo /usr/sbin/chown root:wheel "${SETUID_SCRIPT}"
- ;;
- "Linux")
- sudo chown -R "${DEVMGR_USER}:${DEVMGR_USER}" "${VANADIUM_DEVICE_DIR}"
- sudo chown root:root "${SETUID_SCRIPT}"
- ;;
- esac
- sudo chmod 4551 "${SETUID_SCRIPT}"
+ portable_chown -R "${DEVMGR_USER}:${DEVMGR_USER}" "${VANADIUM_DEVICE_DIR}"
+ make_suid "${SETUID_SCRIPT}"
fi
local -r INIT_SCRIPT="${BIN_INSTALL}/inithelper"
if [[ ${INIT_MODE} == true ]]; then
- case "$(uname)" in
- "Darwin")
- sudo /usr/sbin/chown root:wheel "${INIT_SCRIPT}"
- ;;
- "Linux")
- sudo chown root:root "${INIT_SCRIPT}"
- ;;
- esac
- sudo chmod 4551 "${INIT_SCRIPT}"
+ make_suid "${INIT_SCRIPT}"
fi
echo "Helpers configured."
# Install the device manager.
- if [[ ${SINGLE_USER} == false ]]; then
- sudo -u "${DEVMGR_USER}" \
- NAMESPACE_ROOT="${NAMESPACE_ROOT}" \
- VANADIUM_DEVICE_DIR="${VANADIUM_DEVICE_DIR}" \
- "${BIN_INSTALL}/deviced" install \
- --suid_helper="${SETUID_SCRIPT}" \
- --agent="${BIN_INSTALL}/agentd" \
- --init_helper="${INIT_SCRIPT}" "$@"
- else
- echo "Installing device manager under ${VANADIUM_DEVICE_DIR} ..."
- "${BIN_INSTALL}/deviced" install --suid_helper="${SETUID_SCRIPT}" --agent="${BIN_INSTALL}/agentd" --init_helper="${INIT_SCRIPT}" "$@"
- fi
+ echo "Installing device manager under ${VANADIUM_DEVICE_DIR} ..."
+ echo "VANADIUM_DEVICE_DIR=${VANADIUM_DEVICE_DIR}"
+ run "${BIN_INSTALL}/deviced" install \
+ --suid_helper="${SETUID_SCRIPT}" \
+ --agent="${BIN_INSTALL}/agentd" \
+ --init_helper="${INIT_SCRIPT}" "$@"
echo "Device manager installed."
}
@@ -271,11 +303,8 @@
local -r BIN_INSTALL="${VANADIUM_DEVICE_DIR}/bin"
local -r SETUID_SCRIPT="${BIN_INSTALL}/suidhelper"
echo "Uninstalling device manager from ${VANADIUM_DEVICE_DIR} ..."
- sudo -u $(getdevowner) \
- VANADIUM_DEVICE_DIR="${VANADIUM_DEVICE_DIR}" \
- NAMESPACE_ROOT="${NAMESPACE_ROOT}" \
- "${BIN_INSTALL}/deviced" uninstall \
- --suid_helper="${SETUID_SCRIPT}"
+ run "${BIN_INSTALL}/deviced" uninstall \
+ --suid_helper="${SETUID_SCRIPT}"
echo "Device manager uninstalled."
# Any data created underneath "${VANADIUM_DEVICE_DIR}" by the "deviced
@@ -283,9 +312,8 @@
# However, install() created "${VANADIUM_DEVICE_DIR}", so uninstall() needs
# to remove it (as well as data created by install(), like bin/*).
- rm -rf "${VANADIUM_DEVICE_DIR}" || \
- sudo -u $(getdevowner) rm -rf "${VANADIUM_DEVICE_DIR}" || \
- rmdir "${VANADIUM_DEVICE_DIR}"
+ run rm -rf "${VANADIUM_DEVICE_DIR}/bin"
+ rmdir "${VANADIUM_DEVICE_DIR}"
echo "Removed ${VANADIUM_DEVICE_DIR}"
}
@@ -304,10 +332,7 @@
exit 1
fi
local -r BIN_INSTALL="${VANADIUM_DEVICE_DIR}/bin"
- sudo -u $(getdevowner) \
- VANADIUM_DEVICE_DIR="${VANADIUM_DEVICE_DIR}" \
- NAMESPACE_ROOT="${NAMESPACE_ROOT}" \
- "${BIN_INSTALL}/deviced" start
+ run "${BIN_INSTALL}/deviced" start
}
###############################################################################
@@ -325,10 +350,7 @@
exit 1
fi
local -r BIN_INSTALL="${VANADIUM_DEVICE_DIR}/bin"
- sudo -u $(getdevowner) \
- VANADIUM_DEVICE_DIR="${VANADIUM_DEVICE_DIR}" \
- NAMESPACE_ROOT="${NAMESPACE_ROOT}" \
- "${BIN_INSTALL}/deviced" stop
+ run "${BIN_INSTALL}/deviced" stop
}
main() {
diff --git a/tools/mgmt/suid_test.sh b/tools/mgmt/suid_test.sh
index d76cac2..cdcad85 100755
--- a/tools/mgmt/suid_test.sh
+++ b/tools/mgmt/suid_test.sh
@@ -17,7 +17,7 @@
#
# For exanple:
#
-# ./test.sh --with_suid devicemanager vana
+# ./suid_test.sh --with_suid devicemanager vana
#
# to test a device manager with multi-account support enabled for app
# account vana.
@@ -197,8 +197,8 @@
awk '$2 ~'"${DPID}"' { print $1 }')
;;
"Linux")
- local -r COMPUTED_DEVMGR_USER=$(ps -ef | \
- awk '$2 ~'"${DPID}"' { print $1 }')
+ local -r COMPUTED_DEVMGR_USER=$(awk '/^Uid:/{print $2}' /proc/${DPID}/status | \
+ xargs getent passwd | awk -F: '{print $1}')
;;
esac
shell_test::assert_eq "${COMPUTED_DEVMGR_USER}" \
@@ -274,7 +274,8 @@
local -r COMPUTED_SUID_USER=$(ps -ej | awk '$2 ~'"${PID}"' { print $1 }')
;;
"Linux")
- local -r COMPUTED_SUID_USER=$(ps -ef | awk '$2 ~'"${PID}"' { print $1 }')
+ local -r COMPUTED_SUID_USER=$(awk '/^Uid:/{print $2}' /proc/${PID}/status | \
+ xargs getent passwd | awk -F: '{print $1}')
;;
esac
shell_test::assert_eq "${COMPUTED_SUID_USER}" "${SUID_USER}" "${LINENO}"
diff --git a/tools/principal/bless.go b/tools/principal/bless.go
index 7831729..3b4d851 100644
--- a/tools/principal/bless.go
+++ b/tools/principal/bless.go
@@ -24,7 +24,7 @@
func exchangeMacaroonForBlessing(ctx *context.T, macaroonChan <-chan string) (security.Blessings, error) {
service, macaroon, rootKey, err := prepareBlessArgs(ctx, macaroonChan)
if err != nil {
- return nil, err
+ return security.Blessings{}, err
}
ctx, cancel := context.WithTimeout(ctx, time.Minute)
@@ -36,11 +36,11 @@
// service is not a trusted root yet.
reply, err = identity.MacaroonBlesserClient(service).Bless(ctx, macaroon, options.SkipResolveAuthorization{}, options.ServerPublicKey{rootKey})
if err != nil {
- return nil, fmt.Errorf("failed to get blessing from %q: %v", service, err)
+ return security.Blessings{}, fmt.Errorf("failed to get blessing from %q: %v", service, err)
}
blessings, err := security.NewBlessings(reply)
if err != nil {
- return nil, fmt.Errorf("failed to construct Blessings object from response: %v", err)
+ return security.Blessings{}, fmt.Errorf("failed to construct Blessings object from response: %v", err)
}
return blessings, nil
}
diff --git a/tools/principal/main.go b/tools/principal/main.go
index 83d7c77..2d22948 100644
--- a/tools/principal/main.go
+++ b/tools/principal/main.go
@@ -8,7 +8,6 @@
"crypto/rand"
"crypto/subtle"
"encoding/base64"
- "errors"
"fmt"
"io"
"os"
@@ -747,14 +746,14 @@
func decodeBlessings(fname string) (security.Blessings, error) {
var wire security.WireBlessings
if err := decode(fname, &wire); err != nil {
- return nil, err
+ return security.Blessings{}, err
}
return security.NewBlessings(wire)
}
func dumpBlessings(blessings security.Blessings) error {
- if blessings == nil {
- return errors.New("no blessings found")
+ if blessings.IsZero() {
+ return fmt.Errorf("no blessings found")
}
str, err := base64VomEncode(security.MarshalBlessings(blessings))
if err != nil {
@@ -856,7 +855,7 @@
func (r *recvBlessingsService) Grant(call ipc.ServerCall, token string) error {
b := call.Blessings()
- if b == nil {
+ if b.IsZero() {
return fmt.Errorf("no blessings granted by sender")
}
if len(token) != len(r.token) {
@@ -906,7 +905,7 @@
// abort the RPC before sending the request to the server.
// Thus, there is no concern about leaking the token to an
// imposter server.
- return nil, fmt.Errorf("key mismatch: Remote end has public key %v, want %v", got, g.serverKey)
+ return security.Blessings{}, fmt.Errorf("key mismatch: Remote end has public key %v, want %v", got, g.serverKey)
}
return g.p.Bless(server.PublicKey(), g.with, g.extension, g.caveats[0], g.caveats[1:]...)
}