github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/status/status.go (about) 1 // Copyright 2019 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package status 5 6 import ( 7 "errors" 8 "os" 9 "path/filepath" 10 "strings" 11 12 "github.com/keybase/client/go/install" 13 "github.com/keybase/client/go/libkb" 14 keybase1 "github.com/keybase/client/go/protocol/keybase1" 15 "github.com/keybase/go-framed-msgpack-rpc/rpc" 16 ) 17 18 func GetCurrentStatus(mctx libkb.MetaContext) (res keybase1.CurrentStatus, err error) { 19 cr := mctx.G().Env.GetConfig() 20 if cr == nil { 21 return res, nil 22 } 23 res.Configured = true 24 if uid := cr.GetUID(); uid.Exists() { 25 res.Registered = true 26 res.User = libkb.NewUserThin(cr.GetUsername().String(), uid).Export() 27 } 28 res.SessionIsValid = mctx.ActiveDevice().Valid() 29 res.LoggedIn = res.SessionIsValid 30 res.DeviceName = mctx.ActiveDevice().Name() 31 return res, nil 32 } 33 34 func GetExtendedStatus(mctx libkb.MetaContext) (res keybase1.ExtendedStatus, err error) { 35 mctx = mctx.WithLogTag("EXTSTATUS") 36 defer mctx.Trace("GetExtendedStatus", &err)() 37 g := mctx.G() 38 39 res.Standalone = g.Env.GetStandalone() 40 res.LogDir = g.Env.GetLogDir() 41 res.Clients = libkb.GetClientStatus(mctx) 42 43 if err = g.GetFullSelfer().WithSelf(mctx.Ctx(), func(me *libkb.User) error { 44 ckf := me.GetComputedKeyFamily() 45 if ckf == nil { 46 return errors.New("Couldn't load key family") 47 } 48 device, err := ckf.GetCurrentDevice(g) 49 if err != nil { 50 mctx.Debug("| GetCurrentDevice failed: %s", err) 51 res.DeviceErr = &keybase1.LoadDeviceErr{Where: "ckf.GetCurrentDevice", Desc: err.Error()} 52 } else { 53 res.Device = device.ProtExport() 54 } 55 56 ss := g.SecretStore() 57 if me != nil && ss != nil { 58 s, err := ss.RetrieveSecret(mctx, me.GetNormalizedName()) 59 if err == nil && !s.IsNil() { 60 res.StoredSecret = true 61 } 62 } 63 return nil 64 }); err != nil { 65 mctx.Debug("| could not load me user: %s", err) 66 res.DeviceErr = &keybase1.LoadDeviceErr{Where: "libkb.LoadMe", Desc: err.Error()} 67 } 68 69 // cached device key status 70 _, _, _, sk, ek := g.ActiveDevice.AllFields() 71 res.DeviceSigKeyCached = sk != nil 72 res.DeviceEncKeyCached = ek != nil 73 74 ad := mctx.ActiveDevice() 75 // cached paper key status 76 if pk := ad.ProvisioningKey(mctx); pk != nil { 77 if pk.EncryptionKey() != nil { 78 res.PaperEncKeyCached = true 79 } 80 if pk.SigningKey() != nil { 81 res.PaperSigKeyCached = true 82 } 83 } 84 85 psc := ad.PassphraseStreamCache() 86 res.PassphraseStreamCached = psc.ValidPassphraseStream() 87 res.TsecCached = psc.ValidTsec() 88 res.SecretPromptSkip = mctx.ActiveDevice().SecretPromptCancelTimer().WasRecentlyCanceled(mctx) 89 90 current, all, err := libkb.GetAllProvisionedUsernames(mctx) 91 if err != nil { 92 mctx.Debug("| died in GetAllProvisionedUsernames()") 93 return res, err 94 } 95 res.DefaultUsername = current.String() 96 p := make([]string, len(all)) 97 for i, u := range all { 98 p[i] = u.String() 99 } 100 res.ProvisionedUsernames = p 101 102 accounts, err := libkb.GetConfiguredAccountsFromProvisionedUsernames(mctx, mctx.G().SecretStore(), current, all) 103 if err != nil { 104 mctx.Debug("| died in GetConfiguredAccounts()") 105 return res, err 106 } 107 res.ConfiguredAccounts = accounts 108 109 res.PlatformInfo = getPlatformInfo() 110 res.DefaultDeviceID = g.Env.GetDeviceID() 111 res.RememberPassphrase = g.Env.GetRememberPassphrase(g.Env.GetUsername()) 112 // DeviceEK status, can be nil if user is logged out 113 deviceEKStorage := g.GetDeviceEKStorage() 114 if deviceEKStorage != nil { 115 dekNames, err := deviceEKStorage.ListAllForUser(mctx) 116 if err != nil { 117 return res, err 118 } 119 res.DeviceEkNames = dekNames 120 } 121 122 res.LocalDbStats = strings.Split(g.LocalDb.Stats(), "\n") 123 res.LocalChatDbStats = strings.Split(g.LocalChatDb.Stats(), "\n") 124 if cacheSizeInfo, err := CacheSizeInfo(g); err == nil { 125 res.CacheDirSizeInfo = cacheSizeInfo 126 } 127 128 if g.ConnectionManager != nil { 129 xp := g.ConnectionManager.LookupByClientType(keybase1.ClientType_KBFS) 130 if xp == nil { 131 mctx.Debug("| KBFS stats not available") 132 } else { 133 cli := &keybase1.SimpleFSClient{ 134 Cli: rpc.NewClient( 135 xp, libkb.NewContextifiedErrorUnwrapper(g), nil), 136 } 137 stats, err := cli.SimpleFSGetStats(mctx.Ctx()) 138 if err != nil { 139 mctx.Debug("| KBFS stats error: %+v", err) 140 } else { 141 res.LocalBlockCacheDbStats = stats.BlockCacheDbStats 142 res.LocalSyncCacheDbStats = stats.SyncCacheDbStats 143 } 144 } 145 } 146 147 if g.UIRouter != nil { 148 uiMapping := map[string]int{} 149 for k, v := range g.UIRouter.DumpUIs() { 150 uiMapping[k.String()] = int(v) 151 } 152 res.UiRouterMapping = uiMapping 153 } 154 155 return res, nil 156 } 157 158 func GetConfig(mctx libkb.MetaContext, forkType keybase1.ForkType) (c keybase1.Config, err error) { 159 serverURI, err := mctx.G().Env.GetServerURI() 160 if err != nil { 161 return c, err 162 } 163 164 c.ServerURI = serverURI 165 c.RunMode = string(mctx.G().Env.GetRunMode()) 166 c.SocketFile, err = mctx.G().Env.GetSocketBindFile() 167 if err != nil { 168 return c, err 169 } 170 171 gpg := mctx.G().GetGpgClient() 172 canExec, err := gpg.CanExec(mctx) 173 if err == nil { 174 c.GpgExists = canExec 175 c.GpgPath = gpg.Path(mctx) 176 } 177 178 c.Version = libkb.VersionString() 179 c.VersionShort = libkb.Version 180 181 var v []string 182 libkb.VersionMessage(func(s string) { 183 v = append(v, s) 184 }) 185 c.VersionFull = strings.Join(v, "\n") 186 187 dir, err := filepath.Abs(filepath.Dir(os.Args[0])) 188 if err == nil { 189 c.Path = dir 190 } else { 191 mctx.Warning("Failed to get service path: %s", err) 192 } 193 194 realpath, err := libkb.CurrentBinaryRealpath() 195 if err == nil { 196 c.BinaryRealpath = realpath 197 } else { 198 mctx.Debug("Failed to get service realpath: %s", err) 199 } 200 201 c.ConfigPath = mctx.G().Env.GetConfigFilename() 202 c.Label = mctx.G().Env.GetLabel() 203 if forkType == keybase1.ForkType_AUTO { 204 c.IsAutoForked = true 205 } 206 c.ForkType = forkType 207 return c, nil 208 } 209 210 func GetFullStatus(mctx libkb.MetaContext) (status *keybase1.FullStatus, err error) { 211 status = &keybase1.FullStatus{} 212 // The client overrides this value when sending logs 213 status.Client.Version = libkb.VersionString() 214 status.ConfigPath = mctx.G().Env.GetConfigFilename() 215 216 status.CurStatus, err = GetCurrentStatus(mctx) 217 if err != nil { 218 return nil, err 219 } 220 221 // Duplicate the username at top-level for backwards compatibility of 222 // output. 223 if status.CurStatus.User != nil { 224 status.Username = status.CurStatus.User.Username 225 } 226 227 status.ExtStatus, err = GetExtendedStatus(mctx) 228 if err != nil { 229 return nil, err 230 } 231 232 // set service status 233 if status.ExtStatus.Standalone { 234 status.Service.Running = false 235 } else { 236 status.Service.Running = true 237 } 238 status.Service.Version = libkb.VersionString() 239 240 // set kbfs status 241 kbfsInstalledVersion, err := install.KBFSBundleVersion(mctx.G(), "") 242 if err != nil { 243 mctx.Debug("Failed to get KBFSBundleVersion: %s", err) 244 } else { 245 mctx.Debug("Got KBFSBundleVersion: %s", kbfsInstalledVersion) 246 status.Kbfs.InstalledVersion = kbfsInstalledVersion 247 } 248 if kbfs := GetFirstClient(status.ExtStatus.Clients, keybase1.ClientType_KBFS); kbfs != nil { 249 status.Kbfs.Version = kbfs.Version 250 status.Kbfs.Running = true 251 // This just gets the mountpoint from the environment; the 252 // user could have technically passed a different mountpoint 253 // to KBFS on macOS or Linux. TODO(KBFS-2723): fetch the 254 // actual mountpoint with a new RPC from KBFS. 255 mountDir, err := mctx.G().Env.GetMountDir() 256 if err != nil { 257 return nil, err 258 } 259 status.Kbfs.Mount = mountDir 260 } else { 261 status.Kbfs.Version = kbfsInstalledVersion 262 } 263 264 // set desktop status 265 if desktop := GetFirstClient(status.ExtStatus.Clients, keybase1.ClientType_GUI_MAIN); desktop != nil { 266 status.Desktop.Running = true 267 status.Desktop.Version = desktop.Version 268 } 269 270 // set log paths 271 status.Service.Log = getServiceLog(mctx, status.ExtStatus.LogDir) 272 status.Service.EkLog = filepath.Join(status.ExtStatus.LogDir, libkb.EKLogFileName) 273 status.Service.PerfLog = filepath.Join(status.ExtStatus.LogDir, libkb.PerfLogFileName) 274 status.Kbfs.Log = filepath.Join(status.ExtStatus.LogDir, libkb.KBFSLogFileName) 275 status.Kbfs.PerfLog = filepath.Join(status.ExtStatus.LogDir, libkb.KBFSPerfLogFileName) 276 status.Desktop.Log = filepath.Join(status.ExtStatus.LogDir, libkb.GUILogFileName) 277 status.Updater.Log = filepath.Join(status.ExtStatus.LogDir, libkb.UpdaterLogFileName) 278 status.Start.Log = filepath.Join(status.ExtStatus.LogDir, libkb.StartLogFileName) 279 status.Git.Log = filepath.Join(status.ExtStatus.LogDir, libkb.GitLogFileName) 280 status.Git.PerfLog = filepath.Join(status.ExtStatus.LogDir, libkb.GitPerfLogFileName) 281 282 // set anything os-specific 283 mctx.Debug("Getting osSpecific status info") 284 if err := osSpecific(mctx, status); err != nil { 285 return nil, err 286 } 287 return status, nil 288 }