// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The following enables go generate to generate the doc.go file.
//go:generate go run $VANADIUM_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .

package main

import (
	"bytes"
	"crypto/rand"
	"crypto/subtle"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/user"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/options"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/vom"
	"v.io/x/lib/cmdline"
	_ "v.io/x/ref/profiles/static"
	vsecurity "v.io/x/ref/security"
)

var (
	// Flags for the "blessself" command
	flagBlessSelfCaveats caveatsFlag
	flagBlessSelfFor     time.Duration

	// Flags for the "bless" command
	flagBlessCaveats        caveatsFlag
	flagBlessFor            time.Duration
	flagBlessRequireCaveats bool
	flagBlessWith           string
	flagBlessRemoteKey      string
	flagBlessRemoteToken    string

	// Flags for the "fork" command
	flagForkCaveats        caveatsFlag
	flagForkFor            time.Duration
	flagForkRequireCaveats bool
	flagForkWith           string

	// Flags for the "seekblessings" command
	flagSeekBlessingsFrom       string
	flagSeekBlessingsSetDefault bool
	flagSeekBlessingsForPeer    string
	flagSeekBlessingsBrowser    bool

	// Flags common to many commands
	flagAddToRoots      bool
	flagCreateOverwrite bool
	flagRemoteArgFile   string

	// Flags for the "recvblessings" command
	flagRecvBlessingsSetDefault bool
	flagRecvBlessingsForPeer    string

	errNoCaveats = fmt.Errorf("no caveats provided: it is generally dangerous to bless another principal without any caveats as that gives them almost unrestricted access to the blesser's credentials. If you really want to do this, set --require-caveats=false")
	cmdDump      = &cmdline.Command{
		Name:  "dump",
		Short: "Dump out information about the principal",
		Long: `
Prints out information about the principal specified by the environment
that this tool is running in.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			ctx, shutdown := v23.Init()
			defer shutdown()

			p := v23.GetPrincipal(ctx)
			fmt.Printf("Public key : %v\n", p.PublicKey())
			fmt.Println("---------------- BlessingStore ----------------")
			fmt.Printf("%v", p.BlessingStore().DebugString())
			fmt.Println("---------------- BlessingRoots ----------------")
			fmt.Printf("%v", p.Roots().DebugString())
			return nil
		},
	}

	cmdDumpBlessings = &cmdline.Command{
		Name:  "dumpblessings",
		Short: "Dump out information about the provided blessings",
		Long: `
Prints out information about the blessings (typically obtained from this tool)
encoded in the provided file.
`,
		ArgsName: "<file>",
		ArgsLong: `
<file> is the path to a file containing blessings typically obtained from
this tool. - is used for STDIN.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(args) != 1 {
				return fmt.Errorf("requires exactly one argument, <file>, provided %d", len(args))
			}
			blessings, err := decodeBlessings(args[0])
			if err != nil {
				return fmt.Errorf("failed to decode provided blessings: %v", err)
			}
			wire, err := blessings2wire(blessings)
			if err != nil {
				return fmt.Errorf("failed to decode certificate chains: %v", err)
			}
			fmt.Printf("Blessings          : %v\n", blessings)
			fmt.Printf("PublicKey          : %v\n", blessings.PublicKey())
			fmt.Printf("Certificate chains : %d\n", len(wire.CertificateChains))
			for idx, chain := range wire.CertificateChains {
				fmt.Printf("Chain #%d (%d certificates). Root certificate public key: %v\n", idx, len(chain), rootkey(chain))
				for certidx, cert := range chain {
					fmt.Printf("  Certificate #%d: %v with ", certidx, cert.Extension)
					switch n := len(cert.Caveats); n {
					case 1:
						fmt.Printf("1 caveat")
					default:
						fmt.Printf("%d caveats", n)
					}
					fmt.Println("")
					for cavidx, cav := range cert.Caveats {
						fmt.Printf("    (%d) %v\n", cavidx, &cav)
					}
				}
			}
			return nil
		},
	}

	cmdBlessSelf = &cmdline.Command{
		Name:  "blessself",
		Short: "Generate a self-signed blessing",
		Long: `
Returns a blessing with name <name> and self-signed by the principal specified
by the environment that this tool is running in. Optionally, the blessing can
be restricted with an expiry caveat specified using the --for flag. Additional
caveats can be added with the --caveat flag.
`,
		ArgsName: "[<name>]",
		ArgsLong: `
<name> is the name used to create the self-signed blessing. If not
specified, a name will be generated based on the hostname of the
machine and the name of the user running this command.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			var name string
			switch len(args) {
			case 0:
				name = defaultBlessingName()
			case 1:
				name = args[0]
			default:
				return fmt.Errorf("requires at most one argument, provided %d", len(args))
			}

			caveats, err := caveatsFromFlags(flagBlessSelfFor, &flagBlessSelfCaveats)
			if err != nil {
				return err
			}
			ctx, shutdown := v23.Init()
			defer shutdown()
			principal := v23.GetPrincipal(ctx)
			blessing, err := principal.BlessSelf(name, caveats...)
			if err != nil {
				return fmt.Errorf("failed to create self-signed blessing for name %q: %v", name, err)
			}

			return dumpBlessings(blessing)
		},
	}

	cmdBless = &cmdline.Command{
		Name:  "bless",
		Short: "Bless another principal",
		Long: `
Bless another principal.

The blesser is obtained from the runtime this tool is using. The blessing that
will be extended is the default one from the blesser's store, or specified by
the --with flag. Expiration on the blessing are controlled via the --for flag.
Additional caveats are controlled with the --caveat flag.

For example, let's say a principal "alice" wants to bless another principal "bob"
as "alice/friend", the invocation would be:
    V23_CREDENTIALS=<path to alice> principal bless <path to bob> friend
and this will dump the blessing to STDOUT.

With the --remote-key and --remote-token flags, this command can be used to
bless a principal on a remote machine as well. In this case, the blessing is
not dumped to STDOUT but sent to the remote end. Use 'principal help
recvblessings' for more details on that.

When --remote-arg-file is specified, only the blessing extension is required, as all other
arguments will be extracted from the specified file.
`,
		ArgsName: "[<principal to bless>] <extension>",
		ArgsLong: `
<principal to bless> represents the principal to be blessed (i.e., whose public
key will be provided with a name).  This can be either:
(a) The directory containing credentials for that principal,
OR
(b) The filename (- for STDIN) containing any other blessings of that
    principal,
OR
(c) The object name produced by the 'recvblessings' command of this tool
    running on behalf of another principal (if the --remote-key and
    --remote-token flags are specified).
OR
(d) None (if the --remote-arg-file flag is specified, only <extension> should be provided
    to bless).

<extension> is the string extension that will be applied to create the
blessing.

	`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(flagRemoteArgFile) > 0 && len(args) != 1 {
				return fmt.Errorf("when --remote-arg-file is provided, only <extension> is expected, provided %d", len(args))
			} else if len(flagRemoteArgFile) == 0 && len(args) != 2 {
				return fmt.Errorf("require exactly two arguments when --remote-arg-file is not provided, provided %d", len(args))
			}

			ctx, shutdown := v23.Init()
			defer shutdown()

			p := v23.GetPrincipal(ctx)

			var (
				err  error
				with security.Blessings
			)
			if len(flagBlessWith) > 0 {
				if with, err = decodeBlessings(flagBlessWith); err != nil {
					return fmt.Errorf("failed to read blessings from --with=%q: %v", flagBlessWith, err)
				}
			} else {
				with = p.BlessingStore().Default()
			}
			caveats, err := caveatsFromFlags(flagBlessFor, &flagBlessCaveats)
			if err != nil {
				return err
			}
			if !flagBlessRequireCaveats && len(caveats) == 0 {
				caveats = []security.Caveat{security.UnconstrainedUse()}
			}
			if len(caveats) == 0 {
				return errNoCaveats
			}

			tobless, extension, remoteKey, remoteToken, err := blessArgs(args)
			if err != nil {
				return err
			}

			// Send blessings to a "server" started by a "recvblessings" command, either
			// with the --remote-arg-file flag, or with --remote-key and --remote-token flags.
			if len(remoteKey) > 0 {
				granter := &granter{p, with, extension, caveats, remoteKey}
				return blessOverNetwork(ctx, tobless, granter, remoteToken)
			}

			// Blessing a principal whose key is available locally.
			blessings, err := blessOverFileSystem(p, tobless, with, extension, caveats)
			if err != nil {
				return err
			}
			return dumpBlessings(blessings)
		},
	}

	cmdGetForPeer = &cmdline.Command{
		Name:  "forpeer",
		Short: "Return blessings marked for the provided peer",
		Long: `
Returns blessings that are marked for the provided peer in the
BlessingStore specified by the environment that this tool is
running in.
`,
		ArgsName: "[<peer_1> ... <peer_k>]",
		ArgsLong: `
<peer_1> ... <peer_k> are the (human-readable string) blessings bound
to the peer. The returned blessings are marked with a pattern that is
matched by at least one of these. If no arguments are specified,
store.forpeer returns the blessings that are marked for all peers (i.e.,
blessings set on the store with the "..." pattern).
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			ctx, shutdown := v23.Init()
			defer shutdown()
			principal := v23.GetPrincipal(ctx)
			return dumpBlessings(principal.BlessingStore().ForPeer(args...))
		},
	}

	cmdGetDefault = &cmdline.Command{
		Name:  "default",
		Short: "Return blessings marked as default",
		Long: `
Returns blessings that are marked as default in the BlessingStore specified by
the environment that this tool is running in.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			ctx, shutdown := v23.Init()
			defer shutdown()
			principal := v23.GetPrincipal(ctx)
			return dumpBlessings(principal.BlessingStore().Default())
		},
	}

	cmdSetForPeer = &cmdline.Command{
		Name:  "forpeer",
		Short: "Set provided blessings for peer",
		Long: `
Marks the provided blessings to be shared with the provided peers on the
BlessingStore specified by the environment that this tool is running in.

'set b pattern' marks the intention to reveal b to peers who
present blessings of their own matching 'pattern'.

'set nil pattern' can be used to remove the blessings previously
associated with the pattern (by a prior 'set' command).

It is an error to call 'set forpeer' with blessings whose public
key does not match the public key of this principal specified
by the environment.
`,
		ArgsName: "<file> <pattern>",
		ArgsLong: `
<file> is the path to a file containing a blessing typically obtained
from this tool. - is used for STDIN.

<pattern> is the BlessingPattern used to identify peers with whom this
blessing can be shared with.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(args) != 2 {
				return fmt.Errorf("requires exactly two arguments <file>, <pattern>, provided %d", len(args))
			}
			blessings, err := decodeBlessings(args[0])
			if err != nil {
				return fmt.Errorf("failed to decode provided blessings: %v", err)
			}
			pattern := security.BlessingPattern(args[1])

			ctx, shutdown := v23.Init()
			defer shutdown()

			p := v23.GetPrincipal(ctx)
			if _, err := p.BlessingStore().Set(blessings, pattern); err != nil {
				return fmt.Errorf("failed to set blessings %v for peers %v: %v", blessings, pattern, err)
			}
			if flagAddToRoots {
				if err := p.AddToRoots(blessings); err != nil {
					return fmt.Errorf("AddToRoots failed: %v", err)
				}
			}
			return nil
		},
	}

	cmdAddToRoots = &cmdline.Command{
		Name:  "addtoroots",
		Short: "Add to the set of identity providers recognized by this principal",
		Long: `
Adds an identity provider to the set of recognized roots public keys for this principal.

It accepts either a single argument (which points to a file containing a blessing)
or two arguments (a name and a base64-encoded DER-encoded public key).

For example, to make the principal in credentials directory A recognize the
root of the default blessing in credentials directory B:
  principal -v23.credentials=B bless A some_extension |
  principal -v23.credentials=A addtoroots -
The extension 'some_extension' has no effect in the command above.

Or to make the principal in credentials director A recognize the base64-encoded
public key KEY for blessing patterns P:
  principal -v23.credentials=A addtoroots KEY P
`,
		ArgsName: "<key|blessing> [<blessing pattern>]",
		ArgsLong: `
<blessing> is the path to a file containing a blessing typically obtained from
this tool. - is used for STDIN.

<key> is a base64-encoded, DER-encoded public key.

<blessing pattern> is the blessing pattern for which <key> should be recognized.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(args) != 1 && len(args) != 2 {
				return fmt.Errorf("requires either one argument <file>, or two arguments <key> <blessing pattern>, provided %d", len(args))
			}
			ctx, shutdown := v23.Init()
			defer shutdown()

			p := v23.GetPrincipal(ctx)
			if len(args) == 1 {
				blessings, err := decodeBlessings(args[0])
				if err != nil {
					return fmt.Errorf("failed to decode provided blessings: %v", err)
				}
				if err := p.AddToRoots(blessings); err != nil {
					return fmt.Errorf("AddToRoots failed: %v", err)
				}
				return nil
			}
			// len(args) == 2
			der, err := base64.URLEncoding.DecodeString(args[0])
			if err != nil {
				return fmt.Errorf("invalid base64 encoding of public key: %v", err)
			}
			key, err := security.UnmarshalPublicKey(der)
			if err != nil {
				return fmt.Errorf("invalid DER encoding of public key: %v", err)
			}
			return p.Roots().Add(key, security.BlessingPattern(args[1]))
		},
	}

	cmdSetDefault = &cmdline.Command{
		Name:  "default",
		Short: "Set provided blessings as default",
		Long: `
Sets the provided blessings as default in the BlessingStore specified by the
environment that this tool is running in.

It is an error to call 'set default' with blessings whose public key does
not match the public key of the principal specified by the environment.
`,
		ArgsName: "<file>",
		ArgsLong: `
<file> is the path to a file containing a blessing typically obtained from
this tool. - is used for STDIN.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(args) != 1 {
				return fmt.Errorf("requires exactly one argument, <file>, provided %d", len(args))
			}
			blessings, err := decodeBlessings(args[0])
			if err != nil {
				return fmt.Errorf("failed to decode provided blessings: %v", err)
			}

			ctx, shutdown := v23.Init()
			defer shutdown()

			p := v23.GetPrincipal(ctx)
			if err := p.BlessingStore().SetDefault(blessings); err != nil {
				return fmt.Errorf("failed to set blessings %v as default: %v", blessings, err)
			}
			if flagAddToRoots {
				if err := p.AddToRoots(blessings); err != nil {
					return fmt.Errorf("AddToRoots failed: %v", err)
				}
			}
			return nil
		},
	}

	cmdCreate = &cmdline.Command{
		Name:  "create",
		Short: "Create a new principal and persist it into a directory",
		Long: `
Creates a new principal with a single self-blessed blessing and writes it out
to the provided directory. The same directory can then be used to set the
V23_CREDENTIALS environment variable for other vanadium applications.

The operation fails if the directory already contains a principal. In this case
the --overwrite flag can be provided to clear the directory and write out the
new principal.
`,
		ArgsName: "<directory> <blessing>",
		ArgsLong: `
	<directory> is the directory to which the new principal will be persisted.
	<blessing> is the self-blessed blessing that the principal will be setup to use by default.
	`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(args) != 2 {
				return fmt.Errorf("requires exactly two arguments: <directory> and <blessing>, provided %d", len(args))
			}
			dir, name := args[0], args[1]
			if flagCreateOverwrite {
				if err := os.RemoveAll(dir); err != nil {
					return err
				}
			}
			p, err := vsecurity.CreatePersistentPrincipal(dir, nil)
			if err != nil {
				return err
			}
			blessings, err := p.BlessSelf(name)
			if err != nil {
				return fmt.Errorf("BlessSelf(%q) failed: %v", name, err)
			}
			if err := vsecurity.SetDefaultBlessings(p, blessings); err != nil {
				return fmt.Errorf("could not set blessings %v as default: %v", blessings, err)
			}
			return nil
		},
	}

	cmdFork = &cmdline.Command{
		Name:  "fork",
		Short: "Fork a new principal from the principal that this tool is running as and persist it into a directory",
		Long: `
Creates a new principal with a blessing from the principal specified by the
environment that this tool is running in, and writes it out to the provided
directory. The blessing that will be extended is the default one from the
blesser's store, or specified by the --with flag. Expiration on the blessing
are controlled via the --for flag. Additional caveats on the blessing are
controlled with the --caveat flag. The blessing is marked as default and
shareable with all peers on the new principal's blessing store.

The operation fails if the directory already contains a principal. In this case
the --overwrite flag can be provided to clear the directory and write out the
forked principal.
`,
		ArgsName: "<directory> <extension>",
		ArgsLong: `
	<directory> is the directory to which the forked principal will be persisted.
	<extension> is the extension under which the forked principal is blessed.
	`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(args) != 2 {
				return fmt.Errorf("requires exactly two arguments: <directory> and <extension>, provided %d", len(args))
			}
			dir, extension := args[0], args[1]

			ctx, shutdown := v23.Init()
			defer shutdown()

			caveats, err := caveatsFromFlags(flagForkFor, &flagForkCaveats)
			if err != nil {
				return err
			}
			if !flagForkRequireCaveats && len(caveats) == 0 {
				caveats = []security.Caveat{security.UnconstrainedUse()}
			}
			if len(caveats) == 0 {
				return errNoCaveats
			}
			var with security.Blessings
			if len(flagForkWith) > 0 {
				if with, err = decodeBlessings(flagForkWith); err != nil {
					return fmt.Errorf("failed to read blessings from --with=%q: %v", flagForkWith, err)
				}
			} else {
				with = v23.GetPrincipal(ctx).BlessingStore().Default()
			}

			if flagCreateOverwrite {
				if err := os.RemoveAll(dir); err != nil {
					return err
				}
			}
			p, err := vsecurity.CreatePersistentPrincipal(dir, nil)
			if err != nil {
				return err
			}

			key := p.PublicKey()
			rp := v23.GetPrincipal(ctx)
			blessings, err := rp.Bless(key, with, extension, caveats[0], caveats[1:]...)
			if err != nil {
				return fmt.Errorf("Bless(%v, %v, %q, ...) failed: %v", key, with, extension, err)
			}
			if err := vsecurity.SetDefaultBlessings(p, blessings); err != nil {
				return fmt.Errorf("could not set blessings %v as default: %v", blessings, err)
			}
			return nil
		},
	}

	cmdSeekBlessings = &cmdline.Command{
		Name:  "seekblessings",
		Short: "Seek blessings from a web-based Vanadium blessing service",
		Long: `
Seeks blessings from a web-based Vanadium blesser which
requires the caller to first authenticate with Google using OAuth. Simply
run the command to see what happens.

The blessings are sought for the principal specified by the environment that
this tool is running in.

The blessings obtained are set as default, unless the --set-default flag is
set to true, and are also set for sharing with all peers, unless a more
specific peer pattern is provided using the --for-peer flag.
`,
		Run: func(cmd *cmdline.Command, args []string) error {
			// Initialize the runtime first so that any local errors are reported
			// before the HTTP roundtrips for obtaining the macaroon begin.
			ctx, shutdown := v23.Init()
			defer shutdown()

			blessedChan := make(chan string)
			defer close(blessedChan)
			macaroonChan, err := getMacaroonForBlessRPC(flagSeekBlessingsFrom, blessedChan, flagSeekBlessingsBrowser)
			if err != nil {
				return fmt.Errorf("failed to get macaroon from Vanadium blesser: %v", err)
			}

			blessings, err := exchangeMacaroonForBlessing(ctx, macaroonChan)
			if err != nil {
				return err
			}
			blessedChan <- fmt.Sprint(blessings)
			// Wait for getTokenForBlessRPC to clean up:
			<-macaroonChan

			p := v23.GetPrincipal(ctx)

			if flagSeekBlessingsSetDefault {
				if err := p.BlessingStore().SetDefault(blessings); err != nil {
					return fmt.Errorf("failed to set blessings %v as default: %v", blessings, err)
				}
			}
			if pattern := security.BlessingPattern(flagSeekBlessingsForPeer); len(pattern) > 0 {
				if _, err := p.BlessingStore().Set(blessings, pattern); err != nil {
					return fmt.Errorf("failed to set blessings %v for peers %v: %v", blessings, pattern, err)
				}
			}
			if flagAddToRoots {
				if err := p.AddToRoots(blessings); err != nil {
					return fmt.Errorf("AddToRoots failed: %v", err)
				}
			}
			fmt.Fprintf(cmd.Stdout(), "Received blessings: %v\n", blessings)
			return nil
		},
	}

	cmdRecvBlessings = &cmdline.Command{
		Name:  "recvblessings",
		Short: "Receive blessings sent by another principal and use them as the default",
		Long: `
Allow another principal (likely a remote process) to bless this one.

This command sets up the invoker (this process) to wait for a blessing
from another invocation of this tool (remote process) and prints out the
command to be run as the remote principal.

The received blessings are set as default, unless the --set-default flag is
set to true, and are also set for sharing with all peers, unless a more
specific peer pattern is provided using the --for-peer flag.

TODO(ashankar,cnicolaou): Make this next paragraph possible! Requires
the ability to obtain the proxied endpoint.

Typically, this command should require no arguments.
However, if the sender and receiver are on different network domains, it may
make sense to use the --v23.proxy flag:
    principal --v23.proxy=proxy recvblessings

The command to be run at the sender is of the form:
    principal bless --remote-key=KEY --remote-token=TOKEN ADDRESS EXTENSION

The --remote-key flag is used to by the sender to "authenticate" the receiver,
ensuring it blesses the intended recipient and not any attacker that may have
taken over the address.

The --remote-token flag is used by the sender to authenticate itself to the
receiver. This helps ensure that the receiver rejects blessings from senders
who just happened to guess the network address of the 'recvblessings'
invocation.

If the --remote-arg-file flag is provided to recvblessings, the remote key, remote token
and object address of this principal will be written to the specified location.
This file can be supplied to bless:
		principal bless --remote-arg-file FILE EXTENSION

`,
		Run: func(cmd *cmdline.Command, args []string) error {
			if len(args) != 0 {
				return fmt.Errorf("command accepts no arguments")
			}

			ctx, shutdown := v23.Init()
			defer shutdown()

			server, err := v23.NewServer(ctx)
			if err != nil {
				return fmt.Errorf("failed to create server to listen for blessings: %v", err)
			}
			defer server.Stop()
			eps, err := server.Listen(v23.GetListenSpec(ctx))
			if err != nil {
				return fmt.Errorf("failed to setup listening: %v", err)
			}
			var token [24]byte
			if _, err := rand.Read(token[:]); err != nil {
				return fmt.Errorf("unable to generate token: %v", err)
			}

			p := v23.GetPrincipal(ctx)
			service := &recvBlessingsService{
				principal: p,
				token:     base64.URLEncoding.EncodeToString(token[:]),
				notify:    make(chan error),
			}
			if err := server.Serve("", service, allowAnyone{}); err != nil {
				return fmt.Errorf("failed to setup service: %v", err)
			}
			// Proposed name:
			extension := fmt.Sprintf("extension%d", int(token[0])<<16|int(token[1])<<8|int(token[2]))
			fmt.Println("Run the following command on behalf of the principal that will send blessings:")
			fmt.Println("You may want to adjust flags affecting the caveats on this blessing, for example using")
			fmt.Println("the --for flag, or change the extension to something more meaningful")
			fmt.Println()
			if len(flagRemoteArgFile) > 0 {
				if err := writeRecvBlessingsInfo(flagRemoteArgFile, p.PublicKey().String(), service.token, eps[0].Name()); err != nil {
					return fmt.Errorf("failed to write recvblessings info to %v: %v", flagRemoteArgFile, err)
				}
				fmt.Printf("make %q accessible to the blesser, possibly by copying the file over and then run:\n", flagRemoteArgFile)
				fmt.Printf("principal bless --remote-arg-file=%v %v", flagRemoteArgFile, extension)
			} else {
				fmt.Printf("principal bless --remote-key=%v --remote-token=%v %v %v\n", p.PublicKey(), service.token, eps[0].Name(), extension)
			}
			fmt.Println()
			fmt.Println("...waiting for sender..")
			return <-service.notify
		},
	}
)

func blessArgs(args []string) (tobless, extension, remoteKey, remoteToken string, err error) {
	if len(flagRemoteArgFile) > 0 && (len(flagBlessRemoteKey)+len(flagBlessRemoteToken) > 0) {
		return "", "", "", "", fmt.Errorf("--remote-key and --remote-token cannot be provided with --remote-arg-file")
	}
	if (len(flagBlessRemoteKey) == 0) != (len(flagBlessRemoteToken) == 0) {
		return "", "", "", "", fmt.Errorf("either both --remote-key and --remote-token should be set, or neither should")
	}

	if len(flagRemoteArgFile) == 0 {
		tobless, extension = args[0], args[1]
		remoteKey = flagBlessRemoteKey
		remoteToken = flagBlessRemoteToken
	} else if len(flagRemoteArgFile) > 0 {
		extension = args[0]
		remoteKey, remoteToken, tobless, err = blessArgsFromFile(flagRemoteArgFile)
	}
	return
}

func blessOverFileSystem(p security.Principal, tobless string, with security.Blessings, extension string, caveats []security.Caveat) (security.Blessings, error) {
	var key security.PublicKey
	if finfo, err := os.Stat(tobless); err == nil && finfo.IsDir() {
		other, err := vsecurity.LoadPersistentPrincipal(tobless, nil)
		if err != nil {
			if other, err = vsecurity.CreatePersistentPrincipal(tobless, nil); err != nil {
				return security.Blessings{}, fmt.Errorf("failed to read principal in directory %q: %v", tobless, err)
			}
		}
		key = other.PublicKey()
	} else if other, err := decodeBlessings(tobless); err != nil {
		return security.Blessings{}, fmt.Errorf("failed to decode blessings in %q: %v", tobless, err)
	} else {
		key = other.PublicKey()
	}
	return p.Bless(key, with, extension, caveats[0], caveats[1:]...)
}

type recvBlessingsInfo struct {
	RemoteKey   string `json:remote_key`
	RemoteToken string `json:remote_token`
	Name        string `json:name`
}

func writeRecvBlessingsInfo(fname string, remoteKey, remoteToken, name string) error {
	f, err := os.OpenFile(fname, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		return err
	}
	b, err := json.Marshal(recvBlessingsInfo{remoteKey, remoteToken, name})
	if err != nil {
		return err
	}
	if _, err := f.Write(b); err != nil {
		return err
	}
	return nil
}

func blessArgsFromFile(fname string) (remoteKey, remoteToken, tobless string, err error) {
	blessJSON, err := ioutil.ReadFile(fname)
	if err != nil {
		return "", "", "", err
	}
	var binfo recvBlessingsInfo
	if err := json.Unmarshal(blessJSON, &binfo); err != nil {
		return "", "", "", err
	}
	return binfo.RemoteKey, binfo.RemoteToken, binfo.Name, err
}

func main() {
	cmdBlessSelf.Flags.Var(&flagBlessSelfCaveats, "caveat", flagBlessSelfCaveats.usage())
	cmdBlessSelf.Flags.DurationVar(&flagBlessSelfFor, "for", 0, "Duration of blessing validity (zero implies no expiration)")

	cmdFork.Flags.BoolVar(&flagCreateOverwrite, "overwrite", false, "If true, any existing principal data in the directory will be overwritten")
	cmdFork.Flags.Var(&flagForkCaveats, "caveat", flagForkCaveats.usage())
	cmdFork.Flags.DurationVar(&flagForkFor, "for", 0, "Duration of blessing validity (zero implies no expiration caveat)")
	cmdFork.Flags.BoolVar(&flagForkRequireCaveats, "require-caveats", true, "If false, allow blessing without any caveats. This is typically not advised as the principal wielding the blessing will be almost as powerful as its blesser")
	cmdFork.Flags.StringVar(&flagForkWith, "with", "", "Path to file containing blessing to extend")

	cmdBless.Flags.Var(&flagBlessCaveats, "caveat", flagBlessCaveats.usage())
	cmdBless.Flags.DurationVar(&flagBlessFor, "for", 0, "Duration of blessing validity (zero implies no expiration caveat)")
	cmdBless.Flags.BoolVar(&flagBlessRequireCaveats, "require-caveats", true, "If false, allow blessing without any caveats. This is typically not advised as the principal wielding the blessing will be almost as powerful as its blesser")
	cmdBless.Flags.StringVar(&flagBlessWith, "with", "", "Path to file containing blessing to extend")
	cmdBless.Flags.StringVar(&flagBlessRemoteKey, "remote-key", "", "Public key of the remote principal to bless (obtained from the 'recvblessings' command run by the remote principal")
	cmdBless.Flags.StringVar(&flagBlessRemoteToken, "remote-token", "", "Token provided by principal running the 'recvblessings' command")
	cmdBless.Flags.StringVar(&flagRemoteArgFile, "remote-arg-file", "", "File containing bless arguments written by 'principal recvblessings -remote-arg-file FILE EXTENSION' command. This can be provided to bless in place of --remote-key, --remote-token, and <principal>.")

	cmdSeekBlessings.Flags.StringVar(&flagSeekBlessingsFrom, "from", "https://dev.v.io/auth/google", "URL to use to begin the seek blessings process")
	cmdSeekBlessings.Flags.BoolVar(&flagSeekBlessingsSetDefault, "set-default", true, "If true, the blessings obtained will be set as the default blessing in the store")
	cmdSeekBlessings.Flags.StringVar(&flagSeekBlessingsForPeer, "for-peer", string(security.AllPrincipals), "If non-empty, the blessings obtained will be marked for peers matching this pattern in the store")
	cmdSeekBlessings.Flags.BoolVar(&flagSeekBlessingsBrowser, "browser", true, "If false, the seekblessings command will not open the browser and only print the url to visit.")
	cmdSeekBlessings.Flags.BoolVar(&flagAddToRoots, "add-to-roots", true, "If true, the root certificate of the blessing will be added to the principal's set of recognized root certificates")

	cmdSetForPeer.Flags.BoolVar(&flagAddToRoots, "add-to-roots", true, "If true, the root certificate of the blessing will be added to the principal's set of recognized root certificates")

	cmdSetDefault.Flags.BoolVar(&flagAddToRoots, "add-to-roots", true, "If true, the root certificate of the blessing will be added to the principal's set of recognized root certificates")

	cmdCreate.Flags.BoolVar(&flagCreateOverwrite, "overwrite", false, "If true, any existing principal data in the directory will be overwritten")

	cmdRecvBlessings.Flags.BoolVar(&flagRecvBlessingsSetDefault, "set-default", true, "If true, the blessings received will be set as the default blessing in the store")
	cmdRecvBlessings.Flags.StringVar(&flagRecvBlessingsForPeer, "for-peer", string(security.AllPrincipals), "If non-empty, the blessings received will be marked for peers matching this pattern in the store")
	cmdRecvBlessings.Flags.StringVar(&flagRemoteArgFile, "remote-arg-file", "", "If non-empty, the remote key, remote token, and principal will be written to the specified file in a JSON object. This can be provided to 'principal bless --remote-arg-file FILE EXTENSION'.")

	cmdSet := &cmdline.Command{
		Name:  "set",
		Short: "Mutate the principal's blessings.",
		Long: `
Commands to mutate the blessings of the principal.

All input blessings are expected to be serialized using base64-VOM-encoding.
See 'principal get'.
`,
		Children: []*cmdline.Command{cmdSetDefault, cmdSetForPeer},
	}

	cmdGet := &cmdline.Command{
		Name:  "get",
		Short: "Read the principal's blessings.",
		Long: `
Commands to inspect the blessings of the principal.

All blessings are printed to stdout using base64-VOM-encoding.
`,
		Children: []*cmdline.Command{cmdGetDefault, cmdGetForPeer},
	}

	root := &cmdline.Command{
		Name:  "principal",
		Short: "Create and manage vanadium principals",
		Long: `
The principal tool helps create and manage blessings and the set of trusted
roots bound to a principal.

All objects are printed using base64-VOM-encoding.
`,
		Children: []*cmdline.Command{cmdCreate, cmdFork, cmdSeekBlessings, cmdRecvBlessings, cmdDump, cmdDumpBlessings, cmdBlessSelf, cmdBless, cmdSet, cmdGet, cmdAddToRoots},
	}
	os.Exit(root.Main())
}

func decodeBlessings(fname string) (security.Blessings, error) {
	var b security.Blessings
	err := decode(fname, &b)
	return b, err
}

func dumpBlessings(blessings security.Blessings) error {
	if blessings.IsZero() {
		return fmt.Errorf("no blessings found")
	}
	str, err := base64VomEncode(blessings)
	if err != nil {
		return fmt.Errorf("base64-VOM encoding failed: %v", err)
	}
	fmt.Println(str)
	return nil
}

func read(fname string) (string, error) {
	if len(fname) == 0 {
		return "", nil
	}
	f := os.Stdin
	if fname != "-" {
		var err error
		if f, err = os.Open(fname); err != nil {
			return "", fmt.Errorf("failed to open %q: %v", fname, err)
		}
	}
	defer f.Close()
	var buf bytes.Buffer
	if _, err := io.Copy(&buf, f); err != nil {
		return "", fmt.Errorf("failed to read %q: %v", fname, err)
	}
	return buf.String(), nil
}

func decode(fname string, val interface{}) error {
	str, err := read(fname)
	if err != nil {
		return err
	}
	if err := base64VomDecode(str, val); err != nil || val == nil {
		return fmt.Errorf("failed to decode %q: %v", fname, err)
	}
	return nil
}

func defaultBlessingName() string {
	var name string
	if user, _ := user.Current(); user != nil && len(user.Username) > 0 {
		name = user.Username
	} else {
		name = "anonymous"
	}
	if host, _ := os.Hostname(); len(host) > 0 {
		name = name + "@" + host
	}
	return name
}

func rootkey(chain []security.Certificate) string {
	if len(chain) == 0 {
		return "<empty certificate chain>"
	}
	key, err := security.UnmarshalPublicKey(chain[0].PublicKey)
	if err != nil {
		return fmt.Sprintf("<invalid PublicKey: %v>", err)
	}
	return fmt.Sprintf("%v", key)
}

func base64VomEncode(i interface{}) (string, error) {
	buf := &bytes.Buffer{}
	closer := base64.NewEncoder(base64.URLEncoding, buf)
	enc, err := vom.NewEncoder(closer)
	if err != nil {
		return "", err
	}
	if err := enc.Encode(i); err != nil {
		return "", err
	}
	// Must close the base64 encoder to flush out any partially written
	// blocks.
	if err := closer.Close(); err != nil {
		return "", err
	}
	return buf.String(), nil
}

func base64VomDecode(s string, i interface{}) error {
	b, err := base64.URLEncoding.DecodeString(s)
	if err != nil {
		return err
	}
	dec, err := vom.NewDecoder(bytes.NewBuffer(b))
	if err != nil {
		return err
	}
	return dec.Decode(i)
}

type recvBlessingsService struct {
	principal security.Principal
	notify    chan error
	token     string
}

func (r *recvBlessingsService) Grant(call rpc.StreamServerCall, token string) error {
	b := call.GrantedBlessings()
	if b.IsZero() {
		return fmt.Errorf("no blessings granted by sender")
	}
	if len(token) != len(r.token) {
		// A timing attack can be used to figure out the length
		// of the token, but then again, so can looking at the
		// source code. So, it's okay.
		return fmt.Errorf("blessings received from unexpected sender")
	}
	if subtle.ConstantTimeCompare([]byte(token), []byte(r.token)) != 1 {
		return fmt.Errorf("blessings received from unexpected sender")
	}
	if flagRecvBlessingsSetDefault {
		if err := r.principal.BlessingStore().SetDefault(b); err != nil {
			return fmt.Errorf("failed to set blessings %v as default: %v", b, err)
		}
	}
	if pattern := security.BlessingPattern(flagRecvBlessingsForPeer); len(pattern) > 0 {
		if _, err := r.principal.BlessingStore().Set(b, pattern); err != nil {
			return fmt.Errorf("failed to set blessings %v for peers %v: %v", b, pattern, err)
		}
	}
	if flagAddToRoots {
		if err := r.principal.AddToRoots(b); err != nil {
			return fmt.Errorf("failed to add blessings to recognized roots: %v", err)
		}
	}
	fmt.Println("Received blessings:", b)
	r.notify <- nil
	return nil
}

type allowAnyone struct{}

func (allowAnyone) Authorize(*context.T) error { return nil }

type granter struct {
	p         security.Principal
	with      security.Blessings
	extension string
	caveats   []security.Caveat
	serverKey string
}

func (g *granter) Grant(server security.Blessings) (security.Blessings, error) {
	if got := fmt.Sprintf("%v", server.PublicKey()); got != g.serverKey {
		// If the granter returns an error, the RPC framework should
		// abort the RPC before sending the request to the server.
		// Thus, there is no concern about leaking the token to an
		// imposter server.
		return security.Blessings{}, fmt.Errorf("key mismatch: Remote end has public key %v, want %v", got, g.serverKey)
	}
	return g.p.Bless(server.PublicKey(), g.with, g.extension, g.caveats[0], g.caveats[1:]...)
}
func (*granter) RPCCallOpt() {}

func blessOverNetwork(ctx *context.T, object string, granter *granter, remoteToken string) error {
	client := v23.GetClient(ctx)
	// The receiver is being authorized based on the hash of its public key
	// (see Grant), so it should be fine to ignore the blessing names in the endpoint
	// (which are likely to not be recognized by the sender anyway).
	//
	// At worst, there is a privacy leak of the senders intent to send some
	// blessings.  That could be addressed by making the full public key of
	// the recipeint available to the sender and using
	// options.ServerPublicKey instead of providing a "hash" of the
	// recipients public key and verifying in the Granter implementation.
	call, err := client.StartCall(ctx, object, "Grant", []interface{}{remoteToken}, granter, options.SkipServerEndpointAuthorization{})
	if err != nil {
		return fmt.Errorf("failed to start RPC to %q: %v", object, err)
	}
	if err := call.Finish(); err != nil {
		return fmt.Errorf("failed to finish RPC to %q: %v", object, err)
	}
	return nil
}

func caveatsFromFlags(expiry time.Duration, caveatsFlag *caveatsFlag) ([]security.Caveat, error) {
	caveats, err := caveatsFlag.Compile()
	if err != nil {
		return nil, fmt.Errorf("failed to parse caveats: %v", err)
	}
	if expiry > 0 {
		ecav, err := security.ExpiryCaveat(time.Now().Add(expiry))
		if err != nil {
			return nil, fmt.Errorf("failed to create expiration caveat: %v", err)
		}
		caveats = append(caveats, ecav)
	}
	return caveats, nil
}

// Circuitous route to get to the certificate chains.
// See comments on why security.MarshalBlessings is discouraged.
// Though, a better alternative is worth looking into.
func blessings2wire(b security.Blessings) (security.WireBlessings, error) {
	var wire security.WireBlessings
	data, err := vom.Encode(b)
	if err != nil {
		return wire, err
	}
	err = vom.Decode(data, &wire)
	return wire, err
}
