/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/libkb/env.go
2 113 строк
65 KB
chrisnojima-zoom
Version 670 - clean2 (#29122)
08 июн 2026, 19:31
Не верифицирован
08 июн 2026, 19:31
1943197
Код
Авторство
О чём код?
// Copyright 2015 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package libkb import ( "fmt" "os" "os/user" "path/filepath" "runtime" "strconv" "strings" "sync" "time" logger "github.com/keybase/client/go/logger" keybase1 "github.com/keybase/client/go/protocol/keybase1" "github.com/keybase/client/go/systemd" "github.com/syndtr/goleveldb/leveldb/opt" ) type NullConfiguration struct{} func (n NullConfiguration) GetHome() string { return "" } func (n NullConfiguration) GetMobileSharedHome() string { return "" } func (n NullConfiguration) GetServerURI() (string, error) { return "", nil } func (n NullConfiguration) GetConfigFilename() string { return "" } func (n NullConfiguration) GetUpdaterConfigFilename() string { return "" } func (n NullConfiguration) GetGUIConfigFilename() string { return "" } func (n NullConfiguration) GetDeviceCloneStateFilename() string { return "" } func (n NullConfiguration) GetSessionFilename() string { return "" } func (n NullConfiguration) GetDbFilename() string { return "" } func (n NullConfiguration) GetChatDbFilename() string { return "" } func (n NullConfiguration) GetPvlKitFilename() string { return "" } func (n NullConfiguration) GetParamProofKitFilename() string { return "" } func (n NullConfiguration) GetExternalURLKitFilename() string { return "" } func (n NullConfiguration) GetProveBypass() (bool, bool) { return false, false } func (n NullConfiguration) GetUsername() NormalizedUsername { return NormalizedUsername("") } func (n NullConfiguration) GetEmail() string { return "" } func (n NullConfiguration) GetProxy() string { return "" } func (n NullConfiguration) GetProxyType() string { return "" } func (n NullConfiguration) IsCertPinningEnabled() bool { return true } func (n NullConfiguration) GetGpgHome() string { return "" } func (n NullConfiguration) GetBundledCA(h string) string { return "" } func (n NullConfiguration) GetUserCacheMaxAge() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetProofCacheSize() (int, bool) { return 0, false } func (n NullConfiguration) GetProofCacheLongDur() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetProofCacheMediumDur() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetProofCacheShortDur() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetLinkCacheSize() (int, bool) { return 0, false } func (n NullConfiguration) GetLinkCacheCleanDur() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetUPAKCacheSize() (int, bool) { return 0, false } func (n NullConfiguration) GetUIDMapFullNameCacheSize() (int, bool) { return 0, false } func (n NullConfiguration) GetPayloadCacheSize() (int, bool) { return 0, false } func (n NullConfiguration) GetMerkleKIDs() []string { return nil } func (n NullConfiguration) GetCodeSigningKIDs() []string { return nil } func (n NullConfiguration) GetPinentry() string { return "" } func (n NullConfiguration) GetUID() (ret keybase1.UID) { return } func (n NullConfiguration) GetGpg() string { return "" } func (n NullConfiguration) GetGpgOptions() []string { return nil } func (n NullConfiguration) GetPGPFingerprint() *PGPFingerprint { return nil } func (n NullConfiguration) GetSecretKeyringTemplate() string { return "" } func (n NullConfiguration) GetSalt() []byte { return nil } func (n NullConfiguration) GetSocketFile() string { return "" } func (n NullConfiguration) GetPidFile() string { return "" } func (n NullConfiguration) GetStandalone() (bool, bool) { return false, false } func (n NullConfiguration) GetLocalRPCDebug() string { return "" } func (n NullConfiguration) GetTimers() string { return "" } func (n NullConfiguration) GetDeviceID() keybase1.DeviceID { return "" } func (n NullConfiguration) GetDeviceIDForUsername(un NormalizedUsername) keybase1.DeviceID { return "" } func (n NullConfiguration) GetDeviceIDForUID(u keybase1.UID) keybase1.DeviceID { return "" } func (n NullConfiguration) GetProxyCACerts() ([]string, error) { return nil, nil } func (n NullConfiguration) GetUsernameForUID(u keybase1.UID) NormalizedUsername { return NormalizedUsername("") } func (n NullConfiguration) GetUIDForUsername(u NormalizedUsername) keybase1.UID { return keybase1.UID("") } func (n NullConfiguration) GetStayLoggedOut() (bool, bool) { return false, false } func (n NullConfiguration) GetAutoFork() (bool, bool) { return false, false } func (n NullConfiguration) GetRunMode() (RunMode, error) { return NoRunMode, nil } func (n NullConfiguration) GetNoAutoFork() (bool, bool) { return false, false } func (n NullConfiguration) GetLogFile() string { return "" } func (n NullConfiguration) GetEKLogFile() string { return "" } func (n NullConfiguration) GetPerfLogFile() string { return "" } func (n NullConfiguration) GetGUILogFile() string { return "" } func (n NullConfiguration) GetUseDefaultLogFile() (bool, bool) { return false, false } func (n NullConfiguration) GetUseRootConfigFile() (bool, bool) { return false, false } func (n NullConfiguration) GetLogPrefix() string { return "" } func (n NullConfiguration) GetScraperTimeout() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetAPITimeout() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetTorMode() (TorMode, error) { return TorNone, nil } func (n NullConfiguration) GetTorHiddenAddress() string { return "" } func (n NullConfiguration) GetTorProxy() string { return "" } func (n NullConfiguration) GetUpdatePreferenceAuto() (bool, bool) { return false, false } func (n NullConfiguration) GetUpdatePreferenceSnoozeUntil() keybase1.Time { return keybase1.Time(0) } func (n NullConfiguration) GetUpdateLastChecked() keybase1.Time { return keybase1.Time(0) } func (n NullConfiguration) GetUpdatePreferenceSkip() string { return "" } func (n NullConfiguration) GetUpdateURL() string { return "" } func (n NullConfiguration) GetUpdateDisabled() (bool, bool) { return false, false } func (n NullConfiguration) GetVDebugSetting() string { return "" } func (n NullConfiguration) GetLocalTrackMaxAge() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetGregorURI() string { return "" } func (n NullConfiguration) GetGregorSaveInterval() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetGregorPingInterval() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetGregorPingTimeout() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetChatDelivererInterval() (time.Duration, bool) { return 0, false } func (n NullConfiguration) GetGregorDisabled() (bool, bool) { return false, false } func (n NullConfiguration) GetSecretStorePrimingDisabled() (bool, bool) { return false, false } func (n NullConfiguration) GetMountDir() string { return "" } func (n NullConfiguration) GetMountDirDefault() string { return "" } func (n NullConfiguration) GetBGIdentifierDisabled() (bool, bool) { return false, false } func (n NullConfiguration) GetFeatureFlags() (FeatureFlags, error) { return FeatureFlags{}, nil } func (n NullConfiguration) GetAppType() AppType { return NoAppType } func (n NullConfiguration) IsMobileExtension() (bool, bool) { return false, false } func (n NullConfiguration) GetSlowGregorConn() (bool, bool) { return false, false } func (n NullConfiguration) GetReadDeletedSigChain() (bool, bool) { return false, false } func (n NullConfiguration) GetRememberPassphrase(NormalizedUsername) (bool, bool) { return false, false } func (n NullConfiguration) GetLevelDBNumFiles() (int, bool) { return 0, false } func (n NullConfiguration) GetLevelDBWriteBufferMB() (int, bool) { return 4, false } func (n NullConfiguration) GetChatInboxSourceLocalizeThreads() (int, bool) { return 1, false } func (n NullConfiguration) GetAttachmentHTTPStartPort() (int, bool) { return 0, false } func (n NullConfiguration) GetAttachmentDisableMulti() (bool, bool) { return false, false } func (n NullConfiguration) GetDisableTeamAuditor() (bool, bool) { return false, false } func (n NullConfiguration) GetDisableMerkleAuditor() (bool, bool) { return false, false } func (n NullConfiguration) GetDisableSearchIndexer() (bool, bool) { return false, false } func (n NullConfiguration) GetDisableBgConvLoader() (bool, bool) { return false, false } func (n NullConfiguration) GetDisableTeamBoxAuditor() (bool, bool) { return false, false } func (n NullConfiguration) GetDisableEKBackgroundKeygen() (bool, bool) { return false, false } func (n NullConfiguration) GetEnableBotLiteMode() (bool, bool) { return false, false } func (n NullConfiguration) GetExtraNetLogging() (bool, bool) { return false, false } func (n NullConfiguration) GetForceLinuxKeyring() (bool, bool) { return false, false } func (n NullConfiguration) GetForceSecretStoreFile() (bool, bool) { return false, false } func (n NullConfiguration) GetRuntimeStatsEnabled() (bool, bool) { return false, false } func (n NullConfiguration) GetPassphraseState() *keybase1.PassphraseState { return nil } func (n NullConfiguration) GetPassphraseStateForUsername(NormalizedUsername) *keybase1.PassphraseState { return nil } func (n NullConfiguration) GetBug3964RepairTime(NormalizedUsername) (time.Time, error) { return time.Time{}, nil } func (n NullConfiguration) GetUserConfig() (*UserConfig, error) { return nil, nil } func (n NullConfiguration) GetUserConfigForUsername(s NormalizedUsername) (*UserConfig, error) { return nil, nil } func (n NullConfiguration) GetGString(string) string { return "" } func (n NullConfiguration) GetString(string) string { return "" } func (n NullConfiguration) GetBool(string, bool) (bool, bool) { return false, false } func (n NullConfiguration) GetAllUsernames() (NormalizedUsername, []NormalizedUsername, error) { return NormalizedUsername(""), nil, nil } func (n NullConfiguration) GetAllUserConfigs() (*UserConfig, []UserConfig, error) { return nil, nil, nil } func (n NullConfiguration) GetDebug() (bool, bool) { return false, false } func (n NullConfiguration) GetDebugJourneycard() (bool, bool) { return false, false } func (n NullConfiguration) GetDisplayRawUntrustedOutput() (bool, bool) { return false, false } func (n NullConfiguration) GetLogFormat() string { return "" } func (n NullConfiguration) GetAPIDump() (bool, bool) { return false, false } func (n NullConfiguration) GetNoPinentry() (bool, bool) { return false, false } func (n NullConfiguration) GetStringAtPath(string) (string, bool) { return "", false } func (n NullConfiguration) GetInterfaceAtPath(string) (any, error) { return nil, nil } func (n NullConfiguration) GetBoolAtPath(string) (bool, bool) { return false, false } func (n NullConfiguration) GetIntAtPath(string) (int, bool) { return 0, false } func (n NullConfiguration) GetFloatAtPath(string) (float64, bool) { return 0, false } func (n NullConfiguration) GetNullAtPath(string) bool { return false } func (n NullConfiguration) GetSecurityAccessGroupOverride() (bool, bool) { return false, false } func (n NullConfiguration) GetAndroidInstallReferrerChecked() bool { return false } type TestParameters struct { ConfigFilename string Home string MobileSharedHome string GPG string GPGHome string GPGOptions []string Debug bool // Whether we are in Devel Mode Devel bool // If we're in dev mode, the name for this test, with a random // suffix. DevelName string DevelPrefix string // when in test - name for the test without suffix. RuntimeDir string DisableUpgradePerUserKey bool EnvironmentFeatureFlags FeatureFlags // set to true to use production run mode in tests UseProductionRunMode bool // whether LogoutIfRevoked check should be skipped to avoid races // during resets. SkipLogoutIfRevokedCheck bool // On if, in test, we want to skip sending system chat messages SkipSendingSystemChatMessages bool // If we need to use the real clock for NIST generation (as in really // whacky tests liks TestRekey). UseTimeClockForNISTs bool // TeamNoHeadMerkleStore is used for testing to emulate older clients // that didn't store the head merkle sequence to team chain state. We // have an upgrade path in the code that we'd like to test. TeamNoHeadMerkleStore bool // TeamSkipAudit is on because some team chains are "canned" and therefore // might point off of the merkle sequence in the database. So it's just // easiest to skip the audit in those cases. TeamSkipAudit bool // NoGregor is on if we want to test the service without any gregor connection NoGregor bool // TeamAuditParams can be customized if we want to control the behavior // of audits deep in a test TeamAuditParams *TeamAuditParams // Toggle if we want to try to 'prime' the secret store before using it. SecretStorePrimingDisabled bool // Extra headers for API APIHeaders map[string]string } func (tp TestParameters) GetDebug() (bool, bool) { if tp.Debug { return true, true } return false, false } func (tp TestParameters) GetNoGregor() (bool, bool) { if tp.NoGregor { return true, true } return false, false } func (tp TestParameters) GetSecretStorePrimingDisabled() (bool, bool) { if tp.SecretStorePrimingDisabled { return true, true } return false, false } type Env struct { sync.RWMutex cmd CommandLine config ConfigReader HomeFinder HomeFinder writer ConfigWriter Test *TestParameters updaterConfig UpdaterConfigReader guiConfig *JSONFile } func (e *Env) GetConfig() ConfigReader { e.RLock() defer e.RUnlock() return e.config } func (e *Env) GetConfigWriter() ConfigWriter { e.RLock() defer e.RUnlock() return e.writer } func (e *Env) SetCommandLine(cmd CommandLine) { e.Lock() defer e.Unlock() e.cmd = cmd } func (e *Env) GetCommandLine() CommandLine { e.RLock() defer e.RUnlock() return e.cmd } func (e *Env) SetConfig(r ConfigReader, w ConfigWriter) { e.Lock() defer e.Unlock() e.config = r e.writer = w } func (e *Env) SetGUIConfig(j *JSONFile) { e.Lock() defer e.Unlock() e.guiConfig = j } func (e *Env) GetGUIConfig() *JSONFile { e.RLock() defer e.RUnlock() return e.guiConfig } func (e *Env) SetUpdaterConfig(r UpdaterConfigReader) { e.Lock() defer e.Unlock() e.updaterConfig = r } func (e *Env) GetUpdaterConfig() UpdaterConfigReader { e.RLock() defer e.RUnlock() return e.updaterConfig } func (e *Env) GetOldMountDirDefault() string { switch RuntimeGroup() { case keybase1.RuntimeGroup_LINUXLIKE: return filepath.Join(e.GetDataDir(), "fs") default: return e.GetMountDirDefault() } } func (e *Env) GetMountDirDefault() string { switch RuntimeGroup() { case keybase1.RuntimeGroup_DARWINLIKE: volumes := "/Volumes" user, err := user.Current() var username string if err != nil { // The iOS simulator may not have a proper user set, username = "<unknown>" } else { username = user.Username } var runmodeName string switch e.GetRunMode() { case DevelRunMode: runmodeName = "KeybaseDevel" case StagingRunMode: runmodeName = "KeybaseStaging" case ProductionRunMode: runmodeName = "Keybase" default: panic("Invalid run mode") } return filepath.Join(volumes, fmt.Sprintf( "%s (%s)", runmodeName, username)) case keybase1.RuntimeGroup_LINUXLIKE: return filepath.Join(e.GetRuntimeDir(), "kbfs") // kbfsdokan depends on an empty default case keybase1.RuntimeGroup_WINDOWSLIKE: return "" default: return filepath.Join(e.GetRuntimeDir(), "kbfs") } } func (e *Env) GetMountDir() (string, error) { return e.GetString( func() string { return e.cmd.GetMountDir() }, func() string { return os.Getenv("KEYBASE_MOUNTDIR") }, func() string { return e.GetConfig().GetMountDir() }, e.GetMountDirDefault, ), nil } func NewEnv(cmd CommandLine, config ConfigReader, getLog LogGetter) *Env { return newEnv(cmd, config, runtime.GOOS, getLog) } func newEnv(cmd CommandLine, config ConfigReader, osname string, getLog LogGetter) *Env { if cmd == nil { cmd = NullConfiguration{} } if config == nil { config = NullConfiguration{} } e := Env{cmd: cmd, config: config, Test: &TestParameters{}} e.HomeFinder = NewHomeFinder("keybase", e.getHomeFromTestOrCmd, func() string { return e.GetConfig().GetHome() }, e.getMobileSharedHomeFromCmdOrConfig, osname, e.GetRunMode, getLog, os.Getenv) return &e } func (e *Env) getHomeFromTestOrCmd() string { return e.GetString( func() string { return e.Test.Home }, func() string { home := e.cmd.GetHome() if home == "" { return "" } absHome, err := filepath.Abs(home) if err != nil { return home } return absHome }, ) } func (e *Env) getMobileSharedHomeFromCmdOrConfig() string { return e.GetString( func() string { return e.Test.MobileSharedHome }, func() string { return e.cmd.GetMobileSharedHome() }, func() string { return e.GetConfig().GetMobileSharedHome() }, ) } func (e *Env) GetDownloadsDir() string { return e.HomeFinder.DownloadsDir() } func (e *Env) GetHome() string { return e.HomeFinder.Home(false) } func (e *Env) GetMobileSharedHome() string { return e.HomeFinder.MobileSharedHome(false) } func (e *Env) GetConfigDir() string { return e.HomeFinder.ConfigDir() } func (e *Env) GetCacheDir() string { return e.HomeFinder.CacheDir() } func (e *Env) GetSharedCacheDir() string { return e.HomeFinder.SharedCacheDir() } func (e *Env) GetSandboxCacheDir() string { return e.HomeFinder.SandboxCacheDir() } func (e *Env) GetDataDir() string { return e.HomeFinder.DataDir() } func (e *Env) GetSharedDataDir() string { return e.HomeFinder.SharedDataDir() } func (e *Env) GetLogDir() string { return e.HomeFinder.LogDir() } func (e *Env) SendSystemChatMessages() bool { return !e.Test.SkipSendingSystemChatMessages } func (e *Env) UseTimeClockForNISTs() bool { return e.Test.UseTimeClockForNISTs } func (e *Env) GetRuntimeDir() string { return e.GetString( func() string { return e.Test.RuntimeDir }, func() string { return e.HomeFinder.RuntimeDir() }, ) } func (e *Env) GetInfoDir() string { return e.GetString( func() string { return e.Test.RuntimeDir }, // needed for systests func() string { return e.HomeFinder.InfoDir() }, ) } func (e *Env) GetServiceSpawnDir() (string, error) { return e.HomeFinder.ServiceSpawnDir() } func (e *Env) getEnvInt(s string) (int, bool) { v := os.Getenv(s) if len(v) > 0 { tmp, err := strconv.ParseInt(v, 0, 64) if err == nil { return int(tmp), true } } return 0, false } func (e *Env) getEnvPath(s string) []string { if tmp := os.Getenv(s); len(tmp) != 0 { return strings.Split(tmp, ":") } return nil } func (e *Env) getEnvBool(s string) (bool, bool) { return getEnvBool(s) } func getEnvBool(s string) (bool, bool) { tmp := os.Getenv(s) if len(tmp) == 0 { return false, false } tmp = strings.ToLower(tmp) if tmp == "0" || tmp[0] == byte('n') { return false, true } return true, true } func (e *Env) getEnvDuration(s string) (time.Duration, bool) { d, err := time.ParseDuration(os.Getenv(s)) if err != nil { return 0, false } return d, true } func (e *Env) GetString(flist ...(func() string)) string { var ret string for _, f := range flist { ret = f() if len(ret) > 0 { break } } return ret } func (e *Env) GetBool(def bool, flist ...func() (bool, bool)) bool { for _, f := range flist { if val, isSet := f(); isSet { return val } } return def } type NegBoolFunc struct { neg bool f func() (bool, bool) } // GetNegBool gets a negatable bool. You can give it a list of functions, // and also possible negations for those functions. func (e *Env) GetNegBool(def bool, flist []NegBoolFunc) bool { for _, f := range flist { if val, isSet := f.f(); isSet { return (val != f.neg) } } return def } func (e *Env) GetInt(def int, flist ...func() (int, bool)) int { for _, f := range flist { if val, isSet := f(); isSet { return val } } return def } func (e *Env) GetDuration(def time.Duration, flist ...func() (time.Duration, bool)) time.Duration { for _, f := range flist { if val, isSet := f(); isSet { return val } } return def } func (e *Env) GetServerURI() (string, error) { // appveyor and os x travis CI set server URI, so need to // check for test flag here in order for production api endpoint // tests to pass. if e.Test.UseProductionRunMode { server, e := ServerLookup(e, e.GetRunMode()) if e != nil { return "", nil } return server, nil } serverURI := e.GetString( func() string { serverURI, err := e.cmd.GetServerURI() if err != nil { return "" } return serverURI }, func() string { return os.Getenv("KEYBASE_SERVER_URI") }, func() string { serverURI, err := e.GetConfig().GetServerURI() if err != nil { return "" } return serverURI }, func() string { serverURI, err := ServerLookup(e, e.GetRunMode()) if err != nil { return "" } return serverURI }, ) if serverURI == "" { return "", fmt.Errorf("Env failed to read a server URI from any source!") } return serverURI, nil } func (e *Env) GetUseRootConfigFile() bool { return e.GetBool(false, e.cmd.GetUseRootConfigFile) } func (e *Env) GetRootRedirectorMount() (string, error) { switch RuntimeGroup() { case keybase1.RuntimeGroup_LINUXLIKE, keybase1.RuntimeGroup_DARWINLIKE: return "/keybase", nil default: return "", fmt.Errorf("Root redirector mount unknown on this system.") } } func (e *Env) GetRootConfigDirectory() (string, error) { // NOTE: If this ever changes to more than one level deep, the configure // redirector CLI command needs to be updated to update the permissions // back to 0644 for all the created directories, or other processes won't // be able to read them. // Alternatively, we could package a blank config.json in that directory, // but we can't rely on that for other packages. switch RuntimeGroup() { case keybase1.RuntimeGroup_LINUXLIKE: return "/etc/keybase/", nil default: return "", fmt.Errorf("Root config directory unknown on this system") } } func (e *Env) GetRootConfigFilename() (string, error) { dir, err := e.GetRootConfigDirectory() if err != nil { return "", err } return filepath.Join(dir, "config.json"), nil } func (e *Env) GetEnvFileDir() (string, error) { switch RuntimeGroup() { case keybase1.RuntimeGroup_LINUXLIKE: // Do not respect $XDG_CONFIG_HOME due to debian systemd 229 not supporting %E // see keybase.service systemd unit return filepath.Join(e.GetHome(), ".config", "keybase"), nil default: return "", fmt.Errorf("No envfiledir for %s.", runtime.GOOS) } } func (e *Env) GetEnvfileName() (string, error) { dir, err := e.GetEnvFileDir() if err != nil { return "", err } return filepath.Join(dir, "keybase.autogen.env"), nil } func (e *Env) GetOverrideEnvfileName() (string, error) { dir, err := e.GetEnvFileDir() if err != nil { return "", err } return filepath.Join(dir, "keybase.env"), nil } func (e *Env) GetConfigFilename() string { return e.GetString( func() string { if e.GetUseRootConfigFile() { ret, err := e.GetRootConfigFilename() if err != nil { return "" } return ret } return "" }, func() string { return e.Test.ConfigFilename }, func() string { return e.cmd.GetConfigFilename() }, func() string { return os.Getenv("KEYBASE_CONFIG_FILE") }, func() string { return e.GetConfig().GetConfigFilename() }, func() string { return filepath.Join(e.GetConfigDir(), ConfigFile) }, ) } func (e *Env) GetUpdaterConfigFilename() string { return e.GetString( func() string { if e.GetUseRootConfigFile() { dir, err := e.GetRootConfigDirectory() if err != nil { return "" } return filepath.Join(dir, UpdaterConfigFile) } return "" }, func() string { return e.cmd.GetUpdaterConfigFilename() }, func() string { return os.Getenv("KEYBASE_UPDATER_CONFIG_FILE") }, func() string { return e.GetConfig().GetUpdaterConfigFilename() }, func() string { return filepath.Join(e.GetConfigDir(), UpdaterConfigFile) }, ) } func (e *Env) GetGUIConfigFilename() string { return e.GetString( func() string { if e.GetUseRootConfigFile() { dir, err := e.GetRootConfigDirectory() if err != nil { return "" } return filepath.Join(dir, GUIConfigFile) } return "" }, func() string { return e.cmd.GetGUIConfigFilename() }, func() string { return os.Getenv("KEYBASE_GUI_CONFIG_FILE") }, func() string { return e.GetConfig().GetGUIConfigFilename() }, func() string { return filepath.Join(e.GetConfigDir(), GUIConfigFile) }, ) } func (e *Env) GetDeviceCloneStateFilename() string { return e.GetString( func() string { return e.cmd.GetDeviceCloneStateFilename() }, func() string { return os.Getenv("KEYBASE_DEVICE_CLONE_STATE_FILE") }, func() string { return e.GetConfig().GetDeviceCloneStateFilename() }, func() string { return filepath.Join(e.GetConfigDir(), DeviceCloneStateFile) }, ) } func (e *Env) GetSessionFilename() string { return e.GetString( func() string { return e.cmd.GetSessionFilename() }, func() string { return os.Getenv("KEYBASE_SESSION_FILE") }, func() string { return e.GetConfig().GetSessionFilename() }, func() string { return filepath.Join(e.GetCacheDir(), SessionFile) }, ) } func (e *Env) GetDbFilename() string { return e.GetString( func() string { return e.cmd.GetDbFilename() }, func() string { return os.Getenv("KEYBASE_DB_FILE") }, func() string { return e.GetConfig().GetDbFilename() }, func() string { return filepath.Join(e.GetDataDir(), DBFile) }, ) } func (e *Env) GetChatDbFilename() string { return e.GetString( func() string { return e.cmd.GetChatDbFilename() }, func() string { return os.Getenv("KEYBASE_CHAT_DB_FILE") }, func() string { return e.GetConfig().GetChatDbFilename() }, func() string { return filepath.Join(e.GetDataDir(), ChatDBFile) }, ) } // GetPvlKitFilename gets the path to pvl kit file. // Its value is usually "" which means to use the server. func (e *Env) GetPvlKitFilename() string { return e.GetString( func() string { return e.cmd.GetPvlKitFilename() }, func() string { return os.Getenv("KEYBASE_PVL_KIT_FILE") }, func() string { return e.GetConfig().GetPvlKitFilename() }, ) } // GetParamProofKitFilename gets the path to param proof kit file. Its value // is usually "" which means to use the server. func (e *Env) GetParamProofKitFilename() string { return e.GetString( func() string { return e.cmd.GetParamProofKitFilename() }, func() string { return os.Getenv("KEYBASE_PARAM_PROOF_KIT_FILE") }, func() string { return e.GetConfig().GetParamProofKitFilename() }, ) } // GetExternalURLKitFilename gets the path to param proof kit file. Its value // is usually "" which means to use the server. func (e *Env) GetExternalURLKitFilename() string { return e.GetString( func() string { return e.cmd.GetExternalURLKitFilename() }, func() string { return os.Getenv("KEYBASE_EXTERNAL_URL_KIT_FILE") }, func() string { return e.GetConfig().GetExternalURLKitFilename() }, ) } // GetProveBypass ignores creation_disabled so that the client will let the user // try to make a proof for any known service. func (e *Env) GetProveBypass() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetProveBypass() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_PROVE_BYPASS") }, func() (bool, bool) { return e.GetConfig().GetProveBypass() }) } // GetDebugJourneycard enables experimental chat journey cards. func (e *Env) GetDebugJourneycard() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetDebugJourneycard() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_DEBUG_JOURNEYCARD") }, func() (bool, bool) { return e.GetConfig().GetDebugJourneycard() }) } func (e *Env) GetDebug() bool { return e.GetBool(false, func() (bool, bool) { return e.Test.GetDebug() }, func() (bool, bool) { return e.cmd.GetDebug() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_DEBUG") }, func() (bool, bool) { return e.GetConfig().GetDebug() }, ) } func (e *Env) GetDisplayRawUntrustedOutput() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetDisplayRawUntrustedOutput() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_DISPLAY_RAW_UNTRUSTED_OUTPUT") }, func() (bool, bool) { return e.GetConfig().GetDisplayRawUntrustedOutput() }, ) } func (e *Env) GetAutoFork() bool { // On !Darwin, we auto-fork by default def := (runtime.GOOS != "darwin") return e.GetNegBool(def, []NegBoolFunc{ { neg: false, f: func() (bool, bool) { return e.cmd.GetAutoFork() }, }, { neg: true, f: func() (bool, bool) { return e.cmd.GetNoAutoFork() }, }, { neg: false, f: func() (bool, bool) { return e.getEnvBool("KEYBASE_AUTO_FORK") }, }, { neg: true, f: func() (bool, bool) { return e.getEnvBool("KEYBASE_NO_AUTO_FORK") }, }, { neg: false, f: func() (bool, bool) { return e.GetConfig().GetAutoFork() }, }, }, ) } func (e *Env) GetStandalone() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetStandalone() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_STANDALONE") }, func() (bool, bool) { return e.GetConfig().GetStandalone() }, ) } func (e *Env) GetLogFormat() string { return e.GetString( func() string { return e.cmd.GetLogFormat() }, func() string { return os.Getenv("KEYBASE_LOG_FORMAT") }, func() string { return e.GetConfig().GetLogFormat() }, ) } func (e *Env) GetLabel() string { return e.GetString( func() string { return e.cmd.GetString("label") }, func() string { return os.Getenv("KEYBASE_LABEL") }, ) } func (e *Env) GetServiceType() string { return e.GetString( func() string { return os.Getenv("KEYBASE_SERVICE_TYPE") }, ) } func (e *Env) GetAPIDump() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetAPIDump() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_API_DUMP") }, ) } func (e *Env) GetAllowRoot() bool { return e.GetBool(false, func() (bool, bool) { return e.getEnvBool("KEYBASE_ALLOW_ROOT") }, ) } func (e *Env) GetUsername() NormalizedUsername { return e.GetConfig().GetUsername() } func (e *Env) GetSocketBindFile() (string, error) { return e.GetString( e.sandboxSocketFile, e.defaultSocketFile, ), nil } func (e *Env) defaultSocketFile() string { socketFile := e.GetString( func() string { return e.cmd.GetSocketFile() }, func() string { return os.Getenv("KEYBASE_SOCKET_FILE") }, func() string { return e.GetConfig().GetSocketFile() }, ) if socketFile == "" { socketFile = filepath.Join(e.GetRuntimeDir(), SocketFile) } return socketFile } // sandboxSocketFile is socket file location for sandbox (macOS only) // Note: this was added for KBFS finder integration, which was never // activated. func (e *Env) sandboxSocketFile() string { sandboxCacheDir := e.HomeFinder.SandboxCacheDir() if sandboxCacheDir == "" { return "" } return filepath.Join(sandboxCacheDir, SocketFile) } func (e *Env) GetSocketDialFiles() ([]string, error) { dialFiles := []string{} sandboxSocketFile := e.sandboxSocketFile() if sandboxSocketFile != "" { dialFiles = append(dialFiles, sandboxSocketFile) } dialFiles = append(dialFiles, e.defaultSocketFile()) return dialFiles, nil } func (e *Env) GetGregorURI() string { return e.GetString( func() string { return os.Getenv("KEYBASE_PUSH_SERVER_URI") }, func() string { return e.GetConfig().GetGregorURI() }, func() string { return e.cmd.GetGregorURI() }, func() string { return GregorServerLookup[e.GetRunMode()] }, ) } func (e *Env) GetGregorSaveInterval() time.Duration { return e.GetDuration(time.Minute, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_PUSH_SAVE_INTERVAL") }, func() (time.Duration, bool) { return e.GetConfig().GetGregorSaveInterval() }, func() (time.Duration, bool) { return e.cmd.GetGregorSaveInterval() }, ) } func (e *Env) GetGregorDisabled() bool { return e.GetBool(false, func() (bool, bool) { return e.Test.GetNoGregor() }, func() (bool, bool) { return e.cmd.GetGregorDisabled() }, func() (bool, bool) { return getEnvBool("KEYBASE_PUSH_DISABLED") }, func() (bool, bool) { return e.GetConfig().GetGregorDisabled() }, ) } func (e *Env) GetSecretStorePrimingDisabled() bool { return e.GetBool(false, func() (bool, bool) { return e.Test.GetSecretStorePrimingDisabled() }, ) } func (e *Env) GetBGIdentifierDisabled() bool { return e.GetBool(true, func() (bool, bool) { return e.cmd.GetBGIdentifierDisabled() }, func() (bool, bool) { return getEnvBool("KEYBASE_BG_IDENTIFIER_DISABLED") }, func() (bool, bool) { return e.GetConfig().GetBGIdentifierDisabled() }, ) } func (e *Env) GetGregorPingInterval() time.Duration { return e.GetDuration(10*time.Second, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_PUSH_PING_INTERVAL") }, func() (time.Duration, bool) { return e.GetConfig().GetGregorPingInterval() }, func() (time.Duration, bool) { return e.cmd.GetGregorPingInterval() }, ) } func (e *Env) GetGregorPingTimeout() time.Duration { return e.GetDuration(5*time.Second, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_PUSH_PING_TIMEOUT") }, func() (time.Duration, bool) { return e.GetConfig().GetGregorPingTimeout() }, func() (time.Duration, bool) { return e.cmd.GetGregorPingTimeout() }, ) } func (e *Env) GetChatDelivererInterval() time.Duration { return e.GetDuration(5*time.Second, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_CHAT_DELIVERER_INTERVAL") }, func() (time.Duration, bool) { return e.GetConfig().GetChatDelivererInterval() }, func() (time.Duration, bool) { return e.cmd.GetChatDelivererInterval() }, ) } func (e *Env) GetAttachmentHTTPStartPort() int { return e.GetInt(16423, e.cmd.GetAttachmentHTTPStartPort, func() (int, bool) { return e.getEnvInt("KEYBASE_ATTACHMENT_HTTP_START") }, e.GetConfig().GetAttachmentHTTPStartPort, ) } func (e *Env) GetAttachmentDisableMulti() bool { return e.GetBool(false, e.cmd.GetAttachmentDisableMulti, func() (bool, bool) { return e.getEnvBool("KEYBASE_ATTACHMENT_DISABLE_MULTI") }, e.GetConfig().GetAttachmentDisableMulti, ) } func (e *Env) GetDisableTeamAuditor() bool { return e.GetBool(false, e.cmd.GetDisableTeamAuditor, func() (bool, bool) { return e.getEnvBool("KEYBASE_DISABLE_TEAM_AUDITOR") }, e.GetConfig().GetDisableTeamAuditor, // If unset, use the BotLite setting func() (bool, bool) { return e.GetEnableBotLiteMode(), true }, ) } func (e *Env) GetDisableTeamBoxAuditor() bool { return e.GetBool(false, e.cmd.GetDisableTeamBoxAuditor, func() (bool, bool) { return e.getEnvBool("KEYBASE_DISABLE_TEAM_BOX_AUDITOR") }, e.GetConfig().GetDisableTeamBoxAuditor, // If unset, use the BotLite setting func() (bool, bool) { return e.GetEnableBotLiteMode(), true }, ) } func (e *Env) GetDisableEKBackgroundKeygen() bool { return e.GetBool(false, e.cmd.GetDisableEKBackgroundKeygen, func() (bool, bool) { return e.getEnvBool("KEYBASE_DISABLE_EK_BACKGROUND_KEYGEN") }, e.GetConfig().GetDisableEKBackgroundKeygen, ) } func (e *Env) GetDisableMerkleAuditor() bool { return e.GetBool(false, e.cmd.GetDisableMerkleAuditor, func() (bool, bool) { return e.getEnvBool("KEYBASE_DISABLE_MERKLE_AUDITOR") }, e.GetConfig().GetDisableMerkleAuditor, // If unset, use the BotLite setting func() (bool, bool) { return e.GetEnableBotLiteMode(), true }, ) } func (e *Env) GetDisableSearchIndexer() bool { return e.GetBool(false, e.cmd.GetDisableSearchIndexer, func() (bool, bool) { return e.getEnvBool("KEYBASE_DISABLE_SEARCH_INDEXER") }, e.GetConfig().GetDisableSearchIndexer, // If unset, use the BotLite setting func() (bool, bool) { return e.GetEnableBotLiteMode(), true }, ) } func (e *Env) GetDisableBgConvLoader() bool { return e.GetBool(false, e.cmd.GetDisableBgConvLoader, func() (bool, bool) { return e.getEnvBool("KEYBASE_DISABLE_BG_CONV_LOADER") }, e.GetConfig().GetDisableBgConvLoader, // If unset, use the BotLite setting func() (bool, bool) { return e.GetEnableBotLiteMode(), true }, ) } func (e *Env) GetEnableBotLiteMode() bool { return e.GetBool(false, e.cmd.GetEnableBotLiteMode, func() (bool, bool) { return e.getEnvBool("KEYBASE_ENABLE_BOT_LITE_MODE") }, e.GetConfig().GetEnableBotLiteMode, ) } func (e *Env) GetExtraNetLogging() bool { return e.GetBool(false, e.cmd.GetExtraNetLogging, func() (bool, bool) { return e.getEnvBool("KEYBASE_EXTRA_NET_LOGGING") }, e.GetConfig().GetExtraNetLogging, ) } func (e *Env) GetPidFile() (ret string, err error) { ret = e.GetString( func() string { return e.cmd.GetPidFile() }, func() string { return os.Getenv("KEYBASE_PID_FILE") }, func() string { return e.GetConfig().GetPidFile() }, ) if len(ret) == 0 { ret = filepath.Join(e.GetInfoDir(), PIDFile) } return } func (e *Env) GetEmail() string { return e.GetString( func() string { return os.Getenv("KEYBASE_EMAIL") }, ) } func (e *Env) GetStayLoggedOut() bool { return e.GetBool(false, func() (bool, bool) { return e.GetConfig().GetStayLoggedOut() }, ) } // Upgrade sigchains to contain per-user-keys. func (e *Env) GetUpgradePerUserKey() bool { return !e.Test.DisableUpgradePerUserKey } // If true, do not logout after user.key_change notification handler // decides that current device has been revoked. func (e *Env) GetSkipLogoutIfRevokedCheck() bool { return e.Test.SkipLogoutIfRevokedCheck } // Get the ProxyType based off of the configured proxy and tor settings func (e *Env) GetProxyType() ProxyType { if e.GetTorMode() != TorNone { // Tor mode is enabled. Tor mode is implemented via a socks proxy return Socks } proxyTypeStr := e.GetString( func() string { return e.cmd.GetProxyType() }, func() string { return os.Getenv("PROXY_TYPE") }, func() string { return e.GetConfig().GetProxyType() }, ) return ProxyTypeStrToEnumFunc(proxyTypeStr) } func ProxyTypeStrToEnumFunc(proxyTypeStr string) ProxyType { proxyType, ok := ProxyTypeStrToEnum[strings.ToLower(proxyTypeStr)] if ok { return proxyType } // If they give us a bogus proxy type we just don't enable a proxy return NoProxy } // Get the address (optionally including a port) of the currently configured proxy. Returns an empty string if no proxy // is configured. func (e *Env) GetProxy() string { return e.GetString( func() string { // Only return the tor proxy address if tor mode is enabled to ensure we fall through to the other options if e.GetTorMode() != TorNone { return e.GetTorProxy() } return "" }, // Prioritze tor mode over configured proxies func() string { return e.cmd.GetProxy() }, func() string { return e.GetConfig().GetProxy() }, func() string { return os.Getenv("PROXY") }, // Prioritize the keybase specific methods of configuring a proxy above the standard unix env variables func() string { return os.Getenv("HTTPS_PROXY") }, func() string { return os.Getenv("HTTP_PROXY") }, ) } func (e *Env) IsCertPinningEnabled() bool { // SSL Pinning is enabled if none of the config options say it is disabled if !e.cmd.IsCertPinningEnabled() { return false } res, isSet := e.getEnvBool("DISABLE_SSL_PINNING") if isSet && res { return false } if !e.GetConfig().IsCertPinningEnabled() { return false } return true } func (e *Env) GetGpgHome() string { return e.GetString( func() string { return e.Test.GPGHome }, func() string { return e.cmd.GetGpgHome() }, func() string { return os.Getenv("GNUPGHOME") }, func() string { return e.GetConfig().GetGpgHome() }, func() string { return filepath.Join(e.GetHome(), ".gnupg") }, ) } func (e *Env) GetPinentry() string { return e.GetString( func() string { return e.cmd.GetPinentry() }, func() string { return os.Getenv("KEYBASE_PINENTRY") }, func() string { return e.GetConfig().GetPinentry() }, ) } func (e *Env) GetNoPinentry() bool { isno := func(s string) (bool, bool) { s = strings.ToLower(s) if s == "0" || s == "no" || s == "n" || s == "none" { return true, true } return false, false } return e.GetBool(false, func() (bool, bool) { return isno(e.cmd.GetPinentry()) }, func() (bool, bool) { return isno(os.Getenv("KEYBASE_PINENTRY")) }, func() (bool, bool) { return e.GetConfig().GetNoPinentry() }, ) } func (e *Env) GetBundledCA(host string) string { return e.GetString( func() string { return e.GetConfig().GetBundledCA(host) }, func() string { ret, ok := GetBundledCAsFromHost(host) if !ok { return "" } return string(ret) }, ) } func (e *Env) GetUserCacheMaxAge() time.Duration { return e.GetDuration(UserCacheMaxAge, func() (time.Duration, bool) { return e.cmd.GetUserCacheMaxAge() }, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_USER_CACHE_MAX_AGE") }, func() (time.Duration, bool) { return e.GetConfig().GetUserCacheMaxAge() }, ) } func (e *Env) GetAPITimeout() time.Duration { return e.GetDuration(HTTPDefaultTimeout, func() (time.Duration, bool) { return e.cmd.GetAPITimeout() }, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_API_TIMEOUT") }, func() (time.Duration, bool) { return e.GetConfig().GetAPITimeout() }, ) } func (e *Env) GetScraperTimeout() time.Duration { return e.GetDuration(HTTPDefaultScraperTimeout, func() (time.Duration, bool) { return e.cmd.GetScraperTimeout() }, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_SCRAPER_TIMEOUT") }, func() (time.Duration, bool) { return e.GetConfig().GetScraperTimeout() }, ) } func (e *Env) GetLocalTrackMaxAge() time.Duration { return e.GetDuration(LocalTrackMaxAge, func() (time.Duration, bool) { return e.cmd.GetLocalTrackMaxAge() }, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_LOCAL_TRACK_MAX_AGE") }, func() (time.Duration, bool) { return e.GetConfig().GetLocalTrackMaxAge() }, ) } func (e *Env) GetProofCacheSize() int { return e.GetInt(ProofCacheSize, e.cmd.GetProofCacheSize, func() (int, bool) { return e.getEnvInt("KEYBASE_PROOF_CACHE_SIZE") }, e.GetConfig().GetProofCacheSize, ) } func (e *Env) GetProofCacheLongDur() time.Duration { return e.GetDuration(ProofCacheLongDur, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_PROOF_CACHE_LONG_DUR") }, e.GetConfig().GetProofCacheLongDur, ) } func (e *Env) GetProofCacheMediumDur() time.Duration { return e.GetDuration(ProofCacheMediumDur, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_PROOF_CACHE_MEDIUM_DUR") }, e.GetConfig().GetProofCacheMediumDur, ) } func (e *Env) GetProofCacheShortDur() time.Duration { return e.GetDuration(ProofCacheShortDur, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_PROOF_CACHE_SHORT_DUR") }, e.GetConfig().GetProofCacheShortDur, ) } func (e *Env) GetLinkCacheSize() int { return e.GetInt(LinkCacheSize, e.cmd.GetLinkCacheSize, func() (int, bool) { return e.getEnvInt("KEYBASE_LINK_CACHE_SIZE") }, e.GetConfig().GetLinkCacheSize, ) } func (e *Env) GetUPAKCacheSize() int { return e.GetInt(UPAKCacheSize, e.cmd.GetUPAKCacheSize, func() (int, bool) { return e.getEnvInt("KEYBASE_UPAK_CACHE_SIZE") }, e.GetConfig().GetUPAKCacheSize, ) } func (e *Env) GetUIDMapFullNameCacheSize() int { return e.GetInt(UIDMapFullNameCacheSize, e.cmd.GetUIDMapFullNameCacheSize, func() (int, bool) { return e.getEnvInt("KEYBASE_UID_MAP_FULL_NAME_CACHE_SIZE") }, e.GetConfig().GetUIDMapFullNameCacheSize, ) } func (e *Env) GetLevelDBNumFiles() int { return e.GetInt(LevelDBNumFiles, e.cmd.GetLevelDBNumFiles, func() (int, bool) { return e.getEnvInt("KEYBASE_LEVELDB_NUM_FILES") }, e.GetConfig().GetLevelDBNumFiles, ) } func (e *Env) GetLevelDBWriteBufferMB() int { return e.GetInt(LevelDBWriteBufferMB, e.cmd.GetLevelDBWriteBufferMB, func() (int, bool) { return e.getEnvInt("KEYBASE_LEVELDB_WRITE_BUFFER_MB") }, e.GetConfig().GetLevelDBWriteBufferMB, ) } func (e *Env) GetLinkCacheCleanDur() time.Duration { return e.GetDuration(LinkCacheCleanDur, func() (time.Duration, bool) { return e.getEnvDuration("KEYBASE_LINK_CACHE_CLEAN_DUR") }, e.GetConfig().GetLinkCacheCleanDur, ) } func (e *Env) GetPayloadCacheSize() int { return e.GetInt(PayloadCacheSize, e.cmd.GetPayloadCacheSize, func() (int, bool) { return e.getEnvInt("KEYBASE_PAYLOAD_CACHE_SIZE") }, e.GetConfig().GetPayloadCacheSize, ) } func (e *Env) GetEmailOrUsername() string { un := e.GetUsername().String() if len(un) > 0 { return un } em := e.GetEmail() return em } func (e *Env) GetRunMode() RunMode { // If testing production run mode, then use it: if e.Test.UseProductionRunMode { return ProductionRunMode } var ret RunMode pick := func(m RunMode, err error) { if ret == NoRunMode && err == nil { ret = m } } pick(e.cmd.GetRunMode()) pick(StringToRunMode(os.Getenv("KEYBASE_RUN_MODE"))) pick(e.GetConfig().GetRunMode()) pick(DefaultRunMode, nil) // If we aren't running in devel or staging and we're testing. Let's run in devel. if e.Test.Devel && ret != DevelRunMode && ret != StagingRunMode { return DevelRunMode } return ret } func (e *Env) GetAppType() AppType { switch { case e.cmd.GetAppType() != NoAppType: return e.cmd.GetAppType() case StringToAppType(os.Getenv("KEYBASE_APP_TYPE")) != NoAppType: return StringToAppType(os.Getenv("KEYBASE_APP_TYPE")) case e.GetConfig().GetAppType() != NoAppType: return e.GetConfig().GetAppType() default: return NoAppType } } func (e *Env) IsMobileExtension() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.IsMobileExtension() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_MOBILE_EXTENSION") }, func() (bool, bool) { return e.GetConfig().IsMobileExtension() }, ) } func (e *Env) GetSlowGregorConn() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetSlowGregorConn() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_SLOW_GREGOR_CONN") }, func() (bool, bool) { return e.GetConfig().GetSlowGregorConn() }, ) } func (e *Env) GetReadDeletedSigChain() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetReadDeletedSigChain() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_READ_DELETED_SIGCHAIN") }, func() (bool, bool) { return e.GetConfig().GetReadDeletedSigChain() }, ) } func (e *Env) GetFeatureFlags() FeatureFlags { var ret FeatureFlags pick := func(f FeatureFlags, err error) { if ret.Empty() && err == nil { ret = f } } if e.Test.EnvironmentFeatureFlags != nil { pick(e.Test.EnvironmentFeatureFlags, nil) } pick(e.cmd.GetFeatureFlags()) pick(StringToFeatureFlags(os.Getenv("KEYBASE_FEATURES")), nil) pick(e.GetConfig().GetFeatureFlags()) return ret } func (e *Env) GetUID() keybase1.UID { return e.GetConfig().GetUID() } func (e *Env) GetStringList(list ...(func() []string)) []string { for _, f := range list { if res := f(); res != nil { return res } } return []string{} } func (e *Env) GetMerkleKIDs() []keybase1.KID { slist := e.GetStringList( func() []string { return e.cmd.GetMerkleKIDs() }, func() []string { return e.getEnvPath("KEYBASE_MERKLE_KIDS") }, func() []string { return e.GetConfig().GetMerkleKIDs() }, func() []string { ret := MerkleProdKIDs if e.GetRunMode() == DevelRunMode || e.GetRunMode() == StagingRunMode { ret = append(ret, MerkleTestKIDs...) ret = append(ret, MerkleStagingKIDs...) } return ret }, ) if slist == nil { return nil } var ret []keybase1.KID for _, s := range slist { ret = append(ret, keybase1.KIDFromString(s)) } return ret } func (e *Env) GetCodeSigningKIDs() []keybase1.KID { slist := e.GetStringList( func() []string { return e.cmd.GetCodeSigningKIDs() }, func() []string { return e.getEnvPath("KEYBASE_CODE_SIGNING_KIDS") }, func() []string { return e.GetConfig().GetCodeSigningKIDs() }, func() []string { ret := CodeSigningProdKIDs if e.GetRunMode() == DevelRunMode || e.GetRunMode() == StagingRunMode { ret = append(ret, CodeSigningTestKIDs...) ret = append(ret, CodeSigningStagingKIDs...) } return ret }, ) if slist == nil { return nil } var ret []keybase1.KID for _, s := range slist { ret = append(ret, keybase1.KIDFromString(s)) } return ret } func (e *Env) GetGpg() string { return e.GetString( func() string { return e.Test.GPG }, func() string { return e.cmd.GetGpg() }, func() string { return os.Getenv("GPG") }, func() string { return e.GetConfig().GetGpg() }, ) } func (e *Env) GetGpgOptions() []string { return e.GetStringList( func() []string { return e.Test.GPGOptions }, func() []string { return e.cmd.GetGpgOptions() }, func() []string { return e.GetConfig().GetGpgOptions() }, ) } func (e *Env) GetSecretKeyringTemplate() string { return e.GetString( func() string { return e.cmd.GetSecretKeyringTemplate() }, func() string { return os.Getenv("KEYBASE_SECRET_KEYRING_TEMPLATE") }, func() string { return e.GetConfig().GetSecretKeyringTemplate() }, func() string { return filepath.Join(e.GetConfigDir(), SecretKeyringTemplate) }, ) } func (e *Env) GetLocalRPCDebug() string { return e.GetString( func() string { return e.cmd.GetLocalRPCDebug() }, func() string { return os.Getenv("KEYBASE_LOCAL_RPC_DEBUG") }, func() string { return e.GetConfig().GetLocalRPCDebug() }, ) } func (e *Env) GetDoLogForward() bool { return e.GetLocalRPCDebug() == "" } func (e *Env) GetTimers() string { return e.GetString( func() string { return e.cmd.GetTimers() }, func() string { return os.Getenv("KEYBASE_TIMERS") }, func() string { return e.GetConfig().GetTimers() }, ) } func (e *Env) GetConvSourceType() string { return e.GetString( func() string { return os.Getenv("KEYBASE_CONV_SOURCE_TYPE") }, func() string { return "hybrid" }, ) } func (e *Env) GetInboxSourceType() string { return e.GetString( func() string { return os.Getenv("KEYBASE_INBOX_SOURCE_TYPE") }, func() string { return "hybrid" }, ) } func (e *Env) GetChatInboxSourceLocalizeThreads() int { return e.GetInt( 10, e.cmd.GetChatInboxSourceLocalizeThreads, func() (int, bool) { return e.getEnvInt("KEYBASE_INBOX_SOURCE_LOCALIZE_THREADS") }, e.GetConfig().GetChatInboxSourceLocalizeThreads, ) } // GetChatMemberType returns the default member type for new conversations. func (e *Env) GetChatMemberType() string { return e.GetString( func() string { return os.Getenv("KEYBASE_CHAT_MEMBER_TYPE") }, func() string { return "impteam" }, ) } func (e *Env) GetAvatarSource() string { return e.GetString( func() string { return os.Getenv("KEYBASE_AVATAR_SOURCE") }, func() string { return "full" }, ) } func (e *Env) GetDeviceID() keybase1.DeviceID { return e.GetConfig().GetDeviceID() } func (e *Env) GetDeviceIDForUsername(u NormalizedUsername) keybase1.DeviceID { return e.GetConfig().GetDeviceIDForUsername(u) } func (e *Env) GetDeviceIDForUID(u keybase1.UID) keybase1.DeviceID { return e.GetConfig().GetDeviceIDForUID(u) } func (e *Env) GetUsernameForUID(u keybase1.UID) NormalizedUsername { return e.GetConfig().GetUsernameForUID(u) } func (e *Env) GetInstallID() (ret InstallID) { if rdr := e.GetUpdaterConfig(); rdr != nil { ret = rdr.GetInstallID() } return ret } func (e *Env) GetEffectiveLogFile() (filename string, ok bool) { logFile := e.GetLogFile() if logFile != "" { return logFile, true } filePrefix := e.GetLogPrefix() if filePrefix != "" { filePrefix += time.Now().Format("20060102T150405.999999999Z0700") logFile = filePrefix + ".log" return logFile, true } return e.GetDefaultLogFile(), e.GetUseDefaultLogFile() } func (e *Env) GetLogFile() string { return e.GetString( func() string { return e.cmd.GetLogFile() }, func() string { return os.Getenv("KEYBASE_LOG_FILE") }, ) } func (e *Env) GetEKLogFile() string { return e.GetString( func() string { return e.cmd.GetEKLogFile() }, func() string { return os.Getenv("KEYBASE_EK_LOG_FILE") }, func() string { return filepath.Join(e.GetLogDir(), EKLogFileName) }, ) } func (e *Env) GetPerfLogFile() string { return e.GetString( func() string { return e.cmd.GetPerfLogFile() }, func() string { return os.Getenv("KEYBASE_PERF_LOG_FILE") }, func() string { return filepath.Join(e.GetLogDir(), PerfLogFileName) }, ) } func (e *Env) GetGUILogFile() string { return e.GetString( func() string { return e.cmd.GetGUILogFile() }, func() string { return os.Getenv("KEYBASE_GUI_LOG_FILE") }, func() string { return filepath.Join(e.GetLogDir(), GUILogFileName) }, ) } func (e *Env) GetUseDefaultLogFile() bool { return e.GetBool(false, e.cmd.GetUseDefaultLogFile, func() (bool, bool) { return e.getEnvBool("KEYBASE_USE_DEFAULT_LOG_FILE") }, ) } func (e *Env) GetLogPrefix() string { return e.cmd.GetLogPrefix() } func (e *Env) GetDefaultLogFile() string { return filepath.Join(e.GetLogDir(), ServiceLogFileName) } func (e *Env) GetTorMode() TorMode { var ret TorMode pick := func(m TorMode, err error) { if ret == TorNone && err == nil { ret = m } } pick(e.cmd.GetTorMode()) pick(StringToTorMode(os.Getenv("KEYBASE_TOR_MODE"))) pick(e.GetConfig().GetTorMode()) return ret } func (e *Env) GetTorHiddenAddress() string { return e.GetString( func() string { return e.cmd.GetTorHiddenAddress() }, func() string { return os.Getenv("KEYBASE_TOR_HIDDEN_ADDRESS") }, func() string { return e.GetConfig().GetTorHiddenAddress() }, func() string { return TorServerURI }, ) } func (e *Env) GetTorProxy() string { return e.GetString( func() string { return e.cmd.GetTorProxy() }, func() string { return os.Getenv("KEYBASE_TOR_PROXY") }, func() string { return e.GetConfig().GetTorProxy() }, func() string { return TorProxy }, ) } func (e *Env) GetStoredSecretAccessGroup() string { override := e.GetBool( false, func() (bool, bool) { return e.GetConfig().GetSecurityAccessGroupOverride() }, ) if override { return "" } return "99229SGT5K.group.keybase" } func (e *Env) GetStoredSecretServiceBaseName() string { var serviceName string switch e.GetRunMode() { case DevelRunMode: serviceName = "keybase-devel" case StagingRunMode: serviceName = "keybase-staging" case ProductionRunMode: serviceName = "keybase" default: panic("Invalid run mode") } if e.Test.Devel { // Append DevelName so that tests won't clobber each // other's keychain entries on shutdown. serviceName += "-test" } return serviceName } func (e *Env) GetStoredSecretServiceName() string { serviceName := e.GetStoredSecretServiceBaseName() if e.Test.Devel { // Append DevelName so that tests won't clobber each // other's keychain entries on shutdown. serviceName += fmt.Sprintf("(%s)", e.Test.DevelName) } return serviceName } type AppConfig struct { NullConfiguration DownloadsDir string HomeDir string MobileSharedHomeDir string LogFile string EKLogFile string PerfLogFile string GUILogFile string UseDefaultLogFile bool RunMode RunMode Debug bool LocalRPCDebug string ServerURI string VDebugSetting string SecurityAccessGroupOverride bool ChatInboxSourceLocalizeThreads int MobileExtension bool AttachmentHTTPStartPort int AttachmentDisableMulti bool LinkCacheSize int UPAKCacheSize int PayloadCacheSize int ProofCacheSize int DisableTeamAuditor bool DisableMerkleAuditor bool DisableTeamBoxAuditor bool DisableEKBackgroundKeygen bool LevelDBWriteBufferMB int LevelDBNumFiles int } var _ CommandLine = AppConfig{} func (c AppConfig) GetLogFile() string { return c.LogFile } func (c AppConfig) GetEKLogFile() string { return c.EKLogFile } func (c AppConfig) GetPerfLogFile() string { return c.PerfLogFile } func (c AppConfig) GetGUILogFile() string { return c.GUILogFile } func (c AppConfig) GetUseDefaultLogFile() (bool, bool) { return c.UseDefaultLogFile, true } func (c AppConfig) GetDebug() (bool, bool) { return c.Debug, c.Debug } func (c AppConfig) GetLocalRPCDebug() string { return c.LocalRPCDebug } func (c AppConfig) GetRunMode() (RunMode, error) { return c.RunMode, nil } func (c AppConfig) GetDownloadsDir() string { return c.DownloadsDir } func (c AppConfig) GetHome() string { return c.HomeDir } func (c AppConfig) GetMobileSharedHome() string { return c.MobileSharedHomeDir } func (c AppConfig) GetServerURI() (string, error) { return c.ServerURI, nil } func (c AppConfig) GetSecurityAccessGroupOverride() (bool, bool) { return c.SecurityAccessGroupOverride, c.SecurityAccessGroupOverride } func (c AppConfig) GetAppType() AppType { return MobileAppType } func (c AppConfig) IsMobileExtension() (bool, bool) { return c.MobileExtension, true } func (c AppConfig) GetSlowGregorConn() (bool, bool) { return false, false } func (c AppConfig) GetReadDeletedSigChain() (bool, bool) { return false, false } func (c AppConfig) GetVDebugSetting() string { return c.VDebugSetting } func (c AppConfig) GetChatInboxSourceLocalizeThreads() (int, bool) { return c.ChatInboxSourceLocalizeThreads, true } func (c AppConfig) GetLevelDBWriteBufferMB() (int, bool) { if c.LevelDBWriteBufferMB > 0 { return c.LevelDBWriteBufferMB, true } return LevelDBWriteBufferMBMobile, true } func (c AppConfig) GetLevelDBNumFiles() (int, bool) { if c.LevelDBNumFiles > 0 { return c.LevelDBNumFiles, true } return LevelDBNumFiles, true } func (c AppConfig) GetAttachmentHTTPStartPort() (int, bool) { if c.AttachmentHTTPStartPort != 0 { return c.AttachmentHTTPStartPort, true } return 0, false } func (c AppConfig) GetLinkCacheSize() (int, bool) { if c.LinkCacheSize != 0 { return c.LinkCacheSize, true } return 0, false } func (c AppConfig) GetUPAKCacheSize() (int, bool) { if c.UPAKCacheSize != 0 { return c.UPAKCacheSize, true } return 0, false } func (c AppConfig) GetPayloadCacheSize() (int, bool) { if c.PayloadCacheSize != 0 { return c.PayloadCacheSize, true } return 0, false } func (c AppConfig) GetProofCacheSize() (int, bool) { if c.ProofCacheSize != 0 { return c.ProofCacheSize, true } return 0, false } func (c AppConfig) GetDisableTeamAuditor() (bool, bool) { return c.DisableTeamAuditor, true } func (c AppConfig) GetDisableMerkleAuditor() (bool, bool) { return c.DisableMerkleAuditor, true } func (c AppConfig) GetDisableTeamBoxAuditor() (bool, bool) { return c.DisableTeamBoxAuditor, true } func (c AppConfig) GetDisableEKBackgroundKeygen() (bool, bool) { return c.DisableEKBackgroundKeygen, true } func (c AppConfig) GetAttachmentDisableMulti() (bool, bool) { return c.AttachmentDisableMulti, true } func (e *Env) GetUpdatePreferenceAuto() (bool, bool) { return e.GetConfig().GetUpdatePreferenceAuto() } func (e *Env) GetUpdatePreferenceSkip() string { return e.GetConfig().GetUpdatePreferenceSkip() } func (e *Env) GetUpdatePreferenceSnoozeUntil() keybase1.Time { return e.GetConfig().GetUpdatePreferenceSnoozeUntil() } func (e *Env) GetUpdateLastChecked() keybase1.Time { return e.GetConfig().GetUpdateLastChecked() } func (e *Env) SetUpdatePreferenceAuto(b bool) error { return e.GetConfigWriter().SetUpdatePreferenceAuto(b) } func (e *Env) SetUpdatePreferenceSkip(v string) error { return e.GetConfigWriter().SetUpdatePreferenceSkip(v) } func (e *Env) SetUpdatePreferenceSnoozeUntil(t keybase1.Time) error { return e.GetConfigWriter().SetUpdatePreferenceSnoozeUntil(t) } func (e *Env) SetUpdateLastChecked(t keybase1.Time) error { return e.GetConfigWriter().SetUpdateLastChecked(t) } func (e *Env) GetUpdateURL() string { return e.GetConfig().GetUpdateURL() } func (e *Env) GetUpdateDisabled() (bool, bool) { return e.GetConfig().GetUpdateDisabled() } func (e *Env) GetVDebugSetting() string { return e.GetString( func() string { return e.cmd.GetVDebugSetting() }, func() string { return os.Getenv("KEYBASE_VDEBUG") }, func() string { return e.GetConfig().GetVDebugSetting() }, func() string { return "" }, ) } func (e *Env) GetRunModeAsString() string { return string(e.GetRunMode()) } // GetServiceInfoPath returns path to info file written by the Keybase service after startup func (e *Env) GetServiceInfoPath() string { return filepath.Join(e.GetRuntimeDir(), "keybased.info") } // GetKBFSInfoPath returns path to info file written by the KBFS service after startup func (e *Env) GetKBFSInfoPath() string { return filepath.Join(e.GetRuntimeDir(), "kbfs.info") } func (e *Env) GetUpdateDefaultInstructions() (string, error) { return PlatformSpecificUpgradeInstructionsString() } func (e *Env) RunningInCI() bool { return e.GetBool(false, func() (bool, bool) { return e.getEnvBool("KEYBASE_RUN_CI") }, ) } func (e *Env) WantsSystemd() bool { isNonstandard, isNonstandardErr := e.HomeFinder.IsNonstandardHome() return (e.GetRunMode() == ProductionRunMode && e.ModelessWantsSystemd() && (isNonstandardErr != nil || !isNonstandard)) } func (e *Env) ModelessWantsSystemd() bool { return (systemd.IsRunningSystemd() && os.Getenv("KEYBASE_SYSTEMD") != "0") } func (e *Env) ForceSecretStoreFile() bool { // By default use system-provided secret store (like MacOS Keychain), but // allow users to fall back to file-based store for testing and debugging. return e.GetBool(false, func() (bool, bool) { return e.getEnvBool("KEYBASE_SECRET_STORE_FILE") }, func() (bool, bool) { return e.GetConfig().GetForceSecretStoreFile() }, ) } func (e *Env) GetRuntimeStatsEnabled() bool { return e.GetBool(false, func() (bool, bool) { return e.getEnvBool("KEYBASE_RUNTIME_STATS_ENABLED") }, func() (bool, bool) { return e.GetConfig().GetRuntimeStatsEnabled() }, ) } func (e *Env) GetRememberPassphrase(username NormalizedUsername) bool { return e.GetBool(true, func() (bool, bool) { return e.cmd.GetRememberPassphrase(username) }, func() (bool, bool) { return e.GetConfig().GetRememberPassphrase(username) }, ) } func GetPlatformString() string { if IsIPad { return "ipad" } if isIOS { return "ios" } platform := runtime.GOOS if platform == "darwin" && runtime.GOARCH == "arm64" { platform = "darwin-arm64" } return platform } func IsMobilePlatform() bool { s := GetPlatformString() return (s == "ios" || s == "android" || s == "ipad") } func IsAndroid() bool { return GetPlatformString() == "android" } func (e *Env) AllowPTrace() bool { return e.GetBool(false, func() (bool, bool) { return e.getEnvBool("KEYBASE_ALLOW_PTRACE") }, ) } func (e *Env) GetLogFileConfig(filename string) *logger.LogFileConfig { var maxKeepFiles int var maxSize int64 if e.GetAppType() == MobileAppType && !e.GetFeatureFlags().Admin(e.GetUID()) { maxKeepFiles = 2 maxSize = 16 * opt.MiB } else { maxKeepFiles = 3 maxSize = 128 * opt.MiB } return &logger.LogFileConfig{ Path: filename, MaxAge: 30 * 24 * time.Hour, // 30 days MaxSize: maxSize, MaxKeepFiles: maxKeepFiles, } } func (e *Env) GetForceLinuxKeyring() bool { return e.GetBool(false, func() (bool, bool) { return e.cmd.GetForceLinuxKeyring() }, func() (bool, bool) { return e.getEnvBool("KEYBASE_FORCE_LINUX_KEYRING") }, func() (bool, bool) { return e.GetConfig().GetForceLinuxKeyring() }) }