veyron2/security,veyron/security/caveat: Expose Endpoint in security.Context; implement NetworkType caveat
Change-Id: Ie64f97e5e1c2179515760396747375ec2c54ccf5
diff --git a/examples/boxes/android/src/boxesp2p/main.go b/examples/boxes/android/src/boxesp2p/main.go
index e2359d9..90cae68 100644
--- a/examples/boxes/android/src/boxesp2p/main.go
+++ b/examples/boxes/android/src/boxesp2p/main.go
@@ -135,7 +135,7 @@
func (gs *goState) SyncBoxes(context ipc.ServerContext) error {
// Get the endpoint of the remote process
- endPt, err := inaming.NewEndpoint(context.RemoteAddr().String())
+ endPt, err := inaming.NewEndpoint(context.RemoteEndpoint().String())
if err != nil {
return err
}
diff --git a/runtimes/google/ipc/flow_test.go b/runtimes/google/ipc/flow_test.go
index 35f7662..e856eb3 100644
--- a/runtimes/google/ipc/flow_test.go
+++ b/runtimes/google/ipc/flow_test.go
@@ -10,6 +10,7 @@
_ "veyron/lib/testutil"
"veyron2/ipc"
+ "veyron2/naming"
"veyron2/security"
"veyron2/verror"
)
@@ -31,6 +32,8 @@
func (f *testFlow) Write(b []byte) (int, error) { return f.w.Write(b) }
func (f *testFlow) LocalAddr() net.Addr { return nil }
func (f *testFlow) RemoteAddr() net.Addr { return nil }
+func (f *testFlow) LocalEndpoint() naming.Endpoint { return nil }
+func (f *testFlow) RemoteEndpoint() naming.Endpoint { return nil }
func (f *testFlow) LocalID() security.PublicID { return security.FakePublicID("test") }
func (f *testFlow) RemoteID() security.PublicID { return security.FakePublicID("test") }
func (f *testFlow) SetReadDeadline(t time.Time) error { return nil }
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 5cf77d8..3c0842c 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -3,7 +3,6 @@
import (
"fmt"
"io"
- "net"
"reflect"
"strings"
"sync"
@@ -574,8 +573,8 @@
func (fs *flowServer) RemoteID() security.PublicID { return fs.authorizedRemoteID }
func (fs *flowServer) Deadline() time.Time { return fs.deadline }
func (fs *flowServer) Blessing() security.PublicID { return fs.blessing }
-func (fs *flowServer) LocalAddr() net.Addr { return fs.flow.LocalAddr() }
-func (fs *flowServer) RemoteAddr() net.Addr { return fs.flow.RemoteAddr() }
+func (fs *flowServer) LocalEndpoint() naming.Endpoint { return fs.flow.LocalEndpoint() }
+func (fs *flowServer) RemoteEndpoint() naming.Endpoint { return fs.flow.RemoteEndpoint() }
func (fs *flowServer) IsClosed() bool {
return fs.flow.IsClosed()
diff --git a/runtimes/google/ipc/stream/vc/flow.go b/runtimes/google/ipc/stream/vc/flow.go
index 9a9112e..ccad460 100644
--- a/runtimes/google/ipc/stream/vc/flow.go
+++ b/runtimes/google/ipc/stream/vc/flow.go
@@ -4,6 +4,7 @@
"net"
"time"
+ "veyron2/naming"
"veyron2/security"
)
@@ -11,7 +12,7 @@
idHolder
*reader
*writer
- laddr, raddr net.Addr
+ localEndpoint, remoteEndpoint naming.Endpoint
}
type idHolder interface {
@@ -19,8 +20,12 @@
RemoteID() security.PublicID
}
-func (f *flow) LocalAddr() net.Addr { return f.laddr }
-func (f *flow) RemoteAddr() net.Addr { return f.raddr }
+func (f *flow) LocalEndpoint() naming.Endpoint { return f.localEndpoint }
+func (f *flow) RemoteEndpoint() naming.Endpoint { return f.remoteEndpoint }
+
+// implement net.Conn
+func (f *flow) LocalAddr() net.Addr { return f.localEndpoint }
+func (f *flow) RemoteAddr() net.Addr { return f.remoteEndpoint }
func (f *flow) Close() error {
f.reader.Close()
f.writer.Close()
diff --git a/runtimes/google/ipc/stream/vc/listener_test.go b/runtimes/google/ipc/stream/vc/listener_test.go
index 269c366..a449242 100644
--- a/runtimes/google/ipc/stream/vc/listener_test.go
+++ b/runtimes/google/ipc/stream/vc/listener_test.go
@@ -5,6 +5,7 @@
"testing"
"time"
+ "veyron2/naming"
"veyron2/security"
)
@@ -17,6 +18,8 @@
func (*noopFlow) IsClosed() bool { return false }
func (*noopFlow) Closed() <-chan struct{} { return nil }
func (*noopFlow) Cancel() {}
+func (*noopFlow) LocalEndpoint() naming.Endpoint { return nil }
+func (*noopFlow) RemoteEndpoint() naming.Endpoint { return nil }
func (*noopFlow) LocalAddr() net.Addr { return nil }
func (*noopFlow) RemoteAddr() net.Addr { return nil }
func (*noopFlow) SetDeadline(t time.Time) error { return nil }
diff --git a/runtimes/google/ipc/stream/vc/vc.go b/runtimes/google/ipc/stream/vc/vc.go
index f213412..09d719d 100644
--- a/runtimes/google/ipc/stream/vc/vc.go
+++ b/runtimes/google/ipc/stream/vc/vc.go
@@ -154,11 +154,11 @@
return nil, fmt.Errorf("failed to create writer for Flow: %v", err)
}
f := &flow{
- idHolder: vc,
- reader: newReader(readHandlerImpl{vc, fid}),
- writer: writer,
- laddr: vc.localEP,
- raddr: vc.remoteEP,
+ idHolder: vc,
+ reader: newReader(readHandlerImpl{vc, fid}),
+ writer: writer,
+ localEndpoint: vc.localEP,
+ remoteEndpoint: vc.remoteEP,
}
vc.mu.Lock()
if vc.flowMap != nil {
@@ -257,11 +257,11 @@
return fmt.Errorf("failed to create writer for new flow(%d): %v", fid, err)
}
f := &flow{
- idHolder: vc,
- reader: newReader(readHandlerImpl{vc, fid}),
- writer: writer,
- laddr: vc.localEP,
- raddr: vc.remoteEP,
+ idHolder: vc,
+ reader: newReader(readHandlerImpl{vc, fid}),
+ writer: writer,
+ localEndpoint: vc.localEP,
+ remoteEndpoint: vc.remoteEP,
}
if err = vc.listener.Enqueue(f); err != nil {
f.Shutdown()
diff --git a/runtimes/google/security/util.go b/runtimes/google/security/util.go
index be2c7a2..754a5f8 100644
--- a/runtimes/google/security/util.go
+++ b/runtimes/google/security/util.go
@@ -7,6 +7,7 @@
"strings"
"veyron/runtimes/google/security/keys"
+ "veyron2/naming"
"veyron2/security"
"veyron2/security/wire"
)
@@ -91,6 +92,8 @@
Suffix string
// Label is the security label of the method being invoked.
Label security.Label
+ // LocalEndpoint, RemoteEndpoint are the veyron endpoints of the local and remote ends of a request
+ LocalEndpoint, RemoteEndpoint naming.Endpoint
}
// context implements security.Context. This implementation simply stores the
@@ -141,6 +144,8 @@
func (c *context) CaveatDischarges() security.CaveatDischargeMap { return c.ContextArgs.Discharges }
func (c *context) LocalID() security.PublicID { return c.ContextArgs.LocalID }
func (c *context) RemoteID() security.PublicID { return c.ContextArgs.RemoteID }
+func (c *context) LocalEndpoint() naming.Endpoint { return c.ContextArgs.LocalEndpoint }
+func (c *context) RemoteEndpoint() naming.Endpoint { return c.ContextArgs.RemoteEndpoint }
// NewContext returns a new security.Context for the provided method, name,
// suffix, discharges, label and identities of the local and remote principals
diff --git a/security/caveat/caveat.go b/security/caveat/caveat.go
index 6cb4735..a0e0f11 100644
--- a/security/caveat/caveat.go
+++ b/security/caveat/caveat.go
@@ -59,8 +59,20 @@
return fmt.Errorf("%#v forbids RPCing with peer %s", c, ctx.LocalID())
}
+// NetworkType is a security.Caveat that restricts communication with the
+// remote process to a particular network ("tcp", "udp", "bluetooth" etc.)
+type NetworkType string
+
+func (cav NetworkType) Validate(ctx security.Context) error {
+ if ctx.RemoteEndpoint().Addr().Network() == string(cav) {
+ return nil
+ }
+ return fmt.Errorf("required network type %q, got %q", cav, ctx.RemoteEndpoint().Addr().Network())
+}
+
func init() {
vom.Register(Expiry{})
vom.Register(MethodRestriction(nil))
vom.Register(PeerIdentity(nil))
+ vom.Register(NetworkType(""))
}
diff --git a/security/caveat/caveat_test.go b/security/caveat/caveat_test.go
index 8c7efdf..b4f44f8 100644
--- a/security/caveat/caveat_test.go
+++ b/security/caveat/caveat_test.go
@@ -1,16 +1,27 @@
package caveat_test
import (
+ "net"
"testing"
"time"
"veyron/security/caveat"
+ "veyron2/naming"
"veyron2/security"
)
+// endpoint implements naming.Endpoint
+type endpoint struct {
+ naming.Endpoint
+ addr net.Addr
+}
+
+func (e endpoint) Addr() net.Addr { return e.addr }
+
type context struct {
- local, remote security.PublicID
- method string
+ local, remote security.PublicID
+ localEndpoint, remoteEndpoint endpoint
+ method string
}
func (c *context) Method() string { return c.method }
@@ -20,6 +31,8 @@
func (c *context) CaveatDischarges() security.CaveatDischargeMap { return nil }
func (c *context) LocalID() security.PublicID { return c.local }
func (c *context) RemoteID() security.PublicID { return c.remote }
+func (c *context) LocalEndpoint() naming.Endpoint { return &c.localEndpoint }
+func (c *context) RemoteEndpoint() naming.Endpoint { return &c.remoteEndpoint }
func TestCaveats(t *testing.T) {
var (
@@ -34,6 +47,8 @@
{&caveat.Expiry{IssueTime: now, ExpiryTime: now.Add(time.Hour)}, true},
{&caveat.Expiry{IssueTime: now.Add(-1 * time.Hour), ExpiryTime: now.Add(-1 * time.Minute)}, false},
{caveat.MethodRestriction(nil), false},
+ {caveat.NetworkType("udp"), false},
+ {caveat.NetworkType("tcp"), true},
{caveat.MethodRestriction{"Pause", "Play"}, true},
{caveat.MethodRestriction{"List"}, false},
{caveat.PeerIdentity(nil), false},
@@ -41,7 +56,7 @@
{caveat.PeerIdentity{"fake/carol"}, false},
{caveat.PeerIdentity{"fake/alice", "fake/carol"}, true},
}
- ctx := &context{local: alice, remote: bob, method: "Play"}
+ ctx := &context{local: alice, remote: bob, method: "Play", remoteEndpoint: endpoint{addr: &net.TCPAddr{}}}
for _, test := range tests {
if err := test.c.Validate(ctx); test.ok != (err == nil) {
t.Errorf("Caveat:%#v. Got error:%v, want error:%v", test.c, err, test.ok)
diff --git a/services/store/memstore/blackbox/util.go b/services/store/memstore/blackbox/util.go
index c46baf0..2ff6bf1 100644
--- a/services/store/memstore/blackbox/util.go
+++ b/services/store/memstore/blackbox/util.go
@@ -4,7 +4,6 @@
"fmt"
"io"
"io/ioutil"
- "net"
"os"
"runtime"
"testing"
@@ -16,6 +15,7 @@
"veyron/services/store/service"
"veyron2/ipc"
+ "veyron2/naming"
"veyron2/security"
"veyron2/services/watch"
"veyron2/storage"
@@ -66,11 +66,11 @@
return nil
}
-func (rootContext) LocalAddr() net.Addr {
+func (rootContext) LocalEndpoint() naming.Endpoint {
return nil
}
-func (rootContext) RemoteAddr() net.Addr {
+func (rootContext) RemoteEndpoint() naming.Endpoint {
return nil
}
diff --git a/services/store/memstore/util_test.go b/services/store/memstore/util_test.go
index 0917a4a..9a344a8 100644
--- a/services/store/memstore/util_test.go
+++ b/services/store/memstore/util_test.go
@@ -2,7 +2,6 @@
import (
"io"
- "net"
"runtime"
"testing"
"time"
@@ -11,6 +10,7 @@
"veyron/services/store/service"
"veyron2/ipc"
+ "veyron2/naming"
"veyron2/security"
"veyron2/storage"
)
@@ -60,11 +60,11 @@
return nil
}
-func (*cancellableContext) LocalAddr() net.Addr {
+func (*cancellableContext) LocalEndpoint() naming.Endpoint {
return nil
}
-func (*cancellableContext) RemoteAddr() net.Addr {
+func (*cancellableContext) RemoteEndpoint() naming.Endpoint {
return nil
}
diff --git a/services/store/memstore/watch/testing/util.go b/services/store/memstore/watch/testing/util.go
index 02a7365..941a2a6 100644
--- a/services/store/memstore/watch/testing/util.go
+++ b/services/store/memstore/watch/testing/util.go
@@ -2,11 +2,11 @@
import (
"errors"
- "net"
"sync"
"time"
"veyron2/ipc"
+ "veyron2/naming"
"veyron2/security"
"veyron2/services/watch"
)
@@ -65,11 +65,11 @@
return nil
}
-func (*CancellableContext) LocalAddr() net.Addr {
+func (*CancellableContext) LocalEndpoint() naming.Endpoint {
return nil
}
-func (*CancellableContext) RemoteAddr() net.Addr {
+func (*CancellableContext) RemoteEndpoint() naming.Endpoint {
return nil
}
diff --git a/services/store/server/server_test.go b/services/store/server/server_test.go
index bfdabd4..b434767 100644
--- a/services/store/server/server_test.go
+++ b/services/store/server/server_test.go
@@ -4,7 +4,6 @@
"fmt"
"io/ioutil"
"log"
- "net"
"os"
"reflect"
"testing"
@@ -14,6 +13,7 @@
"veyron/services/store/raw"
"veyron2/ipc"
+ "veyron2/naming"
"veyron2/security"
"veyron2/services/store"
"veyron2/services/watch"
@@ -72,11 +72,11 @@
return nil
}
-func (*testContext) LocalAddr() net.Addr {
+func (*testContext) LocalEndpoint() naming.Endpoint {
return nil
}
-func (*testContext) RemoteAddr() net.Addr {
+func (*testContext) RemoteEndpoint() naming.Endpoint {
return nil
}