/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/engine/pgp_push_private.go
246 строк
6 KB
zoom-ua
gofumpt (#28710)
17 дек 2025, 17:16
Не верифицирован
17 дек 2025, 17:16
cda510b
Код
Авторство
О чём код?
// Copyright 2015 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package engine import ( "errors" "fmt" "github.com/keybase/client/go/libkb" keybase1 "github.com/keybase/client/go/protocol/keybase1" "github.com/keybase/go-framed-msgpack-rpc/rpc" ) type PGPPushPrivate struct { arg keybase1.PGPPushPrivateArg } func (e *PGPPushPrivate) Name() string { return "PGPPushPrivate" } func (e *PGPPushPrivate) Prereqs() Prereqs { return Prereqs{} } func (e *PGPPushPrivate) RequiredUIs() []libkb.UIKind { return []libkb.UIKind{} } func (e *PGPPushPrivate) SubConsumers() []libkb.UIConsumer { return []libkb.UIConsumer{} } func NewPGPPushPrivate(arg keybase1.PGPPushPrivateArg) *PGPPushPrivate { return &PGPPushPrivate{arg} } func getCurrentUserPGPKeys(m libkb.MetaContext) ([]libkb.PGPFingerprint, error) { uid := m.CurrentUID() if uid.IsNil() { return nil, libkb.NewLoginRequiredError("for push/pull of PGP private keys to KBFS") } upk, _, err := m.G().GetUPAKLoader().LoadV2(libkb.NewLoadUserArgWithMetaContext(m).WithUID(uid)) if err != nil { return nil, err } var res []libkb.PGPFingerprint for _, key := range upk.Current.PGPKeys { if key.Base.Revocation != nil { continue } res = append(res, libkb.PGPFingerprint(key.Fingerprint)) } if len(res) == 0 { return nil, errors.New("The --all flag only works if you have PGP keys linked to your Keybase account") } return res, nil } func getPrivateFingerprints(m libkb.MetaContext, fps []keybase1.PGPFingerprint) ([]libkb.PGPFingerprint, error) { if len(fps) == 0 { return getCurrentUserPGPKeys(m) } var ret []libkb.PGPFingerprint for _, fp := range fps { ret = append(ret, libkb.ImportPGPFingerprint(fp)) } return ret, nil } func simpleFSClient(m libkb.MetaContext) (*keybase1.SimpleFSClient, error) { xp := m.G().ConnectionManager.LookupByClientType(keybase1.ClientType_KBFS) if xp == nil { return nil, libkb.KBFSNotRunningError{} } return &keybase1.SimpleFSClient{ Cli: rpc.NewClient(xp, libkb.NewContextifiedErrorUnwrapper(m.G()), nil), }, nil } func (e *PGPPushPrivate) mkdir(m libkb.MetaContext, fs *keybase1.SimpleFSClient, path string) (err error) { opid, err := fs.SimpleFSMakeOpid(m.Ctx()) if err != nil { return err } defer fs.SimpleFSClose(m.Ctx(), opid) err = fs.SimpleFSOpen(m.Ctx(), keybase1.SimpleFSOpenArg{ OpID: opid, Dest: keybase1.NewPathWithKbfsPath(path), Flags: keybase1.OpenFlags_DIRECTORY, }) return err } func (e *PGPPushPrivate) write(m libkb.MetaContext, fs *keybase1.SimpleFSClient, path string, data string) (err error) { opid, err := fs.SimpleFSMakeOpid(m.Ctx()) if err != nil { return err } defer fs.SimpleFSClose(m.Ctx(), opid) err = fs.SimpleFSOpen(m.Ctx(), keybase1.SimpleFSOpenArg{ OpID: opid, Dest: keybase1.NewPathWithKbfsPath(path), Flags: keybase1.OpenFlags_WRITE, }) if err != nil { return err } err = fs.SimpleFSWrite(m.Ctx(), keybase1.SimpleFSWriteArg{ OpID: opid, Offset: 0, Content: []byte(data), }) if err != nil { return err } return nil } func (e *PGPPushPrivate) link(m libkb.MetaContext, fs *keybase1.SimpleFSClient, file string, link string) (err error) { err = fs.SimpleFSSymlink(m.Ctx(), keybase1.SimpleFSSymlinkArg{ Target: file, Link: keybase1.NewPathWithKbfsPath(link), }) return err } func (e *PGPPushPrivate) remove(m libkb.MetaContext, fs *keybase1.SimpleFSClient, file string) (err error) { opid, err := fs.SimpleFSMakeOpid(m.Ctx()) if err != nil { return err } defer fs.SimpleFSClose(m.Ctx(), opid) err = fs.SimpleFSRemove(m.Ctx(), keybase1.SimpleFSRemoveArg{ OpID: opid, Path: keybase1.NewPathWithKbfsPath(file), }) if err != nil { return err } err = fs.SimpleFSWait(m.Ctx(), opid) return err } func (e *PGPPushPrivate) linkExists(m libkb.MetaContext, fs *keybase1.SimpleFSClient, file string) (exists bool, err error) { defer m.Trace(fmt.Sprintf("linkExists(%q)", file), &err)() var dirent keybase1.Dirent dirent, err = fs.SimpleFSStat(m.Ctx(), keybase1.SimpleFSStatArg{ Path: keybase1.NewPathWithKbfsPath(file), RefreshSubscription: false, }) if err != nil { m.Debug("error accessing %s; assuming that the file doesn't exist (%s)", file, err.Error()) return false, nil } if dirent.DirentType != keybase1.DirentType_SYM { return false, fmt.Errorf("Cannot rewrite %s since it's not a symlink", file) } return true, nil } func (e *PGPPushPrivate) push(m libkb.MetaContext, fp libkb.PGPFingerprint, tty string, fs *keybase1.SimpleFSClient) error { armored, err := m.G().GetGpgClient().ImportKeyArmored(m, true /* secret */, fp, tty) if err != nil { return err } username := m.CurrentUsername() if username.IsNil() { return libkb.NewLoginRequiredError("no username found") } path := "/private/" + username.String() + "/.keys" // Make /.keys/pgp. If it already exists, these mkdir calls should not error out. err = e.mkdir(m, fs, path) if err != nil { return err } path += "/pgp" err = e.mkdir(m, fs, path) if err != nil { return err } filename := fp.String() + "-" + fmt.Sprintf("%d", m.G().Clock().Now().Unix()) + ".asc" linkname := fp.String() + ".asc" filepath := path + "/" + filename linkpath := path + "/" + linkname err = e.write(m, fs, filepath, armored) if err != nil { return err } linkExists, err := e.linkExists(m, fs, linkpath) if err != nil { return err } // Note the small chance of a race here, but it doesn't seem dangerous. if linkExists { err = e.remove(m, fs, linkpath) if err != nil { return err } } err = e.link(m, fs, filename, linkpath) return err } func (e *PGPPushPrivate) Run(m libkb.MetaContext) (err error) { defer m.Trace("PGPPushPrivate#Run", &err)() tty, err := m.UIs().GPGUI.GetTTY(m.Ctx()) if err != nil { return err } fingerprints, err := getPrivateFingerprints(m, e.arg.Fingerprints) if err != nil { return err } fs, err := simpleFSClient(m) if err != nil { return err } if len(fingerprints) == 0 { return errors.New("no PGP keys provided") } for _, fp := range fingerprints { err = e.push(m, fp, tty, fs) if err != nil { return err } } return nil }