Example #1
0
func runListKeys(ctx *context.T, env *cmdline.Env, args []string) error {
	peerBlessings := v23.GetPrincipal(ctx).BlessingStore().PeerBlessings()
	const format = "%-30s   %s (Expires: %s)\n"

	fmt.Printf(format, "Lock", "Key", "<expiry time>")
	for lock, key := range peerBlessings {
		if !isValidLockName(string(lock)) {
			continue
		}
		if !isKeyValidForLock(ctx, key, string(lock)) {
			continue
		}
		var (
			expiresIn string
			now       = time.Now()
		)
		if exp := key.Expiry(); !exp.IsZero() && exp.Before(now) {
			// TODO(ataly): Remove the key from the blessing
			// store.
			continue
		} else if exp.IsZero() {
			expiresIn = "NEVER"
		} else {
			expiresIn = fmt.Sprintf("in %v", exp.Sub(now))
		}
		fmt.Printf(format, lock, key, expiresIn)
	}
	return nil
}
Example #2
0
func startLockServer(ctx *context.T, configDir string) (func(), error) {
	blessings, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	lockNhSuffix := fmt.Sprint(blessings)
	// Start a local mounttable where the lock server would be
	// mounted, and make this mounttable visible in the local
	// neighborhood.
	mtName, stopMT, err := locklib.StartMounttable(ctx, configDir, locklib.LockNhPrefix+lockNhSuffix)
	if err != nil {
		return nil, err
	}
	ctx, _, err = v23.WithNewNamespace(ctx, mtName)
	if err != nil {
		stopMT()
		return nil, err
	}
	ctx, cancel := context.WithCancel(ctx)
	_, server, err := v23.WithNewServer(ctx, lockObjectName(ctx), newLock(), security.DefaultAuthorizer())
	if err != nil {
		stopMT()
		return nil, err
	}
	stopLock := func() {
		cancel()
		vlog.Infof("Stopping lock server...")
		<-server.Closed()
		vlog.Infof("Stopped lock server...")
		stopMT()
	}
	vlog.Infof("Started lock server\n")
	vlog.Infof("ENDPOINT: %v\n", server.Status().Endpoints[0].Name())
	return stopLock, nil
}
Example #3
0
func runClaim(ctx *context.T, env *cmdline.Env, args []string) error {
	if numargs := len(args); numargs != 2 {
		return fmt.Errorf("requires exactly two arguments <lock>, <name>, provided %d", numargs)
	}
	lockName, name := args[0], args[1]

	ctx, stop, err := withLocalNamespace(ctx, "", lockUserNhName(ctx))
	if err != nil {
		return err
	}
	defer stop()

	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	// TODO(ataly): We should not skip server endpoint authorization while
	// claiming locks but instead fetch the blessing root of the lock manufacturer
	// from an authoritative source and then appropriately authenticate the server.
	b, err := lock.UnclaimedLockClient(lockObjName(lockName)).Claim(
		ctx,
		name,
		options.ServerAuthorizer{security.AllowEveryone()})
	if err != nil {
		return err
	}

	p := v23.GetPrincipal(ctx)
	if err := security.AddToRoots(p, b); err != nil {
		return fmt.Errorf("failed to add (key) blessing (%v) to roots: %v", b, err)
	}
	if _, err := p.BlessingStore().Set(b, security.BlessingPattern(name)); err != nil {
		return fmt.Errorf("failed to set (key) blessing (%v) for peer %v: %v", b, name, err)
	}
	fmt.Printf("Claimed lock: %v as %v and received key: %v\n", lockName, name, b)
	return nil
}
Example #4
0
func lockUserNhName(ctx *context.T) string {
	var (
		principal    = v23.GetPrincipal(ctx)
		blessings, _ = principal.BlessingStore().Default()
		bNames       = security.BlessingNames(principal, blessings)
	)
	return lockUserNhPrefix + vUser(bNames...)
}
Example #5
0
func isKeyValidForLock(ctx *context.T, key security.Blessings, lockName string) bool {
	bp := security.BlessingPattern(lockName + security.ChainSeparator + "key")
	for _, b := range security.BlessingNames(v23.GetPrincipal(ctx), key) {
		if bp.MatchedBy(b) {
			return true
		}
	}
	return false
}
Example #6
0
//export swift_io_v_v23_security_simple_nativePublicKey
func swift_io_v_v23_security_simple_nativePublicKey(ctxHandle C.GoContextHandle, errOut *C.SwiftVError) *C.char {
	ctx := context.GoContext(uint64(ctxHandle))
	der, err := v23.GetPrincipal(ctx).PublicKey().MarshalBinary()
	if err != nil {
		util.ThrowSwiftError(nil, err, unsafe.Pointer(errOut))
		return nil
	}
	// Swift will have to free the allocation
	return C.CString(base64.URLEncoding.EncodeToString(der))
}
Example #7
0
func saveKeyForLock(ctx *context.T, key security.Blessings, lockName string) error {
	if isKeyValidForLock(ctx, key, lockName) {
		return fmt.Errorf("key %v is not valid for lock %v", key, lockName)
	}
	p := v23.GetPrincipal(ctx)
	if _, err := p.BlessingStore().Set(key, security.BlessingPattern(lockName)); err != nil {
		return fmt.Errorf("failed to save key %v for lock %v", key, lockName)
	}
	if err := security.AddToRoots(p, key); err != nil {
		return fmt.Errorf("failed to save key %v for lock %v", key, lockName)
	}
	return nil
}
Example #8
0
func (ul *unclaimedLock) Claim(ctx *context.T, call rpc.ServerCall, name string) (security.Blessings, error) {
	vlog.Infof("Claim called by %q", call.Security().RemoteBlessings())
	if strings.ContainsAny(name, security.ChainSeparator) {
		// TODO(ataly, ashankar): We have to error out in this case because of the current
		// neighborhood setup wherein the neighborhood-name of a claimed lock's mounttable is
		// the same as the locks's name. Since neighborhood-names aren't allowed to contain
		// slashes, we have to disallow slashes in the lock name as well.
		return security.Blessings{}, NewErrInvalidLockName(ctx, name, security.ChainSeparator)
	}

	var (
		principal      = v23.GetPrincipal(ctx)
		origDefault, _ = principal.BlessingStore().Default()
		restore        = func() error {
			// TODO(ataly): Remove roots of current default blessing if needed
			// (i.e., if current default != origDefault).
			if err := principal.BlessingStore().SetDefault(origDefault); err != nil {
				return verror.Convert(verror.ErrInternal, ctx, err)
			}
			return nil
		}
	)

	defer ul.mu.Unlock()
	ul.mu.Lock()

	if ul.claimed == nil {
		return security.Blessings{}, NewErrLockAlreadyClaimed(ctx)
	}

	keyBlessing, err := ul.makeKey(principal, name, call.Security().RemoteBlessings().PublicKey())
	if err != nil {
		restore()
		return security.Blessings{}, verror.Convert(verror.ErrInternal, ctx, err)
	}

	// Create a file in the config directory to indicate that lock has been claimed.
	f, err := os.Create(filepath.Join(ul.configDir, claimFileName))
	if err != nil {
		restore()
		return security.Blessings{}, verror.Convert(verror.ErrInternal, ctx, err)
	}
	f.Close()

	close(ul.claimed)
	ul.claimed = nil
	vlog.Infof("Lock successfullly claimed with name %q", name)
	return keyBlessing, nil
}
Example #9
0
//export swift_io_v_v23_security_simple_nativeSetBlessings
func swift_io_v_v23_security_simple_nativeSetBlessings(ctxHandle C.GoContextHandle, encodedSwiftBlessings C.SwiftByteArray, errOut *C.SwiftVError) {
	ctx := context.GoContext(uint64(ctxHandle))
	encodedBlessings := util.GoBytesNoCopy(unsafe.Pointer(&encodedSwiftBlessings))
	var blessings security.Blessings
	if err := vom.Decode(encodedBlessings, &blessings); err != nil {
		ctx.Error("Unable to decode:", err)
		util.ThrowSwiftError(nil, err, unsafe.Pointer(errOut))
		return
	}
	principal := v23.GetPrincipal(ctx)
	if err := principal.BlessingStore().SetDefault(blessings); err != nil {
		util.ThrowSwiftError(nil, err, unsafe.Pointer(errOut))
		return
	}
}
Example #10
0
func keyForLock(ctx *context.T, lockName string) (security.Blessings, error) {
	// We could simply return  v23.GetPrincipal(ctx).BlessingStore().ForPeer(lock)
	// however this would also include any blessings tagged for a peer pattern
	// is matched by 'lock'. Therefore we iterate over all the blessings
	// and pick the specific ones that are meant for 'lock'.
	var ret security.Blessings
	for _, b := range v23.GetPrincipal(ctx).BlessingStore().PeerBlessings() {
		if isKeyValidForLock(ctx, b, lockName) {
			if union, err := security.UnionOfBlessings(ret, b); err != nil {
				vlog.Errorf("UnionOfBlessings(%v, %v) failed: %v, dropping latter blessing", ret, b, err)
			} else {
				ret = union
			}
		}
	}
	if ret.IsZero() {
		return security.Blessings{}, fmt.Errorf("no available key for lock %v", lockName)
	}
	return ret, nil
}
Example #11
0
func (nm *networkManager) run(ready chan<- interface{}, newLeftScreen, newRightScreen chan<- chan<- *spec.Triangle, newInvite chan<- Invitation) {
	defer close(nm.myScreen)
	defer close(newLeftScreen)
	defer close(newRightScreen)
	notifyReady := func(result interface{}) {
		ready <- result
		close(ready)
		ready = nil
	}
	ctx, shutdown := v23.Init()
	defer shutdown()
	ctx, server, err := v23.WithNewServer(ctx, "", spec.ScreenServer(nm), security.AllowEveryone())
	if err != nil {
		notifyReady(err)
		return
	}
	disc, err := v23.NewDiscovery(ctx)
	if err != nil {
		notifyReady(err)
		return
	}
	// Select a color based on some unique identifier of the process, the PublicKey serves as one.
	notifyReady(selectColor(v23.GetPrincipal(ctx).PublicKey()))
	var (
		left     = remoteScreen{myScreen: nm.myScreen, notify: newLeftScreen}
		right    = remoteScreen{myScreen: nm.myScreen, notify: newRightScreen}
		accepted = make(chan string) // Names of remote screens that accepted an invitation
		seek     = make(chan bool)   // Send false to stop seeking invitations from others, true otherwise

		pendingInviterName        string
		pendingInviteUserResponse <-chan error
		pendingInviteRPCResponse  chan<- error
	)
	seekInvites(ctx, disc, server, seek)
	go sendInvites(ctx, disc, accepted)
	for {
		select {
		case invitation := <-nm.inviteRPCs:
			if left.Active() {
				invitation.Response <- fmt.Errorf("thanks for the invite but I'm already engaged with a previous invitation")
				break
			}
			// Defer the response to the user interface.
			ch := make(chan error)
			pendingInviterName = invitation.Name
			pendingInviteRPCResponse = invitation.Response
			pendingInviteUserResponse = ch
			invitation.Response = ch
			newInvite <- invitation
		case err := <-pendingInviteUserResponse:
			pendingInviteRPCResponse <- err
			if err == nil {
				ctx.Infof("Activating left screen %q", pendingInviterName)
				left.Activate(ctx, pendingInviterName)
				seek <- false
			}
			pendingInviterName = ""
			pendingInviteUserResponse = nil
			pendingInviteRPCResponse = nil
		case <-left.Lost():
			ctx.Infof("Deactivating left screen")
			left.Deactivate()
			seek <- true
		case invitee := <-accepted:
			ctx.Infof("Activating right screen %q", invitee)
			right.Activate(ctx, invitee)
		case <-right.Lost():
			ctx.Infof("Deactivating right screen")
			right.Deactivate()
			go sendInvites(ctx, disc, accepted)
		case <-ctx.Done():
			return
		}
	}
}
Example #12
0
//export swift_io_v_v23_security_simple_nativeBlessingsDebugString
func swift_io_v_v23_security_simple_nativeBlessingsDebugString(ctxHandle C.GoContextHandle) *C.char {
	ctx := context.GoContext(uint64(ctxHandle))
	blessings, _ := v23.GetPrincipal(ctx).BlessingStore().Default()
	return C.CString(fmt.Sprintf("%v", blessings))
}