// GoCaveat converts the provided Java Caveat into a Go Caveat. func GoCaveat(env jutil.Env, jCav jutil.Object) (security.Caveat, error) { // NOTE(spetrovic): We could call GoVomCopy here, but it's painfully slow and this code is // on the critical path. // Copy the Id field. jId, err := jutil.CallObjectMethod(env, jCav, "getId", nil, idSign) if err != nil { return security.Caveat{}, err } idBytes, err := jutil.CallByteArrayMethod(env, jId, "toPrimitiveArray", nil) if err != nil { return security.Caveat{}, err } var id uniqueid.Id copy(id[:], idBytes[:len(id)]) // Copy the ParamVom field. paramVom, err := jutil.CallByteArrayMethod(env, jCav, "getParamVom", nil) if err != nil { return security.Caveat{}, err } return security.Caveat{ Id: id, ParamVom: paramVom, }, nil }
func (s *blessingStore) PeerBlessings() map[security.BlessingPattern]security.Blessings { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessingsMap, err := jutil.CallObjectMethod(env, s.jBlessingStore, "peerBlessings", nil, jutil.MapSign) if err != nil { log.Printf("Couldn't get Java peer blessings: %v", err) return nil } bmap, err := jutil.GoObjectMap(env, jBlessingsMap) if err != nil { log.Printf("Couldn't convert Java object map into a Go object map: %v", err) return nil } ret := make(map[security.BlessingPattern]security.Blessings) for jPattern, jBlessings := range bmap { pattern, err := GoBlessingPattern(env, jPattern) if err != nil { log.Printf("Couldn't convert Java pattern into Go: %v", err) return nil } blessings, err := GoBlessings(env, jBlessings) if err != nil { log.Printf("Couldn't convert Java blessings into Go: %v", err) return nil } ret[pattern] = blessings } return ret }
// TODO(sjr): support cachedTime in Java func (s *blessingStore) Discharge(caveat security.Caveat, impetus security.DischargeImpetus) (security.Discharge, time.Time) { env, freeFunc := jutil.GetEnv() defer freeFunc() jCaveat, err := JavaCaveat(env, caveat) if err != nil { log.Printf("Couldn't get Java caveat: %v", err) return security.Discharge{}, time.Time{} } jImpetus, err := jutil.JVomCopy(env, impetus, jDischargeImpetusClass) if err != nil { log.Printf("Couldn't get Java DischargeImpetus: %v", err) return security.Discharge{}, time.Time{} } jDischarge, err := jutil.CallObjectMethod(env, s.jBlessingStore, "discharge", []jutil.Sign{caveatSign, dischargeImpetusSign}, dischargeSign, jCaveat, jImpetus) if err != nil { log.Printf("Couldn't call Java discharge method: %v", err) return security.Discharge{}, time.Time{} } discharge, err := GoDischarge(env, jDischarge) if err != nil { log.Printf("Couldn't convert Java discharge to Go: %v", err) return security.Discharge{}, time.Time{} } return discharge, time.Time{} }
func (p *principal) Bless(key security.PublicKey, with security.Blessings, extension string, caveat security.Caveat, additionalCaveats ...security.Caveat) (security.Blessings, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jKey, err := JavaPublicKey(env, key) if err != nil { return security.Blessings{}, err } jWith, err := JavaBlessings(env, with) if err != nil { return security.Blessings{}, err } jCaveat, err := JavaCaveat(env, caveat) if err != nil { return security.Blessings{}, err } jAdditionalCaveats, err := JavaCaveatArray(env, additionalCaveats) if err != nil { return security.Blessings{}, err } jBlessings, err := jutil.CallObjectMethod(env, p.jPrincipal, "bless", []jutil.Sign{publicKeySign, blessingsSign, jutil.StringSign, caveatSign, jutil.ArraySign(caveatSign)}, blessingsSign, jKey, jWith, extension, jCaveat, jAdditionalCaveats) if err != nil { return security.Blessings{}, err } return GoBlessings(env, jBlessings) }
func (p *principal) Sign(message []byte) (security.Signature, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jSig, err := jutil.CallObjectMethod(env, p.jPrincipal, "sign", []jutil.Sign{jutil.ArraySign(jutil.ByteSign)}, signatureSign, message) if err != nil { return security.Signature{}, err } return GoSignature(env, jSig) }
func (s *signer) Sign(purpose, message []byte) (security.Signature, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() signatureSign := jutil.ClassSign("io.v.v23.security.VSignature") jSig, err := jutil.CallObjectMethod(env, s.jSigner, "sign", []jutil.Sign{jutil.ArraySign(jutil.ByteSign), jutil.ArraySign(jutil.ByteSign)}, signatureSign, purpose, message) if err != nil { return security.Signature{}, err } return GoSignature(env, jSig) }
func (p *principal) BlessSelf(name string, caveats ...security.Caveat) (security.Blessings, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jCaveats, err := JavaCaveatArray(env, caveats) if err != nil { return security.Blessings{}, err } jBlessings, err := jutil.CallObjectMethod(env, p.jPrincipal, "blessSelf", []jutil.Sign{jutil.StringSign, jutil.ArraySign(caveatSign)}, blessingsSign, name, jCaveats) if err != nil { return security.Blessings{}, err } return GoBlessings(env, jBlessings) }
//export Java_io_v_v23_syncbase_DatabaseImpl_nativeListenForInvites func Java_io_v_v23_syncbase_DatabaseImpl_nativeListenForInvites(jenv *C.JNIEnv, jDatabase C.jobject, jContext C.jobject, jInviteHandler C.jobject) { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) database := jutil.Object(uintptr(unsafe.Pointer(jDatabase))) handler := jutil.Object(uintptr(unsafe.Pointer(jInviteHandler))) ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext)))) if err != nil { jutil.JThrowV(env, err) return } jDbId, err := jutil.CallObjectMethod(env, database, "id", nil, idSign) if err != nil { jutil.JThrowV(env, err) return } dbName, err := jutil.CallStringMethod(env, jDbId, "getName", nil) if err != nil { jutil.JThrowV(env, err) return } dbBlessing, err := jutil.CallStringMethod(env, jDbId, "getBlessing", nil) if err != nil { jutil.JThrowV(env, err) return } dbId := wire.Id{Name: dbName, Blessing: dbBlessing} // Note: There is no need to use a buffered channel here. ListenForInvites // spawns a goroutine for this listener that acts as an infinite buffer so we can // process invites at our own pace. ch := make(chan discovery.Invite) if err := discovery.ListenForInvites(ctx, dbId, ch); err != nil { jutil.JThrowV(env, err) return } handler = jutil.NewGlobalRef(env, handler) go func() { for invite := range ch { if err := handleInvite(invite, handler); err != nil { // TODO(mattr): We should cancel the stream and return an error to // the user here. ctx.Errorf("couldn't call invite handler: %v", err) } } env, free := jutil.GetEnv() jutil.DeleteGlobalRef(env, handler) free() }() }
func (c *callImpl) Context() *context.T { env, freeFunc := jutil.GetEnv() defer freeFunc() contextSign := jutil.ClassSign("io.v.v23.context.VContext") jCtx, err := jutil.CallObjectMethod(env, c.jCall, "context", nil, contextSign) if err != nil { log.Printf("Couldn't get Java Vanadium context: %v", err) } ctx, _, err := jcontext.GoContext(env, jCtx) if err != nil { log.Printf("Couldn't convert Java Vanadium context to Go: %v", err) } return ctx }
func (l *btListener) Accept(ctx *context.T) (flow.Conn, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jStream, err := jutil.CallObjectMethod(env, l.jListener, "accept", nil, streamSign) if err != nil { return nil, err } // Reference Java Stream; it will be de-referenced when the Go connection // created below is garbage-collected (through the finalizer callback we // setup just below). jStream = jutil.NewGlobalRef(env, jStream) return newConnection(env, jStream), nil }
func (chooser *jniAddressChooser) ChooseAddresses(protocol string, candidates []net.Addr) ([]net.Addr, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jCandidates, err := JavaNetworkAddressArray(env, candidates) if err != nil { return nil, err } addrsSign := jutil.ArraySign(jutil.ClassSign("io.v.v23.rpc.NetworkAddress")) jAddrs, err := jutil.CallObjectMethod(env, chooser.jChooser, "choose", []jutil.Sign{jutil.StringSign, addrsSign}, addrsSign, protocol, jCandidates) if err != nil { return nil, err } return GoNetworkAddressArray(env, jAddrs) }
func (p *principal) PublicKey() security.PublicKey { env, freeFunc := jutil.GetEnv() defer freeFunc() jPublicKey, err := jutil.CallObjectMethod(env, p.jPrincipal, "publicKey", nil, publicKeySign) if err != nil { log.Printf("Couldn't get Java public key: %v", err) return nil } key, err := GoPublicKey(env, jPublicKey) if err != nil { log.Printf("Couldn't convert Java public key to Go: %v", err) return nil } return key }
func (c *callImpl) MethodTags() []*vdl.Value { env, freeFunc := jutil.GetEnv() defer freeFunc() jTags, err := jutil.CallObjectMethod(env, c.jCall, "methodTags", nil, jutil.ArraySign(jutil.VdlValueSign)) if err != nil { log.Println("Couldn't call Java methodTags method: ", err) return nil } tags, err := jutil.GoVDLValueArray(env, jTags) if err != nil { log.Println("Couldn't convert Java tags to Go: ", err) return nil } return tags }
func (c *callImpl) Timestamp() time.Time { env, freeFunc := jutil.GetEnv() defer freeFunc() jTime, err := jutil.CallObjectMethod(env, c.jCall, "timestamp", nil, jutil.DateTimeSign) if err != nil { log.Println("Couldn't call Java timestamp method: ", err) return time.Time{} } t, err := jutil.GoTime(env, jTime) if err != nil { log.Println("Couldn't convert Java time to Go: ", err) return time.Time{} } return t }
func (p *principal) BlessingStore() security.BlessingStore { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessingStore, err := jutil.CallObjectMethod(env, p.jPrincipal, "blessingStore", nil, blessingStoreSign) if err != nil { log.Printf("Couldn't get Java Blessing Store: %v", err) return nil } store, err := GoBlessingStore(env, jBlessingStore) if err != nil { log.Printf("Couldn't convert Java Blessing Store to Go: %v", err) return nil } return store }
func (c *callImpl) RemoteBlessings() security.Blessings { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessings, err := jutil.CallObjectMethod(env, c.jCall, "remoteBlessings", nil, blessingsSign) if err != nil { log.Printf("Couldn't call Java remoteBlessings method: %v", err) return security.Blessings{} } blessings, err := GoBlessings(env, jBlessings) if err != nil { log.Printf("Couldn't convert Java Blessings into Go: %v", err) return security.Blessings{} } return blessings }
func (s *blessingStore) ForPeer(peerBlessings ...string) security.Blessings { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessings, err := jutil.CallObjectMethod(env, s.jBlessingStore, "forPeer", []jutil.Sign{jutil.ArraySign(jutil.StringSign)}, blessingsSign, peerBlessings) if err != nil { log.Printf("Couldn't call Java forPeer method: %v", err) return security.Blessings{} } blessings, err := GoBlessings(env, jBlessings) if err != nil { log.Printf("Couldn't convert Java Blessings into Go: %v", err) return security.Blessings{} } return blessings }
func (c *callImpl) LocalPrincipal() security.Principal { env, freeFunc := jutil.GetEnv() defer freeFunc() jPrincipal, err := jutil.CallObjectMethod(env, c.jCall, "localPrincipal", nil, principalSign) if err != nil { log.Printf("Couldn't call Java localPrincipal method: %v", err) return nil } principal, err := GoPrincipal(env, jPrincipal) if err != nil { log.Printf("Couldn't convert Java principal to Go: %v", err) return nil } return principal }
// GoListenSpec converts the provided Java ListenSpec into a Go ListenSpec. func GoListenSpec(env jutil.Env, jSpec jutil.Object) (rpc.ListenSpec, error) { jAddrs, err := jutil.CallObjectMethod(env, jSpec, "getAddresses", nil, jutil.ArraySign(listenAddrSign)) if err != nil { return rpc.ListenSpec{}, err } addrs, err := GoListenAddrs(env, jAddrs) if err != nil { return rpc.ListenSpec{}, err } proxy, err := jutil.CallStringMethod(env, jSpec, "getProxy", nil) if err != nil { return rpc.ListenSpec{}, err } jChooser, err := jutil.CallObjectMethod(env, jSpec, "getChooser", nil, addressChooserSign) if err != nil { return rpc.ListenSpec{}, err } chooser := GoAddressChooser(env, jChooser) return rpc.ListenSpec{ Addrs: addrs, Proxy: proxy, AddressChooser: chooser, }, nil }
func (p *principal) Roots() security.BlessingRoots { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessingRoots, err := jutil.CallObjectMethod(env, p.jPrincipal, "roots", nil, blessingRootsSign) if err != nil { log.Printf("Couldn't get Java Blessing Roots: %v", err) return nil } roots, err := GoBlessingRoots(env, jBlessingRoots) if err != nil { log.Printf("Couldn't convert Java Blessing Roots to Go: %v", err) return nil } return roots }
func (s *blessingStore) PublicKey() security.PublicKey { env, freeFunc := jutil.GetEnv() defer freeFunc() jPublicKey, err := jutil.CallObjectMethod(env, s.jBlessingStore, "publicKey", nil, publicKeySign) if err != nil { log.Printf("Couldn't get Java public key: %v", err) return nil } publicKey, err := GoPublicKey(env, jPublicKey) if err != nil { log.Printf("Couldn't convert Java ECPublicKey to Go PublicKey: %v", err) return nil } return publicKey }
func (s *blessingStore) Default() (security.Blessings, <-chan struct{}) { env, freeFunc := jutil.GetEnv() defer freeFunc() // TODO(ashankar,spetrovic): Figure out notification API in Java jBlessings, err := jutil.CallObjectMethod(env, s.jBlessingStore, "defaultBlessings", nil, blessingsSign) if err != nil { log.Printf("Couldn't call Java defaultBlessings method: %v", err) return security.Blessings{}, nil } blessings, err := GoBlessings(env, jBlessings) if err != nil { log.Printf("Couldn't convert Java Blessings to Go Blessings: %v", err) return security.Blessings{}, nil } return blessings, nil }
func (s *blessingStore) Set(blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error) { env, freeFunc := jutil.GetEnv() defer freeFunc() jBlessings, err := JavaBlessings(env, blessings) if err != nil { return security.Blessings{}, err } jForPeers, err := JavaBlessingPattern(env, forPeers) if err != nil { return security.Blessings{}, err } jOldBlessings, err := jutil.CallObjectMethod(env, s.jBlessingStore, "set", []jutil.Sign{blessingsSign, blessingPatternSign}, blessingsSign, jBlessings, jForPeers) if err != nil { return security.Blessings{}, err } return GoBlessings(env, jOldBlessings) }
func (s *signer) PublicKey() security.PublicKey { env, freeFunc := jutil.GetEnv() defer freeFunc() publicKeySign := jutil.ClassSign("java.security.interfaces.ECPublicKey") jPublicKey, err := jutil.CallObjectMethod(env, s.jSigner, "publicKey", nil, publicKeySign) if err != nil { log.Printf("Couldn't get Java public key: %v", err) return nil } // Get the encoded version of the public key. encoded, err := jutil.CallByteArrayMethod(env, jPublicKey, "getEncoded", nil) if err != nil { log.Printf("Couldn't get encoded data for Java public key: %v", err) return nil } key, err := security.UnmarshalPublicKey(encoded) if err != nil { log.Printf("Couldn't parse Java ECDSA public key: " + err.Error()) return nil } return key }
//export Java_io_v_impl_google_services_groups_GroupServer_nativeWithNewServer func Java_io_v_impl_google_services_groups_GroupServer_nativeWithNewServer(jenv *C.JNIEnv, jGroupServerClass C.jclass, jContext C.jobject, jGroupServerParams C.jobject) C.jobject { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext))) jParams := jutil.Object(uintptr(unsafe.Pointer(jGroupServerParams))) // Read and translate all of the server params. name, err := jutil.CallStringMethod(env, jParams, "getName", nil) if err != nil { jutil.JThrowV(env, err) return nil } rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil) if err != nil { jutil.JThrowV(env, err) return nil } if rootDir == "" { rootDir = filepath.Join(os.TempDir(), "groupserver") if err := os.Mkdir(rootDir, 0755); err != nil && !os.IsExist(err) { jutil.JThrowV(env, err) return nil } } jEngine, err := jutil.CallObjectMethod(env, jParams, "getStorageEngine", nil, storageEngineSign) if err != nil { jutil.JThrowV(env, err) return nil } engine, err := GoStorageEngine(env, jEngine) if err != nil { jutil.JThrowV(env, err) return nil } // Start the server. ctx, cancel, err := jcontext.GoContext(env, jCtx) if err != nil { jutil.JThrowV(env, err) return nil } dispatcher, err := lib.NewGroupsDispatcher(rootDir, engine) if err != nil { jutil.JThrowV(env, err) return nil } newCtx, s, err := v23.WithNewDispatchingServer(ctx, name, dispatcher) if err != nil { jutil.JThrowV(env, err) return nil } jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel) if err != nil { jutil.JThrowV(env, err) return nil } jServer, err := jrpc.JavaServer(env, s) if err != nil { jutil.JThrowV(env, err) return nil } // Attach a server to the new context. jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer) if err != nil { jutil.JThrowV(env, err) return nil } return C.jobject(unsafe.Pointer(jServerAttCtx)) }
//export Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer func Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer(jenv *C.JNIEnv, jSyncbaseServerClass C.jclass, jContext C.jobject, jSyncbaseServerParams C.jobject) C.jobject { env := jutil.Env(uintptr(unsafe.Pointer(jenv))) jCtx := jutil.Object(uintptr(unsafe.Pointer(jContext))) jParams := jutil.Object(uintptr(unsafe.Pointer(jSyncbaseServerParams))) // Read and translate all of the server params. jPerms, err := jutil.CallObjectMethod(env, jParams, "getPermissions", nil, permissionsSign) if err != nil { jutil.JThrowV(env, err) return nil } perms, err := jaccess.GoPermissions(env, jPerms) if err != nil { jutil.JThrowV(env, err) return nil } name, err := jutil.CallStringMethod(env, jParams, "getName", nil) if err != nil { jutil.JThrowV(env, err) return nil } rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil) if err != nil { jutil.JThrowV(env, err) return nil } if rootDir == "" { rootDir = filepath.Join(os.TempDir(), "syncbaseserver") if err := os.Mkdir(rootDir, 0755); err != nil && !os.IsExist(err) { jutil.JThrowV(env, err) return nil } } jEngine, err := jutil.CallObjectMethod(env, jParams, "getStorageEngine", nil, storageEngineSign) if err != nil { jutil.JThrowV(env, err) return nil } engine, err := GoStorageEngine(env, jEngine) if err != nil { jutil.JThrowV(env, err) return nil } ctx, cancel, err := jcontext.GoContext(env, jCtx) if err != nil { jutil.JThrowV(env, err) return nil } // Create the rpc server before the service so that connections are shared between // clients in the service and the rpc server. (i.e. connections are shared if the // context returned from WithNewDispatchingServer is used for client calls). d := dispatcher.NewDispatcherWrapper() ctx, s, err := v23.WithNewDispatchingServer(ctx, name, d, options.ChannelTimeout(vsync.NeighborConnectionTimeout)) if err != nil { cancel() jutil.JThrowV(env, err) return nil } service, err := server.NewService(ctx, server.ServiceOptions{ Perms: perms, RootDir: rootDir, Engine: engine, }) if err != nil { cancel() jutil.JThrowV(env, err) return nil } // Set the dispatcher in the dispatcher wrapper for the server to start responding // to incoming rpcs. d.SetDispatcher(server.NewDispatcher(service)) if err := service.AddNames(ctx, s); err != nil { cancel() jutil.JThrowV(env, err) return nil } jNewCtx, err := jcontext.JavaContext(env, ctx, cancel) if err != nil { jutil.JThrowV(env, err) return nil } jServer, err := jrpc.JavaServer(env, s) if err != nil { jutil.JThrowV(env, err) return nil } // Attach a server to the new context. jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer) if err != nil { jutil.JThrowV(env, err) return nil } return C.jobject(unsafe.Pointer(jServerAttCtx)) }