예제 #1
0
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
}
예제 #2
0
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.")
	}
}
예제 #3
0
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
}
예제 #4
0
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)
}
예제 #5
0
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
}