veyron/runtimes/google/ipc: Disable authorization if authentication
is disabled.
Change-Id: I68f2078d3ecb5d956f267ac722874bc5f1db8567
diff --git a/runtimes/google/ipc/client.go b/runtimes/google/ipc/client.go
index d20e598..940b43c 100644
--- a/runtimes/google/ipc/client.go
+++ b/runtimes/google/ipc/client.go
@@ -245,18 +245,24 @@
}
flow.SetDeadline(ctx.Done())
- // Validate caveats on the server's identity for the context associated with this call.
- serverB, grantedB, err := c.authorizeServer(flow, name, suffix, method, opts)
- if err != nil {
- lastErr = verror.NoAccessf("ipc: client unwilling to invoke %q.%q on server %v: %v", name, method, flow.RemoteBlessings(), err)
- flow.Close()
- continue
- }
- // Fetch any discharges for third-party caveats on the client's blessings.
+ var serverB []string
+ var grantedB security.Blessings
var discharges []security.Discharge
- if self := flow.LocalBlessings(); self != nil {
- if tpcavs := self.ThirdPartyCaveats(); len(tpcavs) > 0 {
- discharges = c.prepareDischarges(ctx, tpcavs, mkDischargeImpetus(serverB, method, args), opts)
+
+ // LocalPrincipal is nil means that the client wanted to avoid authentication,
+ // and thus wanted to skip authorization as well.
+ if flow.LocalPrincipal() != nil {
+ // Validate caveats on the server's identity for the context associated with this call.
+ if serverB, grantedB, err = c.authorizeServer(flow, name, suffix, method, opts); err != nil {
+ lastErr = verror.NoAccessf("ipc: client unwilling to invoke %q.%q on server %v: %v", name, method, flow.RemoteBlessings(), err)
+ flow.Close()
+ continue
+ }
+ // Fetch any discharges for third-party caveats on the client's blessings.
+ if self := flow.LocalBlessings(); self != nil {
+ if tpcavs := self.ThirdPartyCaveats(); len(tpcavs) > 0 {
+ discharges = c.prepareDischarges(ctx, tpcavs, mkDischargeImpetus(serverB, method, args), opts)
+ }
}
}
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index a26570f..0f0f3a9 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -1044,6 +1044,41 @@
}
}
+func TestSecurityNone(t *testing.T) {
+ sm := imanager.InternalNew(naming.FixedRoutingID(0x66666666))
+ defer sm.Shutdown()
+ ns := tnaming.NewSimpleNamespace()
+ server, err := InternalNewServer(testContext(), sm, ns, options.VCSecurityNone)
+ if err != nil {
+ t.Fatalf("InternalNewServer failed: %v", err)
+ }
+ if _, err = server.Listen(listenSpec); err != nil {
+ t.Fatalf("server.Listen failed: %v", err)
+ }
+ disp := &testServerDisp{&testServer{}}
+ if err := server.Serve("mp/server", disp); err != nil {
+ t.Fatalf("server.Serve failed: %v", err)
+ }
+ client, err := InternalNewClient(sm, ns, options.VCSecurityNone)
+ if err != nil {
+ t.Fatalf("InternalNewClient failed: %v", err)
+ }
+ // When using VCSecurityNone, all authorization checks should be skipped, so
+ // unauthorized methods shoudl be callable.
+ call, err := client.StartCall(testContext(), "mp/server", "Unauthorized", nil)
+ if err != nil {
+ t.Fatalf("client.StartCall failed: %v", err)
+ }
+ var got string
+ var ierr error
+ if err := call.Finish(&got, &ierr); err != nil {
+ t.Errorf("call.Finish failed: %v", err)
+ }
+ if want := "UnauthorizedResult"; got != want {
+ t.Errorf("got (%v), want (%v)", got, want)
+ }
+}
+
func init() {
testutil.Init()
vom.Register(fakeTimeCaveat(0))
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 514377f..e9139b7 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -857,12 +857,18 @@
return nil, verror.NoAccessf("%v is not authorized to call %q.%q (%v)", fs.RemoteID(), fs.Name(), fs.Method(), err)
}
}
+
+ fs.allowDebug = fs.LocalPrincipal() == nil
// Check application's authorization policy and invoke the method.
- if err := fs.authorize(auth); err != nil {
- return nil, err
+ // LocalPrincipal is nil means that the server wanted to avoid authentication,
+ // and thus wanted to skip authorization as well.
+ if fs.LocalPrincipal() != nil {
+ // Check if the caller is permitted to view debug information.
+ if err := fs.authorize(auth); err != nil {
+ return nil, err
+ }
+ fs.allowDebug = fs.authorizeForDebug(auth) == nil
}
- // Check if the caller is permitted to view debug information.
- fs.allowDebug = fs.authorizeForDebug(auth) == nil
results, err := invoker.Invoke(req.Method, fs, argptrs)
fs.server.stats.record(req.Method, time.Since(start))