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