Merge "veyron/tools/naming/simulator: add support for running proxies, sundry fixes."
diff --git a/lib/expect/expect.go b/lib/expect/expect.go
index 4950758..e7da3a3 100644
--- a/lib/expect/expect.go
+++ b/lib/expect/expect.go
@@ -272,6 +272,59 @@
return m[0][1]
}
+// ExpectSetRE verifies whether the supplied set of regular expression
+// parameters matches the next n (where n is the number of parameters)
+// lines of input. Each line is read and matched against the supplied
+// patterns in the order that they are supplied as parameters. Consequently
+// the set may contain repetitions if the same pattern is expected multiple
+// times.
+func (s *Session) ExpectSetRE(expected ...string) {
+ if s.Failed() {
+ return
+ }
+ regexps := make([]*regexp.Regexp, len(expected))
+ for i, expRE := range expected {
+ re, err := regexp.Compile(expRE)
+ if err != nil {
+ s.error(err)
+ return
+ }
+ regexps[i] = re
+ }
+ actual := make([]string, len(expected))
+ for i := 0; i < len(expected); i++ {
+ line, err := s.read(readLine)
+ line = strings.TrimRight(line, "\n")
+ s.log(err, "ExpectSetRE: %s", line)
+ if err != nil {
+ s.error(err)
+ return
+ }
+ actual[i] = line
+ }
+ // Match each line against all regexp's and remove each regexp
+ // that matches.
+ for _, l := range actual {
+ found := false
+ for i, re := range regexps {
+ if re == nil {
+ continue
+ }
+ if re.MatchString(l) {
+ // We remove each RE that matches.
+ found = true
+ regexps[i] = nil
+ break
+ }
+ }
+ if !found {
+ s.error(fmt.Errorf("found no match for %q", l))
+ return
+ }
+ }
+
+}
+
// ReadLine reads the next line, if any, from the input stream. It will set
// the error state to io.EOF if it has read past the end of the stream.
// ReadLine has no effect if an error has already occurred.
diff --git a/lib/expect/expect_test.go b/lib/expect/expect_test.go
index c85d803..8fa62da 100644
--- a/lib/expect/expect_test.go
+++ b/lib/expect/expect_test.go
@@ -87,6 +87,27 @@
s.ExpectEOF()
}
+func TestExpectSetRE(t *testing.T) {
+ buf := []byte{}
+ buffer := bytes.NewBuffer(buf)
+ buffer.WriteString("bar=baz\n")
+ buffer.WriteString("abc\n")
+ buffer.WriteString("def\n")
+ buffer.WriteString("abc\n")
+ s := expect.NewSession(nil, bufio.NewReader(buffer), time.Minute)
+ s.ExpectSetRE("^bar=.*$", "def$", "^abc$", "^a..$")
+ if s.Error() != nil {
+ t.Errorf("unexpected error: %s", s.Error())
+ }
+ buffer.WriteString("ooh\n")
+ buffer.WriteString("aah\n")
+ s.ExpectSetRE("bar=.*", "def")
+ if got, want := s.Error(), "expect_test.go:104: found no match for \"ooh\""; got == nil || got.Error() != want {
+ t.Errorf("got %v, want %q", got, want)
+ }
+ s.ExpectEOF()
+}
+
func TestRead(t *testing.T) {
buf := []byte{}
buffer := bytes.NewBuffer(buf)
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))