// 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 }
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 }
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() }
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) }
// 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 }
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 }
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 }
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 }
// 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 }
// 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 }
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 }
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") }
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 }
// 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 }
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) }
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() }
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()) }
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 }