Exemple #1
0
// This is used by SaltpackDecrypt as well.
func getPaperKey(g *libkb.GlobalContext, ctx *Context) (*keypair, error) {
	passphrase, err := libkb.GetPaperKeyPassphrase(g, ctx.SecretUI, "")
	if err != nil {
		return nil, err
	}

	paperPhrase, err := libkb.NewPaperKeyPhraseCheckVersion(g, passphrase)
	if err != nil {
		return nil, err
	}

	bkarg := &PaperKeyGenArg{
		Passphrase: paperPhrase,
		SkipPush:   true,
	}
	bkeng := NewPaperKeyGen(bkarg, g)
	if err := RunEngine(bkeng, ctx); err != nil {
		return nil, err
	}

	kp := &keypair{sigKey: bkeng.SigKey(), encKey: bkeng.EncKey()}
	if err := g.LoginState().Account(func(a *libkb.Account) {
		a.SetUnlockedPaperKey(kp.sigKey, kp.encKey)
	}, "UnlockedPaperKey"); err != nil {
		return nil, err
	}

	return kp, nil
}
Exemple #2
0
func getUserCard(g *libkb.GlobalContext, uid keybase1.UID, useSession bool) (ret *keybase1.UserCard, err error) {
	defer g.Trace("getUserCard", func() error { return err })()

	arg := libkb.APIArg{
		Endpoint:     "user/card",
		NeedSession:  useSession,
		Contextified: libkb.NewContextified(g),
		Args:         libkb.HTTPArgs{"uid": libkb.S{Val: uid.String()}},
	}

	var card card

	if err = g.API.GetDecode(arg, &card); err != nil {
		g.Log.Warning("error getting user/card for %s: %s\n", uid, err)
		return nil, err
	}

	g.Log.Debug("user card: %+v", card)

	ret = &keybase1.UserCard{
		Following:     card.FollowSummary.Following,
		Followers:     card.FollowSummary.Followers,
		Uid:           uid,
		FullName:      card.Profile.FullName,
		Location:      card.Profile.Location,
		Bio:           card.Profile.Bio,
		Website:       card.Profile.Website,
		Twitter:       card.Profile.Twitter,
		YouFollowThem: card.YouFollowThem,
		TheyFollowYou: card.TheyFollowYou,
	}
	return ret, nil
}
Exemple #3
0
func mainInner(g *libkb.GlobalContext) error {
	cl := libcmdline.NewCommandLine(true, client.GetExtraFlags())
	cl.AddCommands(client.GetCommands(cl, g))
	cl.AddCommands(service.GetCommands(cl, g))
	cl.AddHelpTopics(client.GetHelpTopics())

	var err error
	cmd, err = cl.Parse(os.Args)
	if err != nil {
		err = fmt.Errorf("Error parsing command line arguments: %s\n", err)
		return err
	}

	if cmd == nil {
		return nil
	}

	if !cl.IsService() {
		client.InitUI()
	}

	if err = g.ConfigureCommand(cl, cmd); err != nil {
		return err
	}
	g.StartupMessage()

	warnNonProd(g.Log, g.Env)

	if err = configureProcesses(g, cl, &cmd); err != nil {
		return err
	}

	return cmd.Run()
}
Exemple #4
0
func getMySecretKey(
	g *libkb.GlobalContext, secretUI libkb.SecretUI,
	secretKeyType libkb.SecretKeyType, reason string) (
	libkb.GenericKey, error) {

	var key libkb.GenericKey
	var err error
	aerr := g.LoginState().Account(func(a *libkb.Account) {
		key, err = a.CachedSecretKey(libkb.SecretKeyArg{KeyType: secretKeyType})
	}, "Keyrings - cachedSecretKey")
	if key != nil && err == nil {
		return key, nil
	}
	if aerr != nil {
		g.Log.Debug("error getting account: %s", aerr)
	}

	me, err := libkb.LoadMe(libkb.NewLoadUserArg(g))
	if err != nil {
		return nil, err
	}

	arg := libkb.SecretKeyPromptArg{
		Ska: libkb.SecretKeyArg{
			Me:      me,
			KeyType: secretKeyType,
		},
		SecretUI:       secretUI,
		Reason:         reason,
		UseCancelCache: true,
	}
	return g.Keyrings.GetSecretKeyWithPrompt(arg)
}
Exemple #5
0
// check cached keys for arg.Bundles match.
func matchingCachedKey(g *libkb.GlobalContext, arg keybase1.UnboxBytes32AnyArg) (key libkb.GenericKey, index int, err error) {
	err = g.LoginState().Account(func(a *libkb.Account) {
		// check device key first
		dkey, err := a.CachedSecretKey(libkb.SecretKeyArg{KeyType: libkb.DeviceEncryptionKeyType})
		if err == nil {
			if n, ok := kidMatch(dkey, arg.Bundles); ok {
				key = dkey
				index = n
				return
			}
		}

		// check paper key
		pkey := a.GetUnlockedPaperEncKey()
		if n, ok := kidMatch(pkey, arg.Bundles); ok {
			key = pkey
			index = n
			return
		}
	}, "UnboxBytes32Any")
	if err != nil {
		return nil, 0, err
	}
	if key != nil {
		return key, index, nil
	}

	return nil, 0, nil
}
Exemple #6
0
func CurrentUID(g *libkb.GlobalContext) (keybase1.UID, error) {
	var loggedIn bool
	var err error
	var uid keybase1.UID
	aerr := g.LoginState().Account(func(a *libkb.Account) {
		loggedIn, err = a.LoggedInProvisionedLoad()
		if err != nil {
			return
		}
		if !loggedIn {
			return
		}
		uid = a.LocalSession().GetUID()
	}, "Service - SessionHandler - CurrentUID")
	if aerr != nil {
		return uid, aerr
	}
	if err != nil {
		return uid, err
	}
	if !loggedIn {
		return uid, libkb.LoginRequiredError{}
	}
	return uid, nil
}
Exemple #7
0
func getSocket(g *libkb.GlobalContext, clearError bool) (xp rpc.Transporter, err error) {
	var isNew bool
	_, xp, isNew, err = g.GetSocket(clearError)
	if err == nil && isNew {
		introduceMyself(g, xp)
	}
	return xp, err
}
Exemple #8
0
func GetRPCServer(g *libkb.GlobalContext) (ret *rpc.Server, xp rpc.Transporter, err error) {
	if _, xp, err = g.GetSocket(false); err == nil {
		ret = rpc.NewServer(xp, libkb.WrapError)
	}
	if err != nil {
		DiagnoseSocketError(g.UI, err)
	}
	return
}
Exemple #9
0
// check all the user's paper keys for arg.Bundles match
func matchingPaperKey(g *libkb.GlobalContext, secretUI libkb.SecretUI, arg keybase1.UnboxBytes32AnyArg, me *libkb.User) (key libkb.GenericKey, index int, err error) {
	cki := me.GetComputedKeyInfos()
	if cki == nil {
		return nil, 0, nil
	}
	var matchingPaper []*libkb.Device
	for _, pdev := range cki.PaperDevices() {
		enckey, err := me.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(pdev.ID)
		if err != nil {
			return nil, 0, err
		}
		if _, ok := kidMatch(enckey, arg.Bundles); ok {
			g.Log.Debug("matching paper key: %s", *pdev.Description)
			matchingPaper = append(matchingPaper, pdev)
		}
	}
	if len(matchingPaper) == 0 {
		g.Log.Debug("no matching paper keys found")
		return nil, 0, nil
	}

	phrase, err := libkb.GetPaperKeyForCryptoPassphrase(secretUI, arg.Reason, matchingPaper)
	if err != nil {
		return nil, 0, err
	}
	paperPhrase, err := libkb.NewPaperKeyPhraseCheckVersion(g, phrase)
	if err != nil {
		return nil, 0, err
	}

	bkarg := &PaperKeyGenArg{
		Passphrase: paperPhrase,
		SkipPush:   true,
	}
	bkeng := NewPaperKeyGen(bkarg, g)
	if err := RunEngine(bkeng, &Context{}); err != nil {
		return nil, 0, err
	}

	// find the index for the key they entered (and make sure the key they entered matches)
	if n, ok := kidMatch(bkeng.EncKey(), arg.Bundles); ok {

		// this key matches, so cache this paper key
		if err := g.LoginState().Account(func(a *libkb.Account) {
			a.SetUnlockedPaperKey(bkeng.SigKey(), bkeng.EncKey())
		}, "UnboxBytes32Any - cache paper key"); err != nil {
			return nil, 0, err
		}

		return bkeng.EncKey(), n, nil
	}

	return nil, 0, nil
}
func numPrivateGPGKeys(g *libkb.GlobalContext) (int, error) {
	gpg := g.GetGpgClient()
	if err := gpg.Configure(); err != nil {
		return 0, err
	}

	index, _, err := gpg.Index(true, "")
	if err != nil {
		return 0, err
	}

	return index.Len(), nil
}
Exemple #11
0
// NewScanKeys creates a ScanKeys type.  If there is a login
// session, it will load the pgp keys for that user.
func NewScanKeys(secui libkb.SecretUI, idui libkb.IdentifyUI, opts *keybase1.TrackOptions, g *libkb.GlobalContext) (*ScanKeys, error) {
	sk := &ScanKeys{
		secui:        secui,
		idui:         idui,
		opts:         opts,
		Contextified: libkb.NewContextified(g),
	}
	var err error

	g.Log.Debug("+ NewScanKeys")
	defer func() {
		g.Log.Debug("- NewScanKeys -> %s", err)
	}()

	lin, err := g.LoginState().LoggedInLoad()
	if err != nil {
		return nil, err
	}
	if !lin {
		return sk, nil
	}

	// logged in:

	sk.me, err = libkb.LoadMe(libkb.NewLoadUserArg(sk.G()))
	if err != nil {
		return nil, fmt.Errorf("loadme error: %s", err)
	}

	// if user provided, then load their local keys, and their synced secret key:
	synced, err := sk.me.GetSyncedSecretKey()
	if err != nil {
		return nil, fmt.Errorf("getsyncedsecret err: %s", err)
	}

	aerr := sk.G().LoginState().Account(func(a *libkb.Account) {
		var ring *libkb.SKBKeyringFile
		ring, err = a.Keyring()
		if err != nil {
			return
		}
		err = sk.coalesceBlocks(ring, synced)
	}, "NewScanKeys - coalesceBlocks")
	if aerr != nil {
		return nil, err
	}
	if err != nil {
		return nil, err
	}
	return sk, nil
}
Exemple #12
0
func pingLoop(g *libkb.GlobalContext) error {
	var err error
	for i := 0; i < 10; i++ {
		_, _, err = g.GetSocket(true)
		if err == nil {
			g.Log.Debug("Connected (%d)", i)
			return nil
		}
		g.Log.Debug("Failed to connect to socket (%d): %s", i, err)
		err = nil
		time.Sleep(200 * time.Millisecond)
	}
	return nil
}
Exemple #13
0
func testConfigGet(t *testing.T, g *libkb.GlobalContext, path string, stdout []string, stderr []string, wantErr bool) {
	ctui := configTestUI{}
	g.SetUI(&ctui)
	get := client.NewCmdConfigGetRunner(g)
	get.Path = path
	err := get.Run()
	if wantErr && err == nil {
		t.Fatal("Expected an error")
	}
	if !wantErr && err != nil {
		t.Fatalf("Wanted no error, but got: %v", err)
	}
	compareLists(t, stderr, ctui.stderr, "standard error")
	compareLists(t, stdout, ctui.stdout, "standard output")
}
Exemple #14
0
func mainInner(g *libkb.GlobalContext) error {
	cl := libcmdline.NewCommandLine(true, client.GetExtraFlags())
	cl.AddCommands(client.GetCommands(cl, g))
	cl.AddCommands(service.GetCommands(cl, g))
	cl.AddHelpTopics(client.GetHelpTopics())

	var err error
	cmd, err = cl.Parse(os.Args)
	if err != nil {
		err = fmt.Errorf("Error parsing command line arguments: %s\n", err)
		return err
	}

	if cmd == nil {
		return nil
	}

	checkSystemUser(g.Log)

	if !cl.IsService() {
		client.InitUI()
	}

	if err = g.ConfigureCommand(cl, cmd); err != nil {
		return err
	}
	g.StartupMessage()

	warnNonProd(g.Log, g.Env)

	if err = configureProcesses(g, cl, &cmd); err != nil {
		return err
	}

	// Install hook for after startup
	install.RunAfterStartup(g, cl.IsService(), g.Log)

	err = cmd.Run()
	if !cl.IsService() {
		// Errors that come up in printing this warning are logged but ignored.
		client.PrintOutOfDateWarnings(g)
	}
	return err
}
Exemple #15
0
// UnboxBytes32Any will decrypt any of the KID, ciphertext, nonce
// bundles in arg.Bundles.  Key preference order:  cached device keys,
// cached paper keys, local device key, user-entered paper key.
// It returns the KID and bundle index along with the plaintext.
func UnboxBytes32Any(g *libkb.GlobalContext, secretUI libkb.SecretUI, arg keybase1.UnboxBytes32AnyArg) (res keybase1.UnboxAnyRes, err error) {
	defer g.Trace("UnboxBytes32Any", func() error { return err })

	// find a matching secret key for a bundle in arg.Bundles
	key, index, err := getMatchingSecretKey(g, secretUI, arg)
	if err != nil {
		return res, err
	}

	// decrypt the bundle's ciphertext
	plaintext, err := unboxBytes32(key, arg.Bundles[index].Ciphertext, arg.Bundles[index].Nonce, arg.Bundles[index].PublicKey)
	if err != nil {
		return res, err
	}

	// return plaintext, kid, and index
	res.Plaintext = plaintext
	res.Kid = key.GetKID()
	res.Index = index

	return res, nil
}
Exemple #16
0
func getMySecretKey(g *libkb.GlobalContext, getSecretUI func() libkb.SecretUI, secretKeyType libkb.SecretKeyType, reason string) (libkb.GenericKey, error) {

	g.Log.Debug("getMySecretKey: acquiring lock")
	getKeyMu.Lock()
	defer func() {
		getKeyMu.Unlock()
		g.Log.Debug("getMySecretKey: lock released")
	}()
	g.Log.Debug("getMySecretKey: lock acquired")

	// check cache after acquiring lock
	var key libkb.GenericKey
	var err error
	aerr := g.LoginState().Account(func(a *libkb.Account) {
		key, err = a.CachedSecretKey(libkb.SecretKeyArg{KeyType: secretKeyType})
	}, "Keyrings - cachedSecretKey")
	if key != nil && err == nil {
		return key, nil
	}
	if aerr != nil {
		g.Log.Debug("error getting account: %s", aerr)
	}

	me, err := libkb.LoadMe(libkb.NewLoadUserArg(g))
	if err != nil {
		return nil, err
	}

	arg := libkb.SecretKeyPromptArg{
		Ska: libkb.SecretKeyArg{
			Me:      me,
			KeyType: secretKeyType,
		},
		SecretUI:       getSecretUI(),
		Reason:         reason,
		UseCancelCache: true,
	}
	return g.Keyrings.GetSecretKeyWithPrompt(arg)
}
Exemple #17
0
func mainInner(g *libkb.GlobalContext) error {
	cl := libcmdline.NewCommandLine(true, client.GetExtraFlags())
	cl.AddCommands(client.GetCommands(cl, g))
	cl.AddCommands(service.GetCommands(cl, g))
	cl.AddHelpTopics(client.GetHelpTopics())

	var err error
	cmd, err = cl.Parse(os.Args)
	if err != nil {
		err = fmt.Errorf("Error parsing command line arguments: %s\n", err)
		return err
	}

	if cmd == nil {
		return nil
	}

	if !cl.IsService() {
		client.InitUI()
	}

	if err = g.ConfigureCommand(cl, cmd); err != nil {
		return err
	}
	g.StartupMessage()

	warnNonProd(g.Log, g.Env)

	if cl.IsService() {
		return cmd.Run()
	}

	// Start the server on the other end, possibly.
	// There are two cases in which we do this: (1) we want
	// a local loopback server in standalone mode; (2) we
	// need to "autofork" it. Do at most one of these
	// operations.
	if g.Env.GetStandalone() {
		if cl.IsNoStandalone() {
			return fmt.Errorf("Can't run command in standalone mode")
		}
		if err := service.NewService(false /* isDaemon */, g).StartLoopbackServer(); err != nil {
			if pflerr, ok := err.(libkb.PIDFileLockError); ok {
				err = fmt.Errorf("Can't run in standalone mode with a service running (see %q)",
					pflerr.Filename)
			}
			return err
		}
	} else {
		// If this command warrants an autofork, do it now.
		if fc := cl.GetForkCmd(); fc == libcmdline.ForceFork || (g.Env.GetAutoFork() && fc != libcmdline.NoFork) {
			if err = client.ForkServer(cl, g); err != nil {
				return err
			}
		}
		// Whether or not we autoforked, we're now running in client-server
		// mode (as opposed to standalone). Register a global LogUI so that
		// calls to G.Log() in the daemon can be copied to us. This is
		// something of a hack on the daemon side.
		if !g.Env.GetDoLogForward() {
			g.Log.Debug("Disabling log forwarding")
		} else {
			// TODO This triggers a connection to the RPC server before cmd.Run() is
			// called, so the command has no way to deal with errors on its own.
			// This should probably be moved into RegisterProtocols?
			// Also rpc.RegisterProtocolsWithContext seems to automatically add the
			// LogUIProtocol?
			err := registerGlobalLogUI(g)
			if err != nil {
				return err
			}
		}
	}

	return cmd.Run()
}
Exemple #18
0
func introduceMyself(g *libkb.GlobalContext, xp rpc.Transporter) error {
	cli := rpc.NewClient(xp, libkb.ErrorUnwrapper{})
	ccli := keybase1.ConfigClient{Cli: cli}
	return ccli.HelloIAm(context.TODO(), g.GetMyClientDetails())
}
Exemple #19
0
func GetRPCClientWithContext(g *libkb.GlobalContext) (ret *rpc.Client, xp rpc.Transporter, err error) {
	if _, xp, err = g.GetSocket(false); err == nil {
		ret = rpc.NewClient(xp, libkb.ErrorUnwrapper{})
	}
	return
}