func createGpgClient(tc libkb.TestContext) *libkb.GpgCLI { gpgClient := libkb.NewGpgCLI(tc.G, tc.G.UI.GetLogUI()) err := gpgClient.Configure() if err != nil { tc.T.Fatal("Error while configuring gpg client.") } return gpgClient }
func TestPGPUpdate(t *testing.T) { tc := SetupEngineTest(t, "pgp_update") defer tc.Cleanup() // Note that this user's key is not created in the GPG keyring. For the // purposes of this test that's ok. fakeUser := createFakeUserWithPGPSibkey(tc) bundle := getFakeUsersKeyBundleFromServer(tc, fakeUser) if len(bundle.Subkeys) != 1 { t.Fatal("expected exactly 1 subkey") } originalBundlesLen := len(getFakeUsersBundlesList(tc, fakeUser)) // Modify the key by deleting the subkey. bundle.Subkeys = []openpgp.Subkey{} gpgCLI := libkb.NewGpgCLI(libkb.GpgCLIArg{ LogUI: tc.G.UI.GetLogUI(), }) err := gpgCLI.Configure() if err != nil { t.Fatal("Error initializing GpgCLI", err) } // Add the modified key to the gpg keyring if err := gpgCLI.ExportKey(*bundle); err != nil { t.Fatal(err) } // Now run `client pgp update` with a fingerprint that doesn't match. err = doUpdate([]string{"not_a_real_fingerprint"}, false, fakeUser, tc) if err != nil { t.Fatal("Error in PGPUpdateEngine:", err) } // Get the list of bundles from the server. bundles := getFakeUsersBundlesList(tc, fakeUser) // Check that the key hasn't been modified. if len(bundles) != originalBundlesLen { t.Fatal("Key changes should not have been uploaded.") } // Do the same thing without the fingerprint. It should go through this time. err = doUpdate([]string{}, false, fakeUser, tc) if err != nil { t.Fatal("Error in PGPUpdateEngine:", err) } // Load the user from the server again. reloadedBundles := getFakeUsersBundlesList(tc, fakeUser) // Check that the key hasn't been modified. if len(reloadedBundles) != originalBundlesLen+1 { t.Fatal("Key changes should have been uploaded.") } }
func (e *PGPPullEngine) Run(ctx *Context) error { summaries, err := e.getTrackedUserSummaries(ctx) if err != nil { return err } gpgClient := libkb.NewGpgCLI(libkb.GpgCLIArg{ LogUI: ctx.LogUI, }) err = gpgClient.Configure() if err != nil { return err } // Loop over the list of all users we track. for _, userSummary := range summaries { // Compute the set of tracked pgp fingerprints. LoadUser will fetch key // data from the server, and we will compare it against this. trackedFingerprints := make(map[string]bool) for _, pubKey := range userSummary.Proofs.PublicKeys { if pubKey.PGPFingerprint != "" { trackedFingerprints[pubKey.PGPFingerprint] = true } } // Get user data from the server. user, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(e.G(), userSummary.Username)) if err != nil { ctx.LogUI.Errorf("Failed to load user %s: %s", userSummary.Username, err) continue } for _, bundle := range user.GetActivePGPKeys(false) { // Check each key against the tracked set. if !trackedFingerprints[bundle.GetFingerprint().String()] { ctx.LogUI.Warning("Keybase says that %s owns key %s, but you have not tracked this fingerprint before.", user.GetName(), bundle.GetFingerprint()) continue } err = gpgClient.ExportKey(*bundle) if err != nil { return err } ctx.LogUI.Info("Imported key for %s.", user.GetName()) } } return nil }
func (e *PGPPullEngine) Run(ctx *Context) error { e.gpgClient = libkb.NewGpgCLI(e.G(), ctx.LogUI) err := e.gpgClient.Configure() if err != nil { return err } if ok, _, _ := IsLoggedIn(e, ctx); !ok { return e.runLoggedOut(ctx) } summaries, err := e.getTrackedUserSummaries(ctx) if err != nil { return err } return e.runLoggedIn(ctx, summaries) }
func (e *PGPUpdateEngine) Run(ctx *Context) error { if e.all && len(e.selectedFingerprints) > 0 { return fmt.Errorf("Cannot use explicit fingerprints with --all.") } me, err := libkb.LoadMe(libkb.NewLoadUserArg(e.G())) if err != nil { return err } fingerprints := me.GetActivePGPFingerprints(false /* not just sibkeys */) if len(fingerprints) > 1 && !e.all && len(e.selectedFingerprints) == 0 { return fmt.Errorf("You have more than one PGP key. To update all of them, use --all.") } gpgCLI := libkb.NewGpgCLI(libkb.GpgCLIArg{ LogUI: ctx.LogUI, }) err = gpgCLI.Configure() if err != nil { return err } del := libkb.Delegator{ DelegationType: libkb.PGPUpdateType, Me: me, Expire: libkb.KeyExpireIn, Contextified: libkb.NewContextified(e.G()), } err = del.LoadSigningKey(ctx.LoginContext, ctx.SecretUI) if err != nil { return err } for _, fingerprint := range fingerprints { if len(e.selectedFingerprints) > 0 && !e.selectedFingerprints[fingerprint.String()] { ctx.LogUI.Warning("Skipping update for key %s", fingerprint.String()) continue } bundle, err := gpgCLI.ImportKey(false /* secret */, fingerprint) if err != nil { _, isNoKey := err.(libkb.NoKeyError) if isNoKey { ctx.LogUI.Warning( "No key matching fingerprint %s found in the GPG keyring.", fingerprint.String()) continue } else { return err } } del.NewKey = bundle ctx.LogUI.Info("Posting update for key %s.", fingerprint.String()) if err := del.Run(ctx.LoginContext); err != nil { if appStatusErr, ok := err.(libkb.AppStatusError); ok && appStatusErr.Code == libkb.SCKeyDuplicateUpdate { ctx.LogUI.Info("Key was already up to date.") e.duplicatedFingerprints = append(e.duplicatedFingerprints, fingerprint) continue } return err } ctx.LogUI.Info("Update succeeded for key %s.", fingerprint) } return nil }