github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/engine/pgp_update.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package engine 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/keybase/client/go/libkb" 11 ) 12 13 type PGPUpdateEngine struct { 14 selectedFingerprints map[string]bool 15 all bool 16 duplicatedFingerprints []libkb.PGPFingerprint 17 libkb.Contextified 18 } 19 20 func NewPGPUpdateEngine(g *libkb.GlobalContext, fingerprints []string, all bool) *PGPUpdateEngine { 21 selectedFingerprints := make(map[string]bool) 22 for _, fpString := range fingerprints { 23 selectedFingerprints[strings.ToLower(fpString)] = true 24 } 25 return &PGPUpdateEngine{ 26 selectedFingerprints: selectedFingerprints, 27 all: all, 28 Contextified: libkb.NewContextified(g), 29 } 30 } 31 32 func (e *PGPUpdateEngine) Name() string { 33 return "PGPUpdate" 34 } 35 36 func (e *PGPUpdateEngine) Prereqs() Prereqs { 37 return Prereqs{ 38 Device: true, 39 } 40 } 41 42 func (e *PGPUpdateEngine) RequiredUIs() []libkb.UIKind { 43 return []libkb.UIKind{ 44 libkb.LogUIKind, 45 libkb.SecretUIKind, 46 } 47 } 48 49 func (e *PGPUpdateEngine) SubConsumers() []libkb.UIConsumer { 50 return []libkb.UIConsumer{} 51 } 52 53 func (e *PGPUpdateEngine) Run(m libkb.MetaContext) error { 54 if e.all && len(e.selectedFingerprints) > 0 { 55 return fmt.Errorf("Cannot use explicit fingerprints with --all.") 56 } 57 58 me, err := libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m)) 59 if err != nil { 60 return err 61 } 62 fingerprints := me.GetActivePGPFingerprints(false /* not just sibkeys */) 63 if len(fingerprints) > 1 && !e.all && len(e.selectedFingerprints) == 0 { 64 return fmt.Errorf("You have more than one PGP key. To update all of them, use --all.") 65 } 66 67 gpgCLI := libkb.NewGpgCLI(m.G(), m.UIs().LogUI) 68 err = gpgCLI.Configure(m) 69 if err != nil { 70 return err 71 } 72 73 del := libkb.Delegator{ 74 DelegationType: libkb.DelegationTypePGPUpdate, 75 Me: me, 76 Expire: libkb.KeyExpireIn, 77 Contextified: libkb.NewContextified(e.G()), 78 } 79 80 err = del.LoadSigningKey(m, m.UIs().SecretUI) 81 if err != nil { 82 return err 83 } 84 85 for _, fingerprint := range fingerprints { 86 if len(e.selectedFingerprints) > 0 && !e.selectedFingerprints[fingerprint.String()] { 87 m.UIs().LogUI.Warning("Skipping update for key %s", fingerprint.String()) 88 continue 89 } 90 bundle, err := gpgCLI.ImportKey(m, false /* secret */, fingerprint, "") 91 if err != nil { 92 _, isNoKey := err.(libkb.NoKeyError) 93 if isNoKey { 94 m.UIs().LogUI.Warning( 95 "No key matching fingerprint %s found in the GPG keyring.", 96 fingerprint.String()) 97 continue 98 } else { 99 return err 100 } 101 } 102 103 bundle.InitGPGKey() 104 del.NewKey = bundle 105 106 m.UIs().LogUI.Info("Posting update for key %s.", fingerprint.String()) 107 if err := del.Run(m); err != nil { 108 if appStatusErr, ok := err.(libkb.AppStatusError); ok && appStatusErr.Code == libkb.SCKeyDuplicateUpdate { 109 m.UIs().LogUI.Info("Key was already up to date.") 110 e.duplicatedFingerprints = append(e.duplicatedFingerprints, fingerprint) 111 continue 112 } 113 return err 114 } 115 m.UIs().LogUI.Info("Update succeeded for key %s.", fingerprint) 116 } 117 return nil 118 }