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))