veyron2/options,veyron/runtimes/google/ipc: Allow different servers to
present different blessings.
Prior to this commit, all ipc.Servers created by a Runtime would
present the same (Principal.BlessingStore.Default) blessings to
all clients.
With this commit, distinct ipc.Servers in the same Runtime can
be configured to use distinct blessings - i.e., not use the
BlessingStore's default.
This was mostly motivated by the nodemanager/appmgr use case where
"application" binaries would typically have two ipc.Servers - one
for receiving instructions from the node manager and one for acting
as the "application". It is conceivable that the blessings presented
by the latter would be distinct from the former - for example, the
application does not need to present its "device ownership" blessings
to application clients.
Note that we intentionally do not provide such as "blessings selection"
option for Client creation, since ipc.Clients already present different
blessings to different servers. While there may be a need to be fancier,
we defer that for now.
Change-Id: I9f72335328fdb66f66c9f8336c9fb2828bbb7bf3
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 2c721d9..bdbdc1f 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -373,7 +373,7 @@
// Recreate client in each test (so as to not re-use VCs to the server).
client, err := InternalNewClient(mgr, ns, vc.LocalPrincipal{pclient})
if err != nil {
- t.Errorf("%s: failed ot create client: %v", name, err)
+ t.Errorf("%s: failed to create client: %v", name, err)
continue
}
if call, err := client.StartCall(testContext(), fmt.Sprintf("[%s]mountpoint/server/suffix", test.pattern), "Method", nil); !matchesErrorPattern(err, test.err) {
@@ -1144,6 +1144,79 @@
}
}
+func TestServerBlessingsOpt(t *testing.T) {
+ var (
+ pserver = sectest.NewPrincipal("server")
+ pclient = sectest.NewPrincipal("client")
+ batman, _ = pserver.BlessSelf("batman")
+ )
+ // Make the client recognize all server blessings
+ if err := pclient.AddToRoots(batman); err != nil {
+ t.Fatal(err)
+ }
+ if err := pclient.AddToRoots(pserver.BlessingStore().Default()); err != nil {
+ t.Fatal(err)
+ }
+ // Start a server that uses the ServerBlessings option to configure itself
+ // to act as batman (as opposed to using the default blessing).
+ ns := tnaming.NewSimpleNamespace()
+ runServer := func(name string, opts ...ipc.ServerOpt) stream.Manager {
+ opts = append(opts, vc.LocalPrincipal{pserver})
+ rid, err := naming.NewRoutingID()
+ if err != nil {
+ t.Fatal(err)
+ }
+ sm := imanager.InternalNew(rid)
+ server, err := InternalNewServer(
+ testContext(),
+ sm,
+ ns,
+ opts...)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if _, err := server.Listen(listenSpec); err != nil {
+ t.Fatal(err)
+ }
+ if err := server.Serve(name, &testServer{}, nil); err != nil {
+ t.Fatal(err)
+ }
+ return sm
+ }
+
+ defer runServer("mountpoint/batman", options.ServerBlessings{batman}).Shutdown()
+ defer runServer("mountpoint/default").Shutdown()
+
+ // And finally, make and RPC and see that the client sees "batman"
+ runClient := func(server string) ([]string, error) {
+ smc := imanager.InternalNew(naming.FixedRoutingID(0xc))
+ defer smc.Shutdown()
+ client, err := InternalNewClient(
+ smc,
+ ns,
+ vc.LocalPrincipal{pclient})
+ if err != nil {
+ return nil, err
+ }
+ defer client.Close()
+ call, err := client.StartCall(testContext(), server, "Closure", nil)
+ if err != nil {
+ return nil, err
+ }
+ blessings, _ := call.RemoteBlessings()
+ return blessings, nil
+ }
+
+ // When talking to mountpoint/batman, should see "batman"
+ // When talking to mountpoint/default, should see "server"
+ if got, err := runClient("mountpoint/batman"); err != nil || len(got) != 1 || got[0] != "batman" {
+ t.Errorf("Got (%v, %v) wanted 'batman'", got, err)
+ }
+ if got, err := runClient("mountpoint/default"); err != nil || len(got) != 1 || got[0] != "server" {
+ t.Errorf("Got (%v, %v) wanted 'server'", got, err)
+ }
+}
+
func init() {
testutil.Init()
vom.Register(fakeTimeCaveat(0))