github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/identify_state.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 libkb 5 6 import ( 7 "github.com/keybase/client/go/gregor" 8 keybase1 "github.com/keybase/client/go/protocol/keybase1" 9 ) 10 11 type IdentifyState struct { 12 Contextified 13 res *IdentifyOutcome 14 u *User 15 track *TrackLookup 16 tmpTrack *TrackLookup 17 } 18 19 func NewIdentifyStateWithGregorItem(g *GlobalContext, item gregor.Item, u *User) IdentifyState { 20 res := NewIdentifyOutcome(g, u.GetNormalizedName(), u.GetUID(), u.GetCurrentEldestSeqno()) 21 res.ResponsibleGregorItem = item 22 return IdentifyState{Contextified: NewContextified(g), res: res, u: u} 23 } 24 25 func (s *IdentifyState) SetTrackLookup(t *TrackChainLink) { 26 s.track = NewTrackLookup(s.G(), t) 27 if s.res != nil { 28 s.res.TrackUsed = s.track 29 } 30 } 31 32 func (s *IdentifyState) SetTmpTrackLookup(t *TrackChainLink) { 33 s.tmpTrack = NewTrackLookup(s.G(), t) 34 } 35 36 func (s *IdentifyState) TrackLookup() *TrackLookup { 37 return s.track 38 } 39 40 func (s *IdentifyState) HasPreviousTrack() bool { 41 return s.track != nil 42 } 43 44 func (s *IdentifyState) Result() *IdentifyOutcome { 45 return s.res 46 } 47 48 func (s *IdentifyState) TmpTrackLookup() *TrackLookup { 49 return s.tmpTrack 50 } 51 52 func (s *IdentifyState) computeRevokedProofs(rhook func(TrackIDComponent, TrackDiff)) { 53 if s.track == nil { 54 return 55 } 56 57 found := s.res.TrackSet() 58 59 tracked := s.track.set 60 61 // These are the proofs that user previously tracked that 62 // are not in the current profile: 63 diff := tracked.Subtract(*found) 64 65 for _, e := range diff { 66 if e.GetProofState() != keybase1.ProofState_OK { 67 continue 68 } 69 70 // A proof that was previously tracked as GOOD 71 // is missing, so it has been REVOKED. 72 revokedDetail := ExportTrackIDComponentToRevokedProof(e) 73 var td TrackDiff 74 if s.tmpTrack == nil { 75 td = &TrackDiffRevoked{e} 76 } else { 77 // There is a snoozed track in s.tmpTrack. 78 // The user could have snoozed the revoked proof already. 79 // Check s.tmpTrack to see if that is the case. 80 if s.tmpTrack.set.HasMember(e) { 81 // proof was in snooze, too, so mark it as revoked. 82 td = &TrackDiffRevoked{e} 83 } else { 84 // proof wasn't in snooze, so revoked proof already snoozed. 85 td = &TrackDiffSnoozedRevoked{e} 86 revokedDetail.Snoozed = true 87 } 88 } 89 if td != nil { 90 s.res.Revoked = append(s.res.Revoked, td) 91 if rhook != nil { 92 rhook(e, td) 93 } 94 } 95 s.res.RevokedDetails = append(s.res.RevokedDetails, revokedDetail) 96 } 97 } 98 99 func (s *IdentifyState) initResultList() { 100 idt := s.u.IDTable() 101 if idt == nil { 102 return 103 } 104 activeProofs := idt.remoteProofLinks.Active() 105 s.res.ProofChecks = make([]*LinkCheckResult, len(activeProofs)) 106 for i, p := range activeProofs { 107 s.res.ProofChecks[i] = &LinkCheckResult{link: p, trackedProofState: keybase1.ProofState_NONE, position: i} 108 } 109 } 110 111 func (s *IdentifyState) computeTrackDiffs() { 112 if s.track == nil { 113 return 114 } 115 116 s.G().Log.Debug("| with tracking %v", s.track.set) 117 for _, c := range s.res.ProofChecks { 118 c.diff = c.link.ComputeTrackDiff(s.track) 119 c.trackedProofState = s.track.GetProofState(c.link.ToIDString()) 120 if s.tmpTrack != nil { 121 c.tmpTrackedProofState = s.tmpTrack.GetProofState(c.link.ToIDString()) 122 c.tmpTrackExpireTime = s.tmpTrack.GetTmpExpireTime() 123 } 124 } 125 } 126 127 func (s *IdentifyState) Precompute(dhook func(keybase1.IdentifyKey) error, rhook func(TrackIDComponent, TrackDiff)) { 128 s.computeKeyDiffs(dhook) 129 s.initResultList() 130 s.computeTrackDiffs() 131 s.computeRevokedProofs(rhook) 132 } 133 134 func (s *IdentifyState) getLastDelegationSig(kid keybase1.KID) (ret keybase1.SigID) { 135 ckf := s.u.GetComputedKeyFamily() 136 if ckf == nil { 137 return ret 138 } 139 cki := ckf.getCkiUnchecked(kid) 140 if cki == nil { 141 return ret 142 } 143 dels := cki.DelegationsList 144 if len(dels) == 0 { 145 return ret 146 } 147 return dels[len(dels)-1].SigID 148 } 149 150 func (s *IdentifyState) computeKeyDiffs(dhook func(keybase1.IdentifyKey) error) { 151 mapify := func(v []keybase1.KID) map[keybase1.KID]bool { 152 ret := make(map[keybase1.KID]bool) 153 for _, k := range v { 154 ret[k] = true 155 } 156 return ret 157 } 158 159 display := func(kid keybase1.KID, diff TrackDiff) { 160 k := keybase1.IdentifyKey{ 161 TrackDiff: ExportTrackDiff(diff), 162 } 163 k.KID = kid 164 if fp, ok := s.u.GetKeyFamily().kid2pgp[kid]; ok { 165 k.PGPFingerprint = fp[:] 166 } 167 168 // Get the last signature chronologically that delegated to 169 // this key. 170 k.SigID = s.getLastDelegationSig(kid) 171 172 // Anything other than a no difference here should be displayed to 173 // the user. 174 if diff != nil { 175 k.BreaksTracking = diff.BreaksTracking() 176 } 177 err := dhook(k) 178 if err != nil { 179 s.G().Log.Debug("computeKeyDiffs: dhook error: %+v", err) 180 } 181 } 182 183 // first check the eldest key 184 observedEldest := s.u.GetEldestKID() 185 if s.track != nil { 186 trackedEldest := s.track.GetEldestKID() 187 if observedEldest.NotEqual(trackedEldest) || 188 s.u.GetCurrentEldestSeqno() > s.track.GetTrackedLinkSeqno() { 189 diff := TrackDiffNewEldest{tracked: trackedEldest, observed: observedEldest} 190 s.res.KeyDiffs = append(s.res.KeyDiffs, diff) 191 display(observedEldest, diff) 192 } 193 } 194 195 found := s.u.GetActivePGPKIDs(true) 196 foundMap := mapify(found) 197 var tracked []keybase1.KID 198 if s.track != nil { 199 for _, trackedKey := range s.track.GetTrackedKeys() { 200 tracked = append(tracked, trackedKey.KID) 201 } 202 } 203 trackedMap := mapify(tracked) 204 205 for _, kid := range found { 206 var diff TrackDiff 207 if s.track != nil && !trackedMap[kid] { 208 diff = TrackDiffNew{} 209 s.res.KeyDiffs = append(s.res.KeyDiffs, diff) 210 } else if s.track != nil { 211 diff = TrackDiffNone{} 212 } 213 display(kid, diff) 214 } 215 216 for _, kid := range tracked { 217 if !foundMap[kid] { 218 fp := s.u.GetKeyFamily().kid2pgp[kid] 219 diff := TrackDiffRevoked{fp} 220 s.res.KeyDiffs = append(s.res.KeyDiffs, diff) 221 // the identify outcome should know that this 222 // key was revoked, as well as there being 223 // a KeyDiff: 224 s.res.Revoked = append(s.res.Revoked, diff) 225 display(kid, diff) 226 } 227 } 228 }