github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/context.go (about) 1 package libkb 2 3 import ( 4 "fmt" 5 "runtime/debug" 6 "time" 7 8 logger "github.com/keybase/client/go/logger" 9 "github.com/keybase/client/go/profiling" 10 keybase1 "github.com/keybase/client/go/protocol/keybase1" 11 context "golang.org/x/net/context" 12 ) 13 14 type APITokener interface { 15 Tokens() (session, csrf string) 16 } 17 18 type MetaContext struct { 19 ctx context.Context 20 g *GlobalContext 21 loginContext LoginContext 22 activeDevice *ActiveDevice 23 apiTokener APITokener 24 uis UIs 25 } 26 27 func (m MetaContext) Dump() { 28 m.Debug("MetaContext#Dump:") 29 if m.activeDevice != nil { 30 m.Debug("- Local ActiveDevice:") 31 m.activeDevice.Dump(m, "-- ") 32 } 33 m.Debug("- Global ActiveDevice:") 34 m.g.ActiveDevice.Dump(m, "-- ") 35 if m.loginContext != nil { 36 m.Debug("- Login Context:") 37 m.loginContext.Dump(m, "-- ") 38 } 39 } 40 41 func NewMetaContext(ctx context.Context, g *GlobalContext) MetaContext { 42 return MetaContext{ctx: ctx, g: g} 43 } 44 45 func (m MetaContext) WithLoginContext(l LoginContext) MetaContext { 46 m.loginContext = l 47 return m 48 } 49 50 func (m MetaContext) WithAPITokener(t APITokener) MetaContext { 51 m.apiTokener = t 52 return m 53 } 54 55 func (m MetaContext) WithCtx(c context.Context) MetaContext { 56 m.ctx = c 57 return m 58 } 59 60 func (m MetaContext) G() *GlobalContext { 61 return m.g 62 } 63 64 func (m MetaContext) Ctx() context.Context { 65 return m.ctx 66 } 67 68 func (m MetaContext) LoginContext() LoginContext { 69 return m.loginContext 70 } 71 72 func (m MetaContext) VLogf(lev VDebugLevel, msg string, args ...interface{}) { 73 m.g.VDL.CLogfWithAddedDepth(m.ctx, lev, 1, msg, args...) 74 } 75 76 func (m MetaContext) Trace(msg string, err *error) func() { 77 return CTrace(m.ctx, m.g.Log.CloneWithAddedDepth(1), msg, err, m.G().Clock()) 78 } 79 func (m MetaContext) VTrace(lev VDebugLevel, msg string, err *error) func() { 80 return m.g.CVTrace(m.ctx, lev, msg, err) 81 } 82 func (m MetaContext) PerfTrace(msg string, err *error) func() { 83 return CTrace(m.ctx, m.g.PerfLog.CloneWithAddedDepth(1), msg, err, m.G().Clock()) 84 } 85 func (m MetaContext) TimeBuckets() (MetaContext, *profiling.TimeBuckets) { 86 var ret *profiling.TimeBuckets 87 m.ctx, ret = m.G().CTimeBuckets(m.ctx) 88 return m, ret 89 } 90 func (m MetaContext) TimeTracer(label string, enabled bool) profiling.TimeTracer { 91 return m.G().CTimeTracer(m.Ctx(), label, enabled) 92 } 93 94 func (m MetaContext) Debug(f string, args ...interface{}) { 95 m.g.Log.CloneWithAddedDepth(1).CDebugf(m.ctx, f, args...) 96 } 97 func (m MetaContext) PerfDebug(f string, args ...interface{}) { 98 m.g.PerfLog.CloneWithAddedDepth(1).CDebugf(m.ctx, f, args...) 99 } 100 func (m MetaContext) Warning(f string, args ...interface{}) { 101 m.g.Log.CloneWithAddedDepth(1).CWarningf(m.ctx, f, args...) 102 } 103 func (m MetaContext) Error(f string, args ...interface{}) { 104 m.g.Log.CloneWithAddedDepth(1).CErrorf(m.ctx, f, args...) 105 } 106 func (m MetaContext) Info(f string, args ...interface{}) { 107 m.g.Log.CloneWithAddedDepth(1).CInfof(m.ctx, f, args...) 108 } 109 110 func (m MetaContext) ActiveDevice() *ActiveDevice { 111 if m.activeDevice != nil { 112 m.Debug("MetaContext#ActiveDevice: thread local") 113 return m.activeDevice 114 } 115 m.Debug("MetaContext#ActiveDevice: global") 116 return m.G().ActiveDevice 117 } 118 119 func (m MetaContext) NIST() (*NIST, error) { 120 nist, uid, _, err := m.ActiveDevice().NISTAndUIDDeviceID(m.Ctx()) 121 if err != nil { 122 return nil, err 123 } 124 if !uid.Equal(m.CurrentUID()) { 125 m.Debug("MetaContext#NIST: Not returning nist, since for wrong UID: %s != %s", uid, m.CurrentUID()) 126 return nil, nil 127 } 128 return nist, nil 129 } 130 131 func NewMetaContextTODO(g *GlobalContext) MetaContext { 132 return MetaContext{ctx: context.TODO(), g: g} 133 } 134 func NewMetaContextBackground(g *GlobalContext) MetaContext { 135 return MetaContext{ctx: context.Background(), g: g} 136 } 137 138 func (m MetaContext) WithDelegatedIdentifyUI(u IdentifyUI) MetaContext { 139 m.uis.IdentifyUI = u 140 return m 141 } 142 143 func (m MetaContext) WithContext(ctx context.Context) MetaContext { 144 m.ctx = ctx 145 return m 146 } 147 148 func (m MetaContext) WithContextCancel() (MetaContext, func()) { 149 var f func() 150 m.ctx, f = context.WithCancel(m.ctx) 151 return m, f 152 } 153 154 func (m MetaContext) BackgroundWithCancel() (MetaContext, func()) { 155 var f func() 156 m.ctx, f = context.WithCancel(context.Background()) 157 return m, f 158 } 159 160 func (m MetaContext) BackgroundWithLogTags() MetaContext { 161 m.ctx = CopyTagsToBackground(m.ctx) 162 return m 163 } 164 165 func (m MetaContext) WithTimeout(timeout time.Duration) (MetaContext, func()) { 166 var f func() 167 m.ctx, f = context.WithTimeout(m.ctx, timeout) 168 return m, f 169 } 170 171 func (m MetaContext) WithLogTag(k string) MetaContext { 172 m.ctx = WithLogTag(m.ctx, k) 173 return m 174 } 175 176 func (m MetaContext) WithLogTags(tags map[string]string) MetaContext { 177 for k, v := range tags { 178 m.ctx = WithLogTagWithValue(m.ctx, k, v) 179 } 180 return m 181 } 182 183 func (m MetaContext) WithTimeBuckets() (MetaContext, *profiling.TimeBuckets) { 184 ctx, tbs := m.G().CTimeBuckets(m.ctx) 185 m.ctx = ctx 186 return m, tbs 187 } 188 189 func (m MetaContext) EnsureCtx() MetaContext { 190 if m.ctx == nil { 191 m.ctx = context.Background() 192 m.Debug("installing background context.Context") 193 } 194 return m 195 } 196 197 func (m MetaContext) WithSecretUI(u SecretUI) MetaContext { 198 m.uis.SecretUI = u 199 return m 200 } 201 202 func (m MetaContext) WithLogUI(u LogUI) MetaContext { 203 m.uis.LogUI = u 204 return m 205 } 206 207 func (m MetaContext) WithPgpUI(u PgpUI) MetaContext { 208 m.uis.PgpUI = u 209 return m 210 } 211 212 func (m MetaContext) WithIdentifyUI(u IdentifyUI) MetaContext { 213 m.uis.IdentifyUI = u 214 return m 215 } 216 217 func (m MetaContext) WithGPGUI(u GPGUI) MetaContext { 218 m.uis.GPGUI = u 219 return m 220 } 221 222 func (m MetaContext) WithSaltpackUI(s SaltpackUI) MetaContext { 223 m.uis.SaltpackUI = s 224 return m 225 } 226 227 func (m MetaContext) UIs() UIs { 228 return m.uis 229 } 230 231 func (m MetaContext) WithUIs(u UIs) MetaContext { 232 m.uis = u 233 return m 234 } 235 236 func (m MetaContext) WithActiveDevice(a *ActiveDevice) MetaContext { 237 m.activeDevice = a 238 return m 239 } 240 241 func (m MetaContext) WithProvisioningKeyActiveDevice(d *DeviceWithKeys, uv keybase1.UserVersion) MetaContext { 242 return m.WithActiveDevice(d.ToProvisioningKeyActiveDevice(m, uv)) 243 } 244 245 func (m MetaContext) WithGlobalActiveDevice() MetaContext { 246 m.activeDevice = nil 247 return m 248 } 249 250 func (m MetaContext) SecretKeyPromptArg(ska SecretKeyArg, reason string) SecretKeyPromptArg { 251 return SecretKeyPromptArg{ 252 SecretUI: m.uis.SecretUI, 253 Ska: ska, 254 Reason: reason, 255 } 256 } 257 258 func (m MetaContext) WithNewProvisionalLoginContext() MetaContext { 259 return m.WithLoginContext(newProvisionalLoginContext(m)) 260 } 261 262 func (m MetaContext) WithNewProvisionalLoginContextForUser(u *User) MetaContext { 263 return m.WithNewProvisionalLoginContextForUserVersionAndUsername(u.ToUserVersion(), u.GetNormalizedName()) 264 } 265 266 func (m MetaContext) WithNewProvisionalLoginContextForUserVersionAndUsername(uv keybase1.UserVersion, un NormalizedUsername) MetaContext { 267 plc := newProvisionalLoginContextWithUserVersionAndUsername(m, uv, un) 268 err := m.ActiveDevice().CopyCacheToLoginContextIfForUserVersion(m, plc, uv) 269 if err != nil { 270 m.Debug("WithNewProvisionalLoginContextForUserVersionAndUsername: error %+v", err) 271 } 272 return m.WithLoginContext(plc) 273 } 274 275 func (m MetaContext) CommitProvisionalLogin() MetaContext { 276 m.Debug("MetaContext#CommitProvisionalLogin") 277 lctx := m.loginContext 278 m.loginContext = nil 279 if lctx != nil { 280 if ppsc := lctx.PassphraseStreamCache(); ppsc != nil { 281 m.ActiveDevice().CachePassphraseStream(ppsc) 282 } 283 } 284 return m 285 } 286 287 type UIs struct { 288 GPGUI GPGUI 289 LogUI LogUI 290 LoginUI LoginUI 291 SecretUI SecretUI 292 IdentifyUI IdentifyUI 293 PgpUI PgpUI 294 ProveUI ProveUI 295 ProvisionUI ProvisionUI 296 SaltpackUI SaltpackUI 297 298 // Usually set to `NONE`, meaning none specified. 299 // But if we know it, specify the end client type here 300 // since some things like GPG shell-out work differently 301 // depending. 302 ClientType keybase1.ClientType 303 304 SessionID int 305 } 306 307 func (e UIs) HasUI(kind UIKind) bool { 308 switch kind { 309 case GPGUIKind: 310 return e.GPGUI != nil 311 case LogUIKind: 312 return e.LogUI != nil 313 case LoginUIKind: 314 return e.LoginUI != nil 315 case SecretUIKind: 316 return e.SecretUI != nil 317 case IdentifyUIKind: 318 return e.IdentifyUI != nil 319 case PgpUIKind: 320 return e.PgpUI != nil 321 case ProveUIKind: 322 return e.ProveUI != nil 323 case ProvisionUIKind: 324 return e.ProvisionUI != nil 325 case SaltpackUIKind: 326 return e.SaltpackUI != nil 327 } 328 panic(fmt.Sprintf("unhandled kind: %d", kind)) 329 } 330 331 type MetaContextified struct { 332 m MetaContext 333 } 334 335 func (m MetaContextified) M() MetaContext { 336 return m.m 337 } 338 339 func (m MetaContextified) G() *GlobalContext { 340 return m.m.g 341 } 342 343 func NewMetaContextified(m MetaContext) MetaContextified { 344 return MetaContextified{m: m} 345 } 346 347 // SwitchUserNewConfig switches the global active "user" as far as the global 348 // config file is concerned. It switches the user to a new user, and therefore 349 // you should specify the username, salt, and device ID for this user on this 350 // device. It will take out the global `switchUserMu` and also clear out the 351 // global ActiveDevice at the same time. We follow the same pattern here and 352 // elsewhere: atomically mutate the `current_user` of the config file as we set 353 // the global ActiveDevice. 354 func (m MetaContext) SwitchUserNewConfig(u keybase1.UID, n NormalizedUsername, salt []byte, d keybase1.DeviceID) error { 355 return m.switchUserNewConfig(u, n, salt, d, nil) 356 } 357 358 func (m MetaContext) switchUserNewConfig(u keybase1.UID, n NormalizedUsername, salt []byte, d keybase1.DeviceID, ad *ActiveDevice) error { 359 g := m.G() 360 defer g.switchUserMu.Acquire(m, "switchUserNewConfig")() 361 cw := g.Env.GetConfigWriter() 362 if cw == nil { 363 return NoConfigWriterError{} 364 } 365 // Note that `true` here means that an existing user config entry will 366 // be overwritten. 367 if err := cw.SetUserConfig(NewUserConfig(u, n, salt, d), true /* overwrite */); err != nil { 368 return err 369 } 370 // Clear stayLoggedOut, so that if the service restarts for any reason 371 // we will know that we are logged in. 372 if g.Env.GetStayLoggedOut() { 373 if err := cw.SetStayLoggedOut(false); err != nil { 374 return err 375 } 376 } 377 return g.ActiveDevice.SetOrClear(m, ad) 378 } 379 380 // SwitchUserNewConfigActiveDevice creates a new config file stanza and an 381 // active device for the given user, all while holding the switchUserMu lock. 382 func (m MetaContext) SwitchUserNewConfigActiveDevice(uv keybase1.UserVersion, n NormalizedUsername, salt []byte, d keybase1.DeviceID, sigKey GenericKey, encKey GenericKey, deviceName string, keychainMode KeychainMode) error { 383 ad := NewProvisionalActiveDevice(m, uv, d, sigKey, encKey, deviceName, keychainMode) 384 return m.switchUserNewConfig(uv.Uid, n, salt, d, ad) 385 } 386 387 // SwitchUserNukeConfig removes the given username from the config file, and 388 // then switches to not having a current user (by clearing the ActiveDevice, 389 // etc). It does this in a critical section, holding switchUserMu. 390 func (m MetaContext) SwitchUserNukeConfig(n NormalizedUsername) error { 391 g := m.G() 392 defer g.switchUserMu.Acquire(m, "SwitchUserNukeConfig")() 393 cw := g.Env.GetConfigWriter() 394 cr := g.Env.GetConfig() 395 if cw == nil { 396 return NoConfigWriterError{} 397 } 398 if cr == nil { 399 return NoConfigFileError{} 400 } 401 uid := cr.GetUIDForUsername(n) 402 err := cw.NukeUser(n) 403 if err != nil { 404 return err 405 } 406 if g.ActiveDevice.UID().Equal(uid) { 407 err := g.ActiveDevice.Clear() 408 if err != nil { 409 return err 410 } 411 } 412 return nil 413 } 414 415 func (m MetaContext) SwitchUser(n NormalizedUsername) error { 416 return m.SwitchUserToActiveDevice(n, nil) 417 } 418 419 func (m MetaContext) SwitchUserToActiveDevice(n NormalizedUsername, ad *ActiveDevice) (err error) { 420 421 defer m.Trace(fmt.Sprintf("MetaContext#SwitchUserToActiveDevice(%s,ActiveDevice:%v)", n.String(), (ad != nil)), &err)() 422 423 g := m.G() 424 if n.IsNil() { 425 return nil 426 } 427 if !n.IsValid() { 428 return NewBadUsernameError(n.String()) 429 } 430 defer g.switchUserMu.Acquire(m, "SwitchUserToActiveDevice %v", n)() 431 cw := g.Env.GetConfigWriter() 432 if cw == nil { 433 return NoConfigWriterError{} 434 } 435 err = cw.SwitchUser(n) 436 if _, ok := err.(UserNotFoundError); ok { 437 m.Debug("| No user %s found; clearing out config", n) 438 err = nil 439 } 440 if err != nil { 441 return err 442 } 443 err = g.ActiveDevice.SetOrClear(m, ad) 444 if err != nil { 445 return err 446 } 447 m.CommitProvisionalLogin() 448 449 return nil 450 } 451 452 func (m MetaContext) SwitchUserDeprovisionNukeConfig(username NormalizedUsername) error { 453 g := m.G() 454 defer g.switchUserMu.Acquire(m, "SwitchUserDeprovisionNukeConfig %v", username)() 455 456 cw := g.Env.GetConfigWriter() 457 if cw == nil { 458 return NoConfigWriterError{} 459 } 460 if err := cw.NukeUser(username); err != nil { 461 return err 462 } 463 464 // The config entries we just nuked could still be in memory. Clear them. 465 return cw.SetUserConfig(nil, true /* overwrite; ignored */) 466 } 467 468 // SetActiveOneshotDevice acquires the switchUserMu mutex, setting the active 469 // device to one that corresponds to the given UID and DeviceWithKeys, and also 470 // sets the config file to a temporary in-memory config (not writing to disk) 471 // to satisfy local requests for g.Env.* 472 func (m MetaContext) SwitchUserToActiveOneshotDevice(uv keybase1.UserVersion, nun NormalizedUsername, d *DeviceWithKeys) (err error) { 473 defer m.Trace("MetaContext#SwitchUserToActiveOneshotDevice", &err)() 474 475 g := m.G() 476 defer g.switchUserMu.Acquire(m, "SwitchUserToActiveOneshotDevice")() 477 cw := g.Env.GetConfigWriter() 478 if cw == nil { 479 return NoConfigWriterError{} 480 } 481 ad := d.ToProvisioningKeyActiveDevice(m, uv) 482 err = g.ActiveDevice.Copy(m, ad) 483 if err != nil { 484 return err 485 } 486 uc := NewOneshotUserConfig(uv.Uid, nun, nil, d.DeviceID()) 487 err = cw.SetUserConfig(uc, false) 488 if err != nil { 489 return err 490 } 491 return nil 492 } 493 494 // SwitchUserLoggedOut clears the active device and the current_user stanza of 495 // the config file, all while holding the switchUserMu 496 func (m MetaContext) SwitchUserLoggedOut() (err error) { 497 defer m.Trace("MetaContext#SwitchUserLoggedOut", &err)() 498 g := m.G() 499 defer g.switchUserMu.Acquire(m, "SwitchUserLoggedOut")() 500 cw := g.Env.GetConfigWriter() 501 if cw == nil { 502 return NoConfigWriterError{} 503 } 504 err = g.ActiveDevice.Clear() 505 if err != nil { 506 return err 507 } 508 err = cw.SetUserConfig(nil, false) 509 if err != nil { 510 return err 511 } 512 return nil 513 } 514 515 // SetActiveDevice sets the active device to have the UserVersion, deviceID, 516 // sigKey, encKey and deviceName as specified, and does so while grabbing the 517 // global switchUser lock, since it should be sycnhronized with attempts to 518 // switch the global logged in user. It does not, however, change the 519 // `current_user` in the config file, or edit the global config file in any 520 // way. 521 func (m MetaContext) SetActiveDevice(uv keybase1.UserVersion, deviceID keybase1.DeviceID, 522 sigKey, encKey GenericKey, deviceName string, keychainMode KeychainMode) error { 523 g := m.G() 524 defer g.switchUserMu.Acquire(m, "SetActiveDevice")() 525 if !g.Env.GetUID().Equal(uv.Uid) { 526 return NewUIDMismatchError("UID switched out from underneath provisioning process") 527 } 528 return g.ActiveDevice.Set(m, uv, deviceID, sigKey, encKey, deviceName, 0, keychainMode) 529 } 530 531 func (m MetaContext) SetSigningKey(uv keybase1.UserVersion, deviceID keybase1.DeviceID, sigKey GenericKey, deviceName string) error { 532 g := m.G() 533 defer g.switchUserMu.Acquire(m, "SetSigningKey")() 534 return g.ActiveDevice.setSigningKey(g, uv, deviceID, sigKey, deviceName) 535 } 536 537 func (m MetaContext) SetEncryptionKey(uv keybase1.UserVersion, deviceID keybase1.DeviceID, encKey GenericKey) error { 538 g := m.G() 539 defer g.switchUserMu.Acquire(m, "SetEncryptionKey")() 540 return g.ActiveDevice.setEncryptionKey(uv, deviceID, encKey) 541 } 542 543 // LogoutAndDeprovisionIfRevoked loads the user and checks if the current 544 // device keys have been revoked. If so, it calls Logout and then runs the 545 // ClearSecretsOnDeprovision 546 func (m MetaContext) LogoutAndDeprovisionIfRevoked() (err error) { 547 m = m.WithLogTag("LOIR") 548 549 defer m.Trace("GlobalContext#LogoutAndDeprovisionIfRevoked", &err)() 550 551 if !m.ActiveDevice().Valid() { 552 m.Debug("LogoutAndDeprovisionIfRevoked: skipping check (not logged in)") 553 return nil 554 } 555 556 if m.G().Env.GetSkipLogoutIfRevokedCheck() { 557 m.Debug("LogoutAndDeprovisionIfRevoked: skipping check (SkipLogoutIfRevokedCheck)") 558 return nil 559 } 560 561 doLogout := false 562 err = CheckCurrentUIDDeviceID(m) 563 switch err.(type) { 564 case nil: 565 m.Debug("LogoutAndDeprovisionIfRevoked: current device ok") 566 case DeviceNotFoundError: 567 m.Debug("LogoutAndDeprovisionIfRevoked: device not found error; user was likely reset; calling logout (%s)", err) 568 doLogout = true 569 case KeyRevokedError: 570 m.Debug("LogoutAndDeprovisionIfRevoked: key revoked error error; device was revoked; calling logout (%s)", err) 571 doLogout = true 572 default: 573 m.Debug("LogoutAndDeprovisionIfRevoked: non-actionable error: %s", err) 574 } 575 576 if doLogout { 577 username := m.G().Env.GetUsername() 578 if err := m.LogoutWithOptions(LogoutOptions{KeepSecrets: false, Force: true}); err != nil { 579 return err 580 } 581 return ClearSecretsOnDeprovision(m, username) 582 } 583 584 return nil 585 } 586 587 func (m MetaContext) PassphraseStream() *PassphraseStream { 588 if m.LoginContext() != nil { 589 if m.LoginContext().PassphraseStreamCache() == nil { 590 return nil 591 } 592 return m.LoginContext().PassphraseStreamCache().PassphraseStream() 593 } 594 return m.ActiveDevice().PassphraseStream() 595 } 596 597 func (m MetaContext) PassphraseStreamAndTriplesec() (*PassphraseStream, Triplesec) { 598 var ppsc *PassphraseStreamCache 599 if m.LoginContext() != nil { 600 ppsc = m.LoginContext().PassphraseStreamCache() 601 } else { 602 ppsc = m.ActiveDevice().PassphraseStreamCache() 603 } 604 if ppsc == nil { 605 return nil, nil 606 } 607 return ppsc.PassphraseStreamAndTriplesec() 608 } 609 610 func (m MetaContext) TriplesecAndGeneration() (ret Triplesec, ppgen PassphraseGeneration) { 611 var pps *PassphraseStream 612 pps, ret = m.PassphraseStreamAndTriplesec() 613 if pps == nil { 614 return nil, ppgen 615 } 616 ppgen = pps.Generation() 617 if ppgen.IsNil() { 618 return nil, ppgen 619 } 620 return ret, ppgen 621 } 622 623 func (m MetaContext) CurrentUsername() NormalizedUsername { 624 if m.LoginContext() != nil { 625 return m.LoginContext().GetUsername() 626 } 627 return m.ActiveDevice().Username(m) 628 } 629 630 func (m MetaContext) CurrentUID() keybase1.UID { 631 if m.LoginContext() != nil { 632 return m.LoginContext().GetUID() 633 } 634 return m.ActiveDevice().UID() 635 } 636 637 func (m MetaContext) CurrentUserVersion() keybase1.UserVersion { 638 if m.LoginContext() != nil { 639 return m.LoginContext().GetUserVersion() 640 } 641 return m.ActiveDevice().UserVersion() 642 } 643 644 func (m MetaContext) HasAnySession() (ret bool) { 645 defer m.Trace("MetaContext#HasAnySession", nil)() 646 if m.LoginContext() != nil { 647 ok, _ := m.LoginContext().LoggedInLoad() 648 if ok { 649 m.Debug("| has temporary login session") 650 return true 651 } 652 } 653 654 if m.ActiveDevice().Valid() { 655 m.Debug("| has valid device") 656 return true 657 } 658 659 return false 660 } 661 662 func (m MetaContext) SyncSecrets() (ss *SecretSyncer, err error) { 663 defer m.Trace("MetaContext#SyncSecrets", &err)() 664 if m.LoginContext() != nil { 665 err = m.LoginContext().RunSecretSyncer(m, keybase1.UID("")) 666 if err != nil { 667 return nil, err 668 } 669 return m.LoginContext().SecretSyncer(), nil 670 } 671 return m.ActiveDevice().SyncSecrets(m) 672 } 673 674 func (m MetaContext) SyncSecretsForUID(u keybase1.UID) (ss *SecretSyncer, err error) { 675 defer m.Trace("MetaContext#SyncSecrets", &err)() 676 return m.ActiveDevice().SyncSecretsForUID(m, u, false /* force */) 677 } 678 679 func (m MetaContext) ProvisionalSessionArgs() (token string, csrf string) { 680 if m.LoginContext() == nil { 681 return "", "" 682 } 683 sess := m.LoginContext().LocalSession() 684 if sess == nil || !sess.IsValid() { 685 return "", "" 686 } 687 return sess.token, sess.csrf 688 } 689 690 func (m MetaContext) Keyring() (ret *SKBKeyringFile, err error) { 691 defer m.Trace("MetaContext#Keyring", &err)() 692 if m.LoginContext() != nil { 693 return m.LoginContext().Keyring(m) 694 } 695 return m.ActiveDevice().Keyring(m) 696 } 697 698 var _ logger.ContextInterface = MetaContext{} 699 700 func (m MetaContext) UpdateContextToLoggerContext(c context.Context) logger.ContextInterface { 701 return m.WithContext(c) 702 } 703 704 func (m MetaContext) DebugStack() { 705 m.Debug("stack trace:\n%s", string(debug.Stack())) 706 }