1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package libkb
5
6import (
7	"encoding/hex"
8	"errors"
9	"fmt"
10	"os"
11	"os/exec"
12	"runtime"
13	"strings"
14	"time"
15
16	"github.com/keybase/client/go/gregor"
17	"github.com/keybase/client/go/kbcrypto"
18	"github.com/keybase/client/go/protocol/chat1"
19	"github.com/keybase/client/go/protocol/gregor1"
20	keybase1 "github.com/keybase/client/go/protocol/keybase1"
21)
22
23//=============================================================================
24//
25
26type ProofError interface {
27	error
28	GetProofStatus() keybase1.ProofStatus
29	GetDesc() string
30}
31
32func ProofErrorIsSoft(pe ProofError) bool {
33	s := pe.GetProofStatus()
34	return (s >= keybase1.ProofStatus_BASE_ERROR && s < keybase1.ProofStatus_BASE_HARD_ERROR)
35}
36
37func ProofErrorIsPvlBad(pe ProofError) bool {
38	s := pe.GetProofStatus()
39	switch s {
40	case keybase1.ProofStatus_INVALID_PVL:
41		return true
42	case keybase1.ProofStatus_MISSING_PVL:
43		return true
44	default:
45		return false
46	}
47}
48
49func ProofErrorToState(pe ProofError) keybase1.ProofState {
50	if pe == nil {
51		return keybase1.ProofState_OK
52	}
53
54	switch pe.GetProofStatus() {
55	case keybase1.ProofStatus_NO_HINT:
56		return keybase1.ProofState_SIG_HINT_MISSING
57	case keybase1.ProofStatus_UNKNOWN_TYPE:
58		return keybase1.ProofState_UNKNOWN_TYPE
59	case keybase1.ProofStatus_UNCHECKED:
60		return keybase1.ProofState_UNCHECKED
61	default:
62		return keybase1.ProofState_TEMP_FAILURE
63	}
64
65}
66
67type ProofErrorImpl struct {
68	Status keybase1.ProofStatus
69	Desc   string
70}
71
72func NewProofError(s keybase1.ProofStatus, d string, a ...interface{}) *ProofErrorImpl {
73	// Don't do string interpolation if there are no substitution arguments.
74	// Fixes double-interpolation when deserializing an object.
75	if len(a) == 0 {
76		return &ProofErrorImpl{s, d}
77	}
78	return &ProofErrorImpl{s, fmt.Sprintf(d, a...)}
79}
80
81func NewInvalidPVLSelectorError(selector keybase1.SelectorEntry) error {
82	return NewProofError(
83		keybase1.ProofStatus_INVALID_PVL,
84		"JSON selector entry must be a string, int, or 'all' %v",
85		selector,
86	)
87}
88
89func (e *ProofErrorImpl) Error() string {
90	return fmt.Sprintf("%s (code=%d)", e.Desc, int(e.Status))
91}
92
93func (e *ProofErrorImpl) GetProofStatus() keybase1.ProofStatus { return e.Status }
94func (e *ProofErrorImpl) GetDesc() string                      { return e.Desc }
95
96type ProofAPIError struct {
97	ProofErrorImpl
98	url string
99}
100
101var ProofErrorDNSOverTor = &ProofErrorImpl{
102	Status: keybase1.ProofStatus_TOR_SKIPPED,
103	Desc:   "DNS proofs aren't reliable over Tor",
104}
105
106var ProofErrorHTTPOverTor = &ProofErrorImpl{
107	Status: keybase1.ProofStatus_TOR_SKIPPED,
108	Desc:   "HTTP proofs aren't reliable over Tor",
109}
110
111var ProofErrorUnchecked = &ProofErrorImpl{
112	Status: keybase1.ProofStatus_UNCHECKED,
113	Desc:   "Proof unchecked due to privacy concerns",
114}
115
116type TorSessionRequiredError struct{}
117
118func (t TorSessionRequiredError) Error() string {
119	return "We can't send out PII in Tor-Strict mode; but it's needed for this operation"
120}
121
122func NewProofAPIError(s keybase1.ProofStatus, u string, d string, a ...interface{}) *ProofAPIError {
123	base := NewProofError(s, d, a...)
124	return &ProofAPIError{*base, u}
125}
126
127//=============================================================================
128
129func XapiError(err error, u string) *ProofAPIError {
130	if ae, ok := err.(*APIError); ok {
131		var code keybase1.ProofStatus
132		switch ae.Code / 100 {
133		case 3:
134			code = keybase1.ProofStatus_HTTP_300
135		case 4:
136			if ae.Code == 429 {
137				code = keybase1.ProofStatus_HTTP_429
138			} else {
139				code = keybase1.ProofStatus_HTTP_400
140			}
141		case 5:
142			code = keybase1.ProofStatus_HTTP_500
143		default:
144			code = keybase1.ProofStatus_HTTP_OTHER
145		}
146		return NewProofAPIError(code, u, ae.Msg)
147	}
148	return NewProofAPIError(keybase1.ProofStatus_INTERNAL_ERROR, u, err.Error())
149}
150
151//=============================================================================
152
153type FailedAssertionError struct {
154	user string
155	bad  []AssertionURL
156}
157
158func (u FailedAssertionError) Error() string {
159	v := make([]string, len(u.bad))
160	for i, u := range u.bad {
161		v[i] = u.String()
162	}
163	return ("for " + u.user + ", the follow assertions failed: " +
164		strings.Join(v, ", "))
165}
166
167//=============================================================================
168
169type AssertionParseErrorReason int
170
171const (
172	AssertionParseErrorReasonGeneric      AssertionParseErrorReason = 0
173	AssertionParseErrorReasonUnexpectedOR AssertionParseErrorReason = 1
174)
175
176type AssertionParseError struct {
177	err    string
178	reason AssertionParseErrorReason
179}
180
181func (e AssertionParseError) Reason() AssertionParseErrorReason {
182	return e.reason
183}
184
185func (e AssertionParseError) Error() string {
186	return e.err
187}
188
189func NewAssertionParseError(s string, a ...interface{}) AssertionParseError {
190	return AssertionParseError{
191		reason: AssertionParseErrorReasonGeneric,
192		err:    fmt.Sprintf(s, a...),
193	}
194}
195func NewAssertionParseErrorWithReason(reason AssertionParseErrorReason, s string, a ...interface{}) AssertionParseError {
196	return AssertionParseError{
197		reason: reason,
198		err:    fmt.Sprintf(s, a...),
199	}
200}
201func IsAssertionParseErrorWithReason(err error, reason AssertionParseErrorReason) bool {
202	aerr, ok := err.(AssertionParseError)
203	return ok && aerr.reason == reason
204}
205
206//=============================================================================
207
208type AssertionCheckError struct {
209	err string
210}
211
212func (e AssertionCheckError) Error() string {
213	return e.err
214}
215
216func NewAssertionCheckError(s string, a ...interface{}) AssertionCheckError {
217	return AssertionCheckError{
218		err: fmt.Sprintf(s, a...),
219	}
220}
221
222//=============================================================================
223
224type NeedInputError struct {
225	err string
226}
227
228func (e NeedInputError) Error() string {
229	return e.err
230}
231
232func NewNeedInputError(s string, a ...interface{}) AssertionParseError {
233	return AssertionParseError{
234		err: fmt.Sprintf(s, a...),
235	}
236}
237
238//=============================================================================
239
240type WrongKidError struct {
241	wanted, got keybase1.KID
242}
243
244func (w WrongKidError) Error() string {
245	return fmt.Sprintf("Wanted KID=%s; but got KID=%s", w.wanted, w.got)
246}
247
248func NewWrongKidError(w keybase1.KID, g keybase1.KID) WrongKidError {
249	return WrongKidError{w, g}
250}
251
252//=============================================================================
253
254type WrongKeyError struct {
255	wanted, got *PGPFingerprint
256}
257
258func (e WrongKeyError) Error() string {
259	return fmt.Sprintf("Server gave wrong key; wanted %s; got %s", e.wanted, e.got)
260}
261
262//=============================================================================
263
264type UnexpectedKeyError struct {
265}
266
267func (e UnexpectedKeyError) Error() string {
268	return "Found a key or fingerprint when one wasn't expected"
269}
270
271//=============================================================================
272
273type UserNotFoundError struct {
274	UID keybase1.UID
275	Msg string
276}
277
278func (u UserNotFoundError) Error() string {
279	uid := ""
280	if !u.UID.IsNil() {
281		uid = " " + string(u.UID)
282	}
283	msg := ""
284	if u.Msg != "" {
285		msg = " (" + u.Msg + ")"
286	}
287	return fmt.Sprintf("User%s wasn't found%s", uid, msg)
288}
289
290//=============================================================================
291
292type AlreadyRegisteredError struct {
293	UID keybase1.UID
294}
295
296func (u AlreadyRegisteredError) Error() string {
297	return fmt.Sprintf("Already registered (with uid=%s)", u.UID)
298}
299
300//=============================================================================
301
302type WrongSigError struct {
303	b string
304}
305
306func (e WrongSigError) Error() string {
307	return "Found wrong signature: " + e.b
308}
309
310type BadSigError struct {
311	E string
312}
313
314func (e BadSigError) Error() string {
315	return e.E
316}
317
318//=============================================================================
319
320type NotFoundError struct {
321	Msg string
322}
323
324func (e NotFoundError) Error() string {
325	if len(e.Msg) == 0 {
326		return "Not found"
327	}
328	return e.Msg
329}
330
331func IsNotFoundError(err error) bool {
332	_, ok := err.(NotFoundError)
333	return ok
334}
335
336func NewNotFoundError(s string) error {
337	return NotFoundError{s}
338}
339
340//=============================================================================
341
342type MissingDelegationTypeError struct{}
343
344func (e MissingDelegationTypeError) Error() string {
345	return "DelegationType wasn't set"
346}
347
348//=============================================================================
349
350type NoKeyError struct {
351	Msg string
352}
353
354func (u NoKeyError) Error() string {
355	if len(u.Msg) > 0 {
356		return u.Msg
357	}
358	return "No public key found"
359}
360
361func IsNoKeyError(err error) bool {
362	_, ok := err.(NoKeyError)
363	return ok
364}
365
366type NoSyncedPGPKeyError struct{}
367
368func (e NoSyncedPGPKeyError) Error() string {
369	return "No synced secret PGP key found on keybase.io"
370}
371
372//=============================================================================
373
374type NoSecretKeyError struct {
375}
376
377func (u NoSecretKeyError) Error() string {
378	return "No secret key available"
379}
380
381//=============================================================================
382
383type NoPaperKeysError struct {
384}
385
386func (u NoPaperKeysError) Error() string {
387	return "No paper keys available"
388}
389
390//=============================================================================
391
392type TooManyKeysError struct {
393	n int
394}
395
396func (e TooManyKeysError) Error() string {
397	return fmt.Sprintf("Too many keys (%d) found", e.n)
398}
399
400//=============================================================================
401
402type NoSelectedKeyError struct{}
403
404func (n NoSelectedKeyError) Error() string {
405	return "Please login again to verify your public key"
406}
407
408//=============================================================================
409
410type KeyCorruptedError struct {
411	Msg string
412}
413
414func (e KeyCorruptedError) Error() string {
415	msg := "Key corrupted"
416	if len(e.Msg) != 0 {
417		msg = msg + ": " + e.Msg
418	}
419	return msg
420}
421
422//=============================================================================
423
424type KeyExistsError struct {
425	Key *PGPFingerprint
426}
427
428func (k KeyExistsError) Error() string {
429	ret := "Key already exists for user"
430	if k.Key != nil {
431		ret = fmt.Sprintf("%s (%s)", ret, k.Key)
432	}
433	return ret
434}
435
436//=============================================================================
437
438type PassphraseError struct {
439	Msg string
440}
441
442func (p PassphraseError) Error() string {
443	msg := "Bad password"
444	if len(p.Msg) != 0 {
445		msg = msg + ": " + p.Msg + "."
446	}
447	return msg
448}
449
450//=============================================================================
451
452type PaperKeyError struct {
453	msg      string
454	tryAgain bool
455}
456
457func (p PaperKeyError) Error() string {
458	msg := "Bad paper key: " + p.msg
459	if p.tryAgain {
460		msg += ". Please try again."
461	}
462	return msg
463}
464
465func NewPaperKeyError(s string, t bool) error {
466	return PaperKeyError{msg: s, tryAgain: t}
467}
468
469//=============================================================================
470
471type BadEmailError struct {
472	Msg string
473}
474
475func (e BadEmailError) Error() string {
476	msg := "Bad email"
477	if len(e.Msg) != 0 {
478		msg = msg + ": " + e.Msg
479	}
480	return msg
481}
482
483//=============================================================================
484
485type BadFingerprintError struct {
486	fp1, fp2 PGPFingerprint
487}
488
489func (b BadFingerprintError) Error() string {
490	return fmt.Sprintf("Got bad PGP key; fingerprint %s != %s", b.fp1, b.fp2)
491}
492
493//=============================================================================
494
495type AppStatusError struct {
496	Code   int
497	Name   string
498	Desc   string
499	Fields map[string]string
500}
501
502// If the error is an AppStatusError, returns its code.
503// Otherwise returns (SCGeneric, false).
504func GetAppStatusCode(err error) (code keybase1.StatusCode, ok bool) {
505	code = keybase1.StatusCode_SCGeneric
506	switch err := err.(type) {
507	case AppStatusError:
508		return keybase1.StatusCode(err.Code), true
509	default:
510		return code, false
511	}
512}
513
514func (a AppStatusError) IsBadField(s string) bool {
515	_, found := a.Fields[s]
516	return found
517}
518
519func NewAppStatusError(ast *AppStatus) AppStatusError {
520	return AppStatusError{
521		Code:   ast.Code,
522		Name:   ast.Name,
523		Desc:   ast.Desc,
524		Fields: ast.Fields,
525	}
526}
527
528func (a AppStatusError) Error() string {
529	v := make([]string, len(a.Fields))
530	i := 0
531
532	for k := range a.Fields {
533		v[i] = k
534		i++
535	}
536
537	fields := ""
538	if i > 0 {
539		fields = fmt.Sprintf(" (bad fields: %s)", strings.Join(v, ","))
540	}
541
542	return fmt.Sprintf("%s%s (error %d)", a.Desc, fields, a.Code)
543}
544
545func (a AppStatusError) WithDesc(desc string) AppStatusError {
546	a.Desc = desc
547	return a
548}
549
550func IsAppStatusCode(err error, code keybase1.StatusCode) bool {
551	switch err := err.(type) {
552	case AppStatusError:
553		return err.Code == int(code)
554	default:
555		return false
556	}
557}
558
559func IsEphemeralRetryableError(err error) bool {
560	switch err := err.(type) {
561	case AppStatusError:
562		switch keybase1.StatusCode(err.Code) {
563		case keybase1.StatusCode_SCSigWrongKey,
564			keybase1.StatusCode_SCSigOldSeqno,
565			keybase1.StatusCode_SCEphemeralKeyBadGeneration,
566			keybase1.StatusCode_SCEphemeralKeyUnexpectedBox,
567			keybase1.StatusCode_SCEphemeralKeyMissingBox,
568			keybase1.StatusCode_SCEphemeralKeyWrongNumberOfKeys,
569			keybase1.StatusCode_SCTeambotKeyBadGeneration,
570			keybase1.StatusCode_SCTeambotKeyOldBoxedGeneration:
571			return true
572		default:
573			return false
574		}
575	default:
576		return false
577	}
578}
579
580//=============================================================================
581
582type GpgError struct {
583	M string
584}
585
586func (e GpgError) Error() string {
587	return fmt.Sprintf("GPG error: %s", e.M)
588}
589
590func ErrorToGpgError(e error) GpgError {
591	return GpgError{e.Error()}
592}
593
594type GpgIndexError struct {
595	lineno int
596	m      string
597}
598
599func (e GpgIndexError) Error() string {
600	return fmt.Sprintf("GPG index error at line %d: %s", e.lineno, e.m)
601}
602
603func ErrorToGpgIndexError(l int, e error) GpgIndexError {
604	return GpgIndexError{l, e.Error()}
605}
606
607type GPGUnavailableError struct{}
608
609func (g GPGUnavailableError) Error() string {
610	return "GPG is unavailable on this device"
611}
612
613//=============================================================================
614
615type LoginRequiredError struct {
616	Context string
617}
618
619func (e LoginRequiredError) Error() string {
620	msg := "Login required"
621	if len(e.Context) > 0 {
622		msg = fmt.Sprintf("%s: %s", msg, e.Context)
623	}
624	return msg
625}
626
627func NewLoginRequiredError(s string) error {
628	return LoginRequiredError{s}
629}
630
631type ReloginRequiredError struct{}
632
633func (e ReloginRequiredError) Error() string {
634	return "Login required due to an unexpected error since your previous login"
635}
636
637type DeviceRequiredError struct{}
638
639func (e DeviceRequiredError) Error() string {
640	return "Login required"
641}
642
643type NoSessionError struct{}
644
645// KBFS currently matching on this string, so be careful changing this:
646func (e NoSessionError) Error() string {
647	return "no current session"
648}
649
650//=============================================================================
651
652type LogoutError struct{}
653
654func (e LogoutError) Error() string {
655	return "Failed to logout"
656}
657
658//=============================================================================
659
660type LoggedInError struct{}
661
662func (e LoggedInError) Error() string {
663	return "You are already logged in as a different user; try logout first"
664}
665
666//=============================================================================
667
668type LoggedInWrongUserError struct {
669	ExistingName  NormalizedUsername
670	AttemptedName NormalizedUsername
671}
672
673func (e LoggedInWrongUserError) Error() string {
674	return fmt.Sprintf("Logged in as %q, attempting to log in as %q: try logout first", e.ExistingName, e.AttemptedName)
675}
676
677//=============================================================================
678
679type InternalError struct {
680	Msg string
681}
682
683func (e InternalError) Error() string {
684	return fmt.Sprintf("Internal error: %s", e.Msg)
685}
686
687//=============================================================================
688
689type ServerChainError struct {
690	msg string
691}
692
693func (e ServerChainError) Error() string {
694	return e.msg
695}
696
697func NewServerChainError(d string, a ...interface{}) ServerChainError {
698	return ServerChainError{fmt.Sprintf(d, a...)}
699}
700
701//=============================================================================
702
703type WaitForItError struct{}
704
705func (e WaitForItError) Error() string {
706	return "It is advised you 'wait for it'"
707}
708
709//=============================================================================
710
711type InsufficientKarmaError struct {
712	un string
713}
714
715func (e InsufficientKarmaError) Error() string {
716	return "Bad karma"
717}
718
719func NewInsufficientKarmaError(un string) InsufficientKarmaError {
720	return InsufficientKarmaError{un: un}
721}
722
723//=============================================================================
724
725type InvalidHostnameError struct {
726	h string
727}
728
729func (e InvalidHostnameError) Error() string {
730	return "Invalid hostname: " + e.h
731}
732func NewInvalidHostnameError(h string) InvalidHostnameError {
733	return InvalidHostnameError{h: h}
734}
735
736//=============================================================================
737
738type WebUnreachableError struct {
739	h string
740}
741
742func (h WebUnreachableError) Error() string {
743	return "Host " + h.h + " is down; tried both HTTPS and HTTP protocols"
744}
745
746func NewWebUnreachableError(h string) WebUnreachableError {
747	return WebUnreachableError{h: h}
748}
749
750//=============================================================================
751
752type ProtocolSchemeMismatch struct {
753	msg string
754}
755
756func (h ProtocolSchemeMismatch) Error() string {
757	return h.msg
758}
759func NewProtocolSchemeMismatch(msg string) ProtocolSchemeMismatch {
760	return ProtocolSchemeMismatch{msg: msg}
761}
762
763//=============================================================================
764type ProtocolDowngradeError struct {
765	msg string
766}
767
768func (h ProtocolDowngradeError) Error() string {
769	return h.msg
770}
771func NewProtocolDowngradeError(msg string) ProtocolDowngradeError {
772	return ProtocolDowngradeError{msg: msg}
773}
774
775//=============================================================================
776
777type ProfileNotPublicError struct {
778	msg string
779}
780
781func (p ProfileNotPublicError) Error() string {
782	return p.msg
783}
784
785func NewProfileNotPublicError(s string) ProfileNotPublicError {
786	return ProfileNotPublicError{msg: s}
787}
788
789//=============================================================================
790
791type BadUsernameError struct {
792	N   string
793	msg string
794}
795
796func (e BadUsernameError) Error() string {
797	if len(e.msg) == 0 {
798		return "Bad username: '" + e.N + "'"
799	}
800	return e.msg
801}
802
803func NewBadUsernameError(n string) BadUsernameError {
804	return BadUsernameError{N: n}
805}
806
807func NewBadUsernameErrorWithFullMessage(msg string) BadUsernameError {
808	return BadUsernameError{msg: msg}
809}
810
811//=============================================================================
812
813type NoUsernameError struct{}
814
815func (e NoUsernameError) Error() string {
816	return "No username known"
817}
818
819func NewNoUsernameError() NoUsernameError { return NoUsernameError{} }
820
821//=============================================================================
822
823type NoKeyringsError struct{}
824
825func (k NoKeyringsError) Error() string {
826	return "No keyrings available"
827}
828
829//=============================================================================
830
831type KeyCannotSignError struct{}
832
833func (s KeyCannotSignError) Error() string {
834	return "Key cannot create signatures"
835}
836
837type KeyCannotVerifyError struct{}
838
839func (k KeyCannotVerifyError) Error() string {
840	return "Key cannot verify signatures"
841}
842
843type KeyCannotEncryptError struct{}
844
845func (k KeyCannotEncryptError) Error() string {
846	return "Key cannot encrypt data"
847}
848
849type KeyCannotDecryptError struct{}
850
851func (k KeyCannotDecryptError) Error() string {
852	return "Key cannot decrypt data"
853}
854
855type KeyUnimplementedError struct{}
856
857func (k KeyUnimplementedError) Error() string {
858	return "Key function isn't implemented yet"
859}
860
861type NoPGPEncryptionKeyError struct {
862	User                    string
863	HasKeybaseEncryptionKey bool
864}
865
866func (e NoPGPEncryptionKeyError) Error() string {
867	var other string
868	if e.HasKeybaseEncryptionKey {
869		other = "; they do have a keybase key, so you can `keybase encrypt` to them instead"
870	}
871	return fmt.Sprintf("User %s doesn't have a PGP key%s", e.User, other)
872}
873
874type NoNaClEncryptionKeyError struct {
875	Username     string
876	HasPGPKey    bool
877	HasPUK       bool
878	HasDeviceKey bool
879	HasPaperKey  bool
880}
881
882func (e NoNaClEncryptionKeyError) Error() string {
883	var other string
884	switch {
885	case e.HasPUK:
886		other = "; they have a per user key, so you can encrypt without the `--no-entity-keys` flag to them instead"
887	case e.HasDeviceKey:
888		other = "; they do have a device key, so you can encrypt without the `--no-device-keys` flag to them instead"
889	case e.HasPaperKey:
890		other = "; they do have a paper key, so you can encrypt without the `--no-paper-keys` flag to them instead"
891	case e.HasPGPKey:
892		other = "; they do have a PGP key, so you can `keybase pgp encrypt` to encrypt for them instead"
893	}
894
895	return fmt.Sprintf("User %s doesn't have the necessary key type(s)%s", e.Username, other)
896}
897
898type KeyPseudonymError struct {
899	message string
900}
901
902func (e KeyPseudonymError) Error() string {
903	if e.message != "" {
904		return e.message
905	}
906	return "Bad Key Pseydonym or Nonce"
907}
908
909func NewKeyPseudonymError(message string) KeyPseudonymError {
910	return KeyPseudonymError{message: message}
911}
912
913//=============================================================================
914
915type DecryptBadPacketTypeError struct{}
916
917func (d DecryptBadPacketTypeError) Error() string {
918	return "Bad packet type; can't decrypt"
919}
920
921type DecryptBadNonceError struct{}
922
923func (d DecryptBadNonceError) Error() string {
924	return "Bad packet nonce; can't decrypt"
925}
926
927type DecryptBadSenderError struct{}
928
929func (d DecryptBadSenderError) Error() string {
930	return "Bad sender key"
931}
932
933type DecryptWrongReceiverError struct{}
934
935func (d DecryptWrongReceiverError) Error() string {
936	return "Bad receiver key"
937}
938
939type DecryptOpenError struct {
940	What string
941}
942
943func NewDecryptOpenError(what string) DecryptOpenError {
944	return DecryptOpenError{What: what}
945}
946
947func (d DecryptOpenError) Error() string {
948	if len(d.What) == 0 {
949		return "box.Open failure; ciphertext was corrupted or wrong key"
950	}
951	return fmt.Sprintf("failed to decrypt '%s'; ciphertext was corrupted or wrong key", d.What)
952}
953
954//=============================================================================
955
956type NoConfigFileError struct{}
957
958func (n NoConfigFileError) Error() string {
959	return "No configuration file available"
960}
961
962//=============================================================================
963
964type SelfTrackError struct{}
965
966func (e SelfTrackError) Error() string {
967	return "Cannot follow yourself"
968}
969
970//=============================================================================
971
972type NoUIError struct {
973	Which string
974}
975
976func (e NoUIError) Error() string {
977	return fmt.Sprintf("no %s-UI was available", e.Which)
978}
979
980//=============================================================================
981
982type NoConfigWriterError struct{}
983
984func (e NoConfigWriterError) Error() string {
985	return "Can't write; no ConfigWriter available"
986}
987
988//=============================================================================
989
990type NoSessionWriterError struct{}
991
992func (e NoSessionWriterError) Error() string {
993	return "Can't write; no SessionWriter available"
994}
995
996//=============================================================================
997
998type BadServiceError struct {
999	Service string
1000}
1001
1002func (e BadServiceError) Error() string {
1003	return e.Service + ": unsupported service"
1004}
1005
1006type ServiceDoesNotSupportNewProofsError struct {
1007	Service string
1008}
1009
1010func (e ServiceDoesNotSupportNewProofsError) Error() string {
1011	if len(e.Service) == 0 {
1012		return fmt.Sprintf("New proofs of that type are not supported")
1013	}
1014	return fmt.Sprintf("New %s proofs are not supported", e.Service)
1015}
1016
1017//=============================================================================
1018
1019type NotConfirmedError struct{}
1020
1021func (e NotConfirmedError) Error() string {
1022	return "Not confirmed"
1023}
1024
1025//=============================================================================
1026
1027type SibkeyAlreadyExistsError struct{}
1028
1029func (e SibkeyAlreadyExistsError) Error() string {
1030	return "Key is already selected for use on Keybase"
1031}
1032
1033//=============================================================================
1034
1035type ProofNotYetAvailableError struct{}
1036
1037func (e ProofNotYetAvailableError) Error() string {
1038	return "Proof wasn't available; we'll keep trying"
1039}
1040
1041type ProofNotFoundForServiceError struct {
1042	Service string
1043}
1044
1045func (e ProofNotFoundForServiceError) Error() string {
1046	return fmt.Sprintf("proof not found for service %q", e.Service)
1047}
1048
1049type ProofNotFoundForUsernameError struct {
1050	Service  string
1051	Username string
1052}
1053
1054func (e ProofNotFoundForUsernameError) Error() string {
1055	return fmt.Sprintf("proof not found for %q on %q", e.Username, e.Service)
1056}
1057
1058//=============================================================================
1059
1060//=============================================================================
1061
1062type KeyGenError struct {
1063	Msg string
1064}
1065
1066func (e KeyGenError) Error() string {
1067	return fmt.Sprintf("key generation error: %s", e.Msg)
1068}
1069
1070//=============================================================================
1071
1072type KeyFamilyError struct {
1073	Msg string
1074}
1075
1076func (e KeyFamilyError) Error() string {
1077	return fmt.Sprintf("Bad key family: %s", e.Msg)
1078}
1079
1080//=============================================================================
1081
1082type BadRevocationError struct {
1083	msg string
1084}
1085
1086func (e BadRevocationError) Error() string {
1087	return fmt.Sprintf("Bad revocation: %s", e.msg)
1088}
1089
1090//=============================================================================
1091
1092type NoSigChainError struct{}
1093
1094func (e NoSigChainError) Error() string {
1095	return "No sigchain was available"
1096}
1097
1098//=============================================================================
1099
1100type NotProvisionedError struct{}
1101
1102func (e NotProvisionedError) Error() string {
1103	return "This device isn't provisioned (no 'device_kid' entry in config.json)"
1104}
1105
1106//=============================================================================
1107
1108type UIDMismatchError struct {
1109	Msg string
1110}
1111
1112func (u UIDMismatchError) Error() string {
1113	return fmt.Sprintf("UID mismatch error: %s", u.Msg)
1114}
1115
1116func NewUIDMismatchError(m string) UIDMismatchError {
1117	return UIDMismatchError{Msg: m}
1118}
1119
1120//=============================================================================
1121
1122type KeyRevokedError struct {
1123	msg string
1124}
1125
1126func NewKeyRevokedError(m string) KeyRevokedError {
1127	return KeyRevokedError{m}
1128}
1129
1130func (r KeyRevokedError) Error() string {
1131	return fmt.Sprintf("Key revoked: %s", r.msg)
1132}
1133
1134//=============================================================================
1135
1136type KeyExpiredError struct {
1137	msg string
1138}
1139
1140func (r KeyExpiredError) Error() string {
1141	return fmt.Sprintf("Key expired: %s", r.msg)
1142}
1143
1144//=============================================================================
1145
1146type UnknownKeyTypeError struct {
1147	typ kbcrypto.AlgoType
1148}
1149
1150func (e UnknownKeyTypeError) Error() string {
1151	return fmt.Sprintf("Unknown key type: %d", e.typ)
1152}
1153
1154//=============================================================================
1155
1156type SelfNotFoundError struct {
1157	msg string
1158}
1159
1160func (e SelfNotFoundError) Error() string {
1161	return e.msg
1162}
1163
1164type ChainLinkError struct {
1165	msg string
1166}
1167
1168func (c ChainLinkError) Error() string {
1169	return fmt.Sprintf("Error in parsing chain Link: %s", c.msg)
1170}
1171
1172type ChainLinkStubbedUnsupportedError struct {
1173	msg string
1174}
1175
1176func (c ChainLinkStubbedUnsupportedError) Error() string {
1177	return c.msg
1178}
1179
1180type SigchainV2Error struct {
1181	msg string
1182}
1183
1184func (s SigchainV2Error) Error() string {
1185	return fmt.Sprintf("Error in sigchain v2 link: %s", s.msg)
1186}
1187
1188type SigchainV2MismatchedFieldError struct {
1189	msg string
1190}
1191
1192func (s SigchainV2MismatchedFieldError) Error() string {
1193	return fmt.Sprintf("Mismatched field in sigchain v2 link: %s", s.msg)
1194}
1195
1196type SigchainV2StubbedFirstLinkError struct{}
1197
1198func (s SigchainV2StubbedFirstLinkError) Error() string {
1199	return "First link can't be stubbed out"
1200}
1201
1202type SigchainV2StubbedSignatureNeededError struct{}
1203
1204func (s SigchainV2StubbedSignatureNeededError) Error() string {
1205	return "Stubbed-out link actually needs a signature"
1206}
1207
1208type SigchainV2MismatchedHashError struct{}
1209
1210func (s SigchainV2MismatchedHashError) Error() string {
1211	return "Sigchain V2 hash mismatch error"
1212}
1213
1214type SigchainV2StubbedDisallowed struct{}
1215
1216func (s SigchainV2StubbedDisallowed) Error() string {
1217	return "Link was stubbed but required"
1218}
1219
1220type SigchainV2Required struct{}
1221
1222func (s SigchainV2Required) Error() string {
1223	return "Link must use sig v2"
1224}
1225
1226//=============================================================================
1227
1228type ReverseSigError struct {
1229	msg string
1230}
1231
1232func (r ReverseSigError) Error() string {
1233	return fmt.Sprintf("Error in reverse signature: %s", r.msg)
1234}
1235
1236func NewReverseSigError(msgf string, a ...interface{}) ReverseSigError {
1237	return ReverseSigError{msg: fmt.Sprintf(msgf, a...)}
1238}
1239
1240//=============================================================================
1241
1242type ConfigError struct {
1243	fn  string
1244	msg string
1245}
1246
1247func (c ConfigError) Error() string {
1248	return fmt.Sprintf("In config file %s: %s\n", c.fn, c.msg)
1249}
1250
1251//=============================================================================
1252
1253type NoUserConfigError struct{}
1254
1255func (n NoUserConfigError) Error() string {
1256	return "No user config found for user"
1257}
1258
1259//=============================================================================
1260
1261type InactiveKeyError struct {
1262	kid keybase1.KID
1263}
1264
1265func (i InactiveKeyError) Error() string {
1266	return fmt.Sprintf("The key '%s' is not active", i.kid)
1267}
1268
1269//=============================================================================
1270
1271type merkleClientErrorType int
1272
1273const (
1274	merkleErrorNone merkleClientErrorType = iota
1275	merkleErrorNoKnownKey
1276	merkleErrorNoLegacyUIDRoot
1277	merkleErrorUIDMismatch
1278	merkleErrorNoSkipSequence
1279	merkleErrorSkipMissing
1280	merkleErrorSkipHashMismatch
1281	merkleErrorHashMeta
1282	merkleErrorBadResetChain
1283	merkleErrorNotFound
1284	merkleErrorBadSeqno
1285	merkleErrorBadLeaf
1286	merkleErrorNoUpdates
1287	merkleErrorBadSigID
1288	merkleErrorAncientSeqno
1289	merkleErrorKBFSBadTree
1290	merkleErrorKBFSMismatch
1291	merkleErrorBadRoot
1292	merkleErrorOldTree
1293	merkleErrorOutOfOrderCtime
1294	merkleErrorWrongSkipSequence
1295	merkleErrorWrongRootSkips
1296	merkleErrorFailedCheckpoint
1297	merkleErrorTooMuchClockDrift
1298)
1299
1300type MerkleClientError struct {
1301	m string
1302	t merkleClientErrorType
1303}
1304
1305func NewClientMerkleSkipHashMismatchError(m string) MerkleClientError {
1306	return MerkleClientError{
1307		t: merkleErrorSkipHashMismatch,
1308		m: m,
1309	}
1310}
1311
1312func NewClientMerkleSkipMissingError(m string) MerkleClientError {
1313	return MerkleClientError{
1314		t: merkleErrorSkipMissing,
1315		m: m,
1316	}
1317}
1318
1319func NewClientMerkleFailedCheckpointError(m string) MerkleClientError {
1320	return MerkleClientError{
1321		t: merkleErrorFailedCheckpoint,
1322		m: m,
1323	}
1324}
1325
1326func (m MerkleClientError) Error() string {
1327	return fmt.Sprintf("Error checking merkle tree: %s", m.m)
1328}
1329
1330func (m MerkleClientError) IsNotFound() bool {
1331	return m.t == merkleErrorNotFound
1332}
1333
1334func (m MerkleClientError) IsOldTree() bool {
1335	return m.t == merkleErrorOldTree
1336}
1337
1338func (m MerkleClientError) IsSkipHashMismatch() bool {
1339	return m.t == merkleErrorSkipHashMismatch
1340}
1341
1342type MerklePathNotFoundError struct {
1343	k   string
1344	msg string
1345}
1346
1347func (m MerklePathNotFoundError) Error() string {
1348	return fmt.Sprintf("For key '%s', Merkle path not found: %s", m.k, m.msg)
1349}
1350
1351type MerkleClashError struct {
1352	c string
1353}
1354
1355func (m MerkleClashError) Error() string {
1356	return fmt.Sprintf("Merkle tree clashed with server reply: %s", m.c)
1357}
1358
1359//=============================================================================
1360
1361type CanceledError struct {
1362	M string
1363}
1364
1365func (c CanceledError) Error() string {
1366	return c.M
1367}
1368
1369func NewCanceledError(m string) CanceledError {
1370	return CanceledError{M: m}
1371}
1372
1373type InputCanceledError struct{}
1374
1375func (e InputCanceledError) Error() string {
1376	return "Input canceled"
1377}
1378
1379type SkipSecretPromptError struct{}
1380
1381func (e SkipSecretPromptError) Error() string {
1382	return "Skipping secret prompt due to recent user cancel of secret prompt"
1383}
1384
1385//=============================================================================
1386
1387type NoDeviceError struct {
1388	Reason string
1389}
1390
1391func NewNoDeviceError(s string) NoDeviceError {
1392	return NoDeviceError{s}
1393}
1394
1395func (e NoDeviceError) Error() string {
1396	return fmt.Sprintf("No device found %s", e.Reason)
1397}
1398
1399type TimeoutError struct{}
1400
1401func (e TimeoutError) Error() string {
1402	return "Operation timed out"
1403}
1404
1405type ReceiverDeviceError struct {
1406	Msg string
1407}
1408
1409func NewReceiverDeviceError(expected, received keybase1.DeviceID) ReceiverDeviceError {
1410	return ReceiverDeviceError{Msg: fmt.Sprintf("Device ID mismatch in message receiver, got %q, expected %q", received, expected)}
1411}
1412
1413func (e ReceiverDeviceError) Error() string {
1414	return e.Msg
1415}
1416
1417type InvalidKexPhraseError struct{}
1418
1419func (e InvalidKexPhraseError) Error() string {
1420	return "Invalid kex secret phrase"
1421}
1422
1423var ErrNilUser = errors.New("User is nil")
1424
1425//=============================================================================
1426
1427type StreamExistsError struct{}
1428
1429func (s StreamExistsError) Error() string { return "stream already exists" }
1430
1431type StreamNotFoundError struct{}
1432
1433func (s StreamNotFoundError) Error() string { return "stream wasn't found" }
1434
1435type StreamWrongKindError struct{}
1436
1437func (s StreamWrongKindError) Error() string { return "found a stream but not of right kind" }
1438
1439//=============================================================================
1440
1441type UntrackError struct {
1442	err string
1443}
1444
1445func (e UntrackError) Error() string {
1446	return fmt.Sprintf("Unfollow error: %s", e.err)
1447}
1448
1449func NewUntrackError(d string, a ...interface{}) UntrackError {
1450	return UntrackError{
1451		err: fmt.Sprintf(d, a...),
1452	}
1453}
1454
1455//=============================================================================
1456
1457type APINetError struct {
1458	Err error
1459}
1460
1461func (e APINetError) Error() string {
1462	return fmt.Sprintf("API network error: %s", e.Err)
1463}
1464
1465//=============================================================================
1466
1467type NoDecryptionKeyError struct {
1468	Msg string
1469}
1470
1471func (e NoDecryptionKeyError) Error() string {
1472	return fmt.Sprintf("decrypt error: %s", e.Msg)
1473}
1474
1475//=============================================================================
1476
1477type ErrorCause struct {
1478	Err        error
1479	StatusCode int
1480}
1481
1482// DecryptionError is the default decryption error
1483type DecryptionError struct {
1484	Cause ErrorCause
1485}
1486
1487func (e DecryptionError) Error() string {
1488	if e.Cause.Err == nil {
1489		return "Decryption error"
1490	}
1491	return fmt.Sprintf("Decryption error: %+v", e.Cause)
1492}
1493
1494//=============================================================================
1495
1496// VerificationError is the default verification error
1497type VerificationError struct {
1498	Cause ErrorCause
1499}
1500
1501func (e VerificationError) Error() string {
1502	if e.Cause.Err == nil {
1503		return "Verification error"
1504	}
1505	return fmt.Sprintf("Verification error: %+v", e.Cause)
1506}
1507
1508//=============================================================================
1509
1510type ChainLinkPrevHashMismatchError struct {
1511	Msg string
1512}
1513
1514func (e ChainLinkPrevHashMismatchError) Error() string {
1515	return fmt.Sprintf("Chain link prev hash mismatch error: %s", e.Msg)
1516}
1517
1518//=============================================================================
1519
1520type ChainLinkWrongSeqnoError struct {
1521	Msg string
1522}
1523
1524func (e ChainLinkWrongSeqnoError) Error() string {
1525	return fmt.Sprintf("Chain link wrong seqno error: %s", e.Msg)
1526}
1527
1528func NewChainLinkWrongSeqnoError(s string) error {
1529	return ChainLinkWrongSeqnoError{s}
1530}
1531
1532//=============================================================================
1533
1534type ChainLinkHighSkipHashMismatchError struct {
1535	Msg string
1536}
1537
1538func (e ChainLinkHighSkipHashMismatchError) Error() string {
1539	return fmt.Sprintf("Chain link HighSkipHash mismatch error: %s", e.Msg)
1540}
1541
1542//=============================================================================
1543
1544type ChainLinkWrongHighSkipSeqnoError struct {
1545	Msg string
1546}
1547
1548func (e ChainLinkWrongHighSkipSeqnoError) Error() string {
1549	return fmt.Sprintf("Chain link wrong HighSkipSeqno error: %s", e.Msg)
1550}
1551
1552//=============================================================================
1553
1554type CtimeMismatchError struct {
1555	Msg string
1556}
1557
1558func (e CtimeMismatchError) Error() string {
1559	return fmt.Sprintf("Ctime mismatch error: %s", e.Msg)
1560}
1561
1562//=============================================================================
1563
1564type ChainLinkFingerprintMismatchError struct {
1565	Msg string
1566}
1567
1568func (e ChainLinkFingerprintMismatchError) Error() string {
1569	return e.Msg
1570}
1571
1572//=============================================================================
1573
1574type ChainLinkKIDMismatchError struct {
1575	Msg string
1576}
1577
1578func (e ChainLinkKIDMismatchError) Error() string {
1579	return e.Msg
1580}
1581
1582//=============================================================================
1583
1584type UnknownSpecialKIDError struct {
1585	k keybase1.KID
1586}
1587
1588func (u UnknownSpecialKIDError) Error() string {
1589	return fmt.Sprintf("Unknown special KID: %s", u.k)
1590}
1591
1592type IdentifyTimeoutError struct{}
1593
1594func (e IdentifyTimeoutError) Error() string {
1595	return "Identification expired."
1596}
1597
1598//=============================================================================
1599
1600type TrackBrokenError struct{}
1601
1602func (e TrackBrokenError) Error() string {
1603	return "track of user was broken"
1604}
1605
1606//=============================================================================
1607
1608type IdentifyDidNotCompleteError struct{}
1609
1610func (e IdentifyDidNotCompleteError) Error() string {
1611	return "Identification did not complete."
1612}
1613
1614//=============================================================================
1615
1616type IdentifyFailedError struct {
1617	Assertion string
1618	Reason    string
1619}
1620
1621func (e IdentifyFailedError) Error() string {
1622	return fmt.Sprintf("For user %q: %s", e.Assertion, e.Reason)
1623}
1624
1625//=============================================================================
1626
1627type IdentifiesFailedError struct {
1628}
1629
1630func (e IdentifiesFailedError) Error() string {
1631	return fmt.Sprintf("one or more identifies failed")
1632}
1633
1634func NewIdentifiesFailedError() IdentifiesFailedError {
1635	return IdentifiesFailedError{}
1636}
1637
1638//=============================================================================
1639
1640type IdentifySummaryError struct {
1641	username NormalizedUsername
1642	problems []string
1643}
1644
1645func NewIdentifySummaryError(failure keybase1.TLFIdentifyFailure) IdentifySummaryError {
1646	problem := "a followed proof failed"
1647	if failure.Breaks != nil {
1648		num := len(failure.Breaks.Proofs)
1649		problem = fmt.Sprintf("%d followed proof%s failed", num, GiveMeAnS(num))
1650	}
1651	return IdentifySummaryError{
1652		username: NewNormalizedUsername(failure.User.Username),
1653		problems: []string{problem},
1654	}
1655}
1656
1657func (e IdentifySummaryError) Error() string {
1658	return fmt.Sprintf("failed to identify %q: %s",
1659		e.username,
1660		strings.Join(e.problems, "; "))
1661}
1662
1663func (e IdentifySummaryError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
1664	return chat1.OutboxErrorType_IDENTIFY, true
1665}
1666
1667func (e IdentifySummaryError) Problems() []string {
1668	return e.problems
1669}
1670
1671func IsIdentifyProofError(err error) bool {
1672	switch err.(type) {
1673	case ProofError, IdentifySummaryError:
1674		return true
1675	default:
1676		return false
1677	}
1678}
1679
1680//=============================================================================
1681
1682type NotLatestSubchainError struct {
1683	Msg string
1684}
1685
1686func (e NotLatestSubchainError) Error() string {
1687	return e.Msg
1688}
1689
1690type LoginSessionNotFound struct {
1691	SessionID int
1692}
1693
1694func (e LoginSessionNotFound) Error() string {
1695	return fmt.Sprintf("No login session found for session id %d", e.SessionID)
1696}
1697
1698type KeyVersionError struct{}
1699
1700func (k KeyVersionError) Error() string {
1701	return "Invalid key version"
1702}
1703
1704//=============================================================================
1705
1706type PIDFileLockError struct {
1707	Filename string
1708}
1709
1710func (e PIDFileLockError) Error() string {
1711	return fmt.Sprintf("error locking %s: server already running", e.Filename)
1712}
1713
1714type SecretStoreError struct {
1715	Msg string
1716}
1717
1718func (e SecretStoreError) Error() string {
1719	return "Secret store error: " + e.Msg
1720}
1721
1722type PassphraseProvisionImpossibleError struct{}
1723
1724func (e PassphraseProvisionImpossibleError) Error() string {
1725	return "Passphrase provision is not possible since you have at least one provisioned device or pgp key already"
1726}
1727
1728type ProvisionViaDeviceRequiredError struct{}
1729
1730func (e ProvisionViaDeviceRequiredError) Error() string {
1731	return "You must select an existing device to provision a new device"
1732}
1733
1734type ProvisionUnavailableError struct{}
1735
1736func (e ProvisionUnavailableError) Error() string {
1737	return "Provision unavailable as you don't have access to any of your devices"
1738}
1739
1740type InvalidArgumentError struct {
1741	Msg string
1742}
1743
1744func (e InvalidArgumentError) Error() string {
1745	return fmt.Sprintf("invalid argument: %s", e.Msg)
1746}
1747
1748type RetryExhaustedError struct {
1749}
1750
1751func (e RetryExhaustedError) Error() string {
1752	return "Prompt attempts exhausted."
1753}
1754
1755//=============================================================================
1756
1757type PGPPullLoggedOutError struct{}
1758
1759func (e PGPPullLoggedOutError) Error() string {
1760	return "When running `pgp pull` logged out, you must specify users to pull keys for"
1761}
1762
1763//=============================================================================
1764
1765type UIDelegationUnavailableError struct{}
1766
1767func (e UIDelegationUnavailableError) Error() string {
1768	return "This process does not support UI delegation"
1769}
1770
1771//=============================================================================
1772
1773type UnmetAssertionError struct {
1774	User   string
1775	Remote bool
1776}
1777
1778func (e UnmetAssertionError) Error() string {
1779	which := "local"
1780	if e.Remote {
1781		which = "remote"
1782	}
1783	return fmt.Sprintf("Unmet %s assertions for user %q", which, e.User)
1784}
1785
1786//=============================================================================
1787
1788type ResolutionErrorKind int
1789
1790const (
1791	ResolutionErrorGeneral ResolutionErrorKind = iota
1792	ResolutionErrorNotFound
1793	ResolutionErrorAmbiguous
1794	ResolutionErrorRateLimited
1795	ResolutionErrorInvalidInput
1796	ResolutionErrorRequestFailed
1797)
1798
1799type ResolutionError struct {
1800	Input string
1801	Msg   string
1802	Kind  ResolutionErrorKind
1803}
1804
1805func (e ResolutionError) Error() string {
1806	return fmt.Sprintf("In resolving '%s': %s", e.Input, e.Msg)
1807}
1808
1809func IsResolutionError(err error) bool {
1810	_, ok := err.(ResolutionError)
1811	return ok
1812}
1813
1814func IsResolutionNotFoundError(err error) bool {
1815	rerr, ok := err.(ResolutionError)
1816	if !ok {
1817		return false
1818	}
1819	return rerr.Kind == ResolutionErrorNotFound
1820}
1821
1822//=============================================================================
1823
1824type NoUIDError struct{}
1825
1826func (e NoUIDError) Error() string {
1827	return "No UID given but one was expected"
1828}
1829
1830//=============================================================================
1831
1832type TrackingBrokeError struct{}
1833
1834func (e TrackingBrokeError) Error() string {
1835	return "Following broke"
1836}
1837
1838//=============================================================================
1839
1840type KeybaseSaltpackError struct{}
1841
1842func (e KeybaseSaltpackError) Error() string {
1843	return "Bad use of saltpack for Keybase"
1844}
1845
1846//=============================================================================
1847
1848type TrackStaleError struct {
1849	FirstTrack bool
1850}
1851
1852func (e TrackStaleError) Error() string {
1853	return "Following statement was stale"
1854}
1855
1856//=============================================================================
1857
1858type InconsistentCacheStateError struct{}
1859
1860func (e InconsistentCacheStateError) Error() string {
1861	return "Inconsistent cache state, likely after a DB reset; need a force reload"
1862}
1863
1864//=============================================================================
1865
1866type UnknownStreamError struct{}
1867
1868func (e UnknownStreamError) Error() string {
1869	return "unknown stream format"
1870}
1871
1872type UTF16UnsupportedError struct{}
1873
1874func (e UTF16UnsupportedError) Error() string {
1875	return "UTF-16 not supported"
1876}
1877
1878type WrongCryptoFormatError struct {
1879	Wanted, Received CryptoMessageFormat
1880	Operation        string
1881}
1882
1883func (e WrongCryptoFormatError) Error() string {
1884	ret := "Wrong crypto message format"
1885	switch {
1886	case e.Wanted == CryptoMessageFormatPGP && e.Received == CryptoMessageFormatSaltpack:
1887		ret += "; wanted PGP but got saltpack"
1888		if len(e.Operation) > 0 {
1889			ret += "; try `keybase " + e.Operation + "` instead"
1890		}
1891	case e.Wanted == CryptoMessageFormatSaltpack && e.Received == CryptoMessageFormatPGP:
1892		ret += "; wanted saltpack but got PGP"
1893		if len(e.Operation) > 0 {
1894			ret += "; try `keybase pgp " + e.Operation + "` instead"
1895		}
1896	}
1897	return ret
1898}
1899
1900//=============================================================================
1901
1902type BadInvitationCodeError struct{}
1903
1904func (e BadInvitationCodeError) Error() string {
1905	return "bad invitation code"
1906}
1907
1908type NoMatchingGPGKeysError struct {
1909	Fingerprints    []string
1910	HasActiveDevice bool // true if the user has an active device that they chose not to use
1911}
1912
1913func (e NoMatchingGPGKeysError) Error() string {
1914	return fmt.Sprintf("No private GPG keys found on this device that match account PGP keys %s", strings.Join(e.Fingerprints, ", "))
1915}
1916
1917type DeviceAlreadyProvisionedError struct{}
1918
1919func (e DeviceAlreadyProvisionedError) Error() string {
1920	return "Device already provisioned for current user"
1921}
1922
1923type DirExecError struct {
1924	Path string
1925}
1926
1927func (e DirExecError) Error() string {
1928	return fmt.Sprintf("file %q is a directory and not executable", e.Path)
1929}
1930
1931type FileExecError struct {
1932	Path string
1933}
1934
1935func (e FileExecError) Error() string {
1936	return fmt.Sprintf("file %q is not executable", e.Path)
1937}
1938
1939func IsExecError(err error) bool {
1940	if err == nil {
1941		return false
1942	}
1943
1944	switch err.(type) {
1945	case DirExecError:
1946		return true
1947	case FileExecError:
1948		return true
1949	case *exec.Error:
1950		return true
1951	case *os.PathError:
1952		return true
1953	}
1954	return false
1955}
1956
1957//=============================================================================
1958
1959type UserDeletedError struct {
1960	Msg string
1961}
1962
1963func (e UserDeletedError) Error() string {
1964	if len(e.Msg) == 0 {
1965		return "User deleted"
1966	}
1967	return e.Msg
1968}
1969
1970//=============================================================================
1971
1972type DeviceNameInUseError struct{}
1973
1974func (e DeviceNameInUseError) Error() string {
1975	return "device name already in use"
1976}
1977
1978//=============================================================================
1979
1980type DeviceBadNameError struct{}
1981
1982func (e DeviceBadNameError) Error() string {
1983	return "device name is malformed"
1984}
1985
1986//=============================================================================
1987
1988type UnexpectedChatDataFromServer struct {
1989	Msg string
1990}
1991
1992func (e UnexpectedChatDataFromServer) Error() string {
1993	return fmt.Sprintf("unexpected chat data from server: %s", e.Msg)
1994}
1995
1996//=============================================================================
1997
1998type ChatInternalError struct{}
1999
2000func (e ChatInternalError) Error() string {
2001	return "chat internal error"
2002}
2003
2004//=============================================================================
2005
2006type ChatConvExistsError struct {
2007	ConvID chat1.ConversationID
2008}
2009
2010func (e ChatConvExistsError) Error() string {
2011	return fmt.Sprintf("conversation already exists: %s", e.ConvID)
2012}
2013
2014//=============================================================================
2015
2016type ChatMessageCollisionError struct {
2017	HeaderHash string
2018}
2019
2020func (e ChatMessageCollisionError) Error() string {
2021	return fmt.Sprintf("a message with that hash already exists: %s", e.HeaderHash)
2022}
2023
2024//=============================================================================
2025
2026type ChatCollisionError struct {
2027}
2028
2029func (e ChatCollisionError) Error() string {
2030	return fmt.Sprintf("conversation id collision")
2031}
2032
2033//=============================================================================
2034
2035type ChatUnknownTLFIDError struct {
2036	TlfID chat1.TLFID
2037}
2038
2039func (e ChatUnknownTLFIDError) Error() string {
2040	return fmt.Sprintf("unknown TLF ID: %s", hex.EncodeToString(e.TlfID))
2041}
2042
2043//=============================================================================
2044
2045type ChatNotInConvError struct {
2046	UID    gregor.UID
2047	ConvID chat1.ConversationID
2048}
2049
2050func (e ChatNotInConvError) Error() string {
2051	return fmt.Sprintf("user is not in conversation: %s uid: %s", e.ConvID.String(), e.UID.String())
2052}
2053
2054func (e ChatNotInConvError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2055	return chat1.OutboxErrorType_MISC, true
2056}
2057
2058//=============================================================================
2059
2060type ChatNotInTeamError struct {
2061	UID   gregor.UID
2062	TlfID chat1.TLFID
2063}
2064
2065func (e ChatNotInTeamError) Error() string {
2066	return fmt.Sprintf("user is not in team: %v uid: %s", e.TlfID, e.UID.String())
2067}
2068
2069func (e ChatNotInTeamError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2070	return chat1.OutboxErrorType_MISC, true
2071}
2072
2073//=============================================================================
2074
2075type ChatBadMsgError struct {
2076	Msg string
2077}
2078
2079func (e ChatBadMsgError) Error() string {
2080	return e.Msg
2081}
2082
2083func (e ChatBadMsgError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2084	return chat1.OutboxErrorType_MISC, true
2085}
2086
2087//=============================================================================
2088
2089type ChatBroadcastError struct {
2090	Msg string
2091}
2092
2093func (e ChatBroadcastError) Error() string {
2094	return e.Msg
2095}
2096
2097//=============================================================================
2098
2099type ChatRateLimitError struct {
2100	Msg       string
2101	RateLimit chat1.RateLimit
2102}
2103
2104func (e ChatRateLimitError) Error() string {
2105	return e.Msg
2106}
2107
2108//=============================================================================
2109
2110type ChatAlreadySupersededError struct {
2111	Msg string
2112}
2113
2114func (e ChatAlreadySupersededError) Error() string {
2115	return e.Msg
2116}
2117
2118func (e ChatAlreadySupersededError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2119	return chat1.OutboxErrorType_MISC, true
2120}
2121
2122//=============================================================================
2123
2124type ChatAlreadyDeletedError struct {
2125	Msg string
2126}
2127
2128func (e ChatAlreadyDeletedError) Error() string {
2129	return e.Msg
2130}
2131
2132func (e ChatAlreadyDeletedError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2133	return chat1.OutboxErrorType_ALREADY_DELETED, true
2134}
2135
2136//=============================================================================
2137
2138type ChatBadConversationError struct {
2139	Msg string
2140}
2141
2142func (e ChatBadConversationError) Error() string {
2143	return e.Msg
2144}
2145
2146func (e ChatBadConversationError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2147	return chat1.OutboxErrorType_MISC, true
2148}
2149
2150//=============================================================================
2151type ChatTLFFinalizedError struct {
2152	TlfID chat1.TLFID
2153}
2154
2155func (e ChatTLFFinalizedError) Error() string {
2156	return fmt.Sprintf("unable to create conversation on finalized TLF: %s", e.TlfID)
2157}
2158
2159//=============================================================================
2160
2161type ChatDuplicateMessageError struct {
2162	OutboxID chat1.OutboxID
2163}
2164
2165func (e ChatDuplicateMessageError) Error() string {
2166	return fmt.Sprintf("duplicate message send: outboxID: %s", e.OutboxID)
2167}
2168
2169func (e ChatDuplicateMessageError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2170	return chat1.OutboxErrorType_DUPLICATE, true
2171}
2172
2173//=============================================================================
2174
2175type ChatClientError struct {
2176	Msg string
2177}
2178
2179func (e ChatClientError) Error() string {
2180	return fmt.Sprintf("error from chat server: %s", e.Msg)
2181}
2182
2183func (e ChatClientError) IsImmediateFail() (chat1.OutboxErrorType, bool) {
2184	if strings.HasPrefix(e.Msg, "Admins have set that you must be a team") {
2185		return chat1.OutboxErrorType_MINWRITER, true
2186	}
2187	return chat1.OutboxErrorType_MISC, true
2188}
2189
2190//=============================================================================
2191
2192type ChatUsersAlreadyInConversationError struct {
2193	Uids []keybase1.UID
2194}
2195
2196func (e ChatUsersAlreadyInConversationError) Error() string {
2197	return fmt.Sprintf("Cannot readd existing users to this conversation")
2198}
2199
2200//=============================================================================
2201
2202type ChatStalePreviousStateError struct{}
2203
2204func (e ChatStalePreviousStateError) Error() string {
2205	return "Unable to change chat channels"
2206}
2207
2208//=============================================================================
2209
2210type ChatEphemeralRetentionPolicyViolatedError struct {
2211	MaxAge gregor1.DurationSec
2212}
2213
2214func (e ChatEphemeralRetentionPolicyViolatedError) Error() string {
2215	return fmt.Sprintf("messages in this conversation are required to be exploding with a maximum lifetime of %v", e.MaxAge.ToDuration())
2216}
2217
2218//=============================================================================
2219
2220type InvalidAddressError struct {
2221	Msg string
2222}
2223
2224func (e InvalidAddressError) Error() string {
2225	return e.Msg
2226}
2227
2228type ExistsError struct {
2229	Msg string
2230}
2231
2232func (e ExistsError) Error() string {
2233	return e.Msg
2234}
2235
2236//=============================================================================
2237
2238type LevelDBOpenClosedError struct{}
2239
2240func (e LevelDBOpenClosedError) Error() string {
2241	return "opening a closed DB"
2242}
2243
2244//=============================================================================
2245
2246type DBError struct {
2247	Msg string
2248}
2249
2250func (e DBError) Error() string {
2251	return fmt.Sprintf("DB error: %s", e.Msg)
2252}
2253
2254func NewDBError(s string) DBError {
2255	return DBError{Msg: s}
2256}
2257
2258//=============================================================================
2259
2260// These rekey types are not-exact duplicates of the libkbfs errors of the same name.
2261
2262// NeedSelfRekeyError indicates that the folder in question needs to
2263// be rekeyed for the local device, and can be done so by one of the
2264// other user's devices.
2265type NeedSelfRekeyError struct {
2266	// Canonical tlf name
2267	Tlf string
2268	Msg string
2269}
2270
2271func (e NeedSelfRekeyError) Error() string {
2272	return e.Msg
2273}
2274
2275// NeedOtherRekeyError indicates that the folder in question needs to
2276// be rekeyed for the local device, and can only done so by one of the
2277// other users.
2278type NeedOtherRekeyError struct {
2279	// Canonical tlf name
2280	Tlf string
2281	Msg string
2282}
2283
2284func (e NeedOtherRekeyError) Error() string {
2285	return e.Msg
2286}
2287
2288//=============================================================================
2289
2290type DeviceNotFoundError struct {
2291	Where  string
2292	ID     keybase1.DeviceID
2293	Loaded bool
2294}
2295
2296func (e DeviceNotFoundError) Error() string {
2297	loaded := ""
2298	if !e.Loaded {
2299		loaded = " (no device keys loaded)"
2300	}
2301	return fmt.Sprintf("%s: no device found for ID=%s%s", e.Where, e.ID, loaded)
2302}
2303
2304//=============================================================================
2305
2306// PseudonymGetError is sometimes written by unmarshaling (no fields of) a server response.
2307type PseudonymGetError struct {
2308	msg string
2309}
2310
2311func (e PseudonymGetError) Error() string {
2312	if e.msg == "" {
2313		return "Pseudonym could not be resolved"
2314	}
2315	return e.msg
2316}
2317
2318var _ error = (*PseudonymGetError)(nil)
2319
2320//=============================================================================
2321
2322// PseudonymGetError is sometimes written by unmarshaling (some fields of) a server response.
2323type KeyPseudonymGetError struct {
2324	msg string
2325}
2326
2327func (e KeyPseudonymGetError) Error() string {
2328	if e.msg == "" {
2329		return "Pseudonym could not be resolved"
2330	}
2331	return e.msg
2332}
2333
2334var _ error = (*KeyPseudonymGetError)(nil)
2335
2336//=============================================================================
2337
2338type PerUserKeyImportError struct {
2339	msg string
2340}
2341
2342func (e PerUserKeyImportError) Error() string {
2343	return fmt.Sprintf("per-user-key import error: %s", e.msg)
2344}
2345
2346func NewPerUserKeyImportError(format string, args ...interface{}) PerUserKeyImportError {
2347	return PerUserKeyImportError{
2348		msg: fmt.Sprintf(format, args...),
2349	}
2350}
2351
2352//=============================================================================
2353
2354type LoginOfflineError struct {
2355	msg string
2356}
2357
2358func NewLoginOfflineError(msg string) LoginOfflineError {
2359	return LoginOfflineError{msg: msg}
2360}
2361
2362func (e LoginOfflineError) Error() string {
2363	return "LoginOffline error: " + e.msg
2364}
2365
2366//=============================================================================
2367
2368type EldestSeqnoMissingError struct{}
2369
2370func (e EldestSeqnoMissingError) Error() string {
2371	return "user's eldest seqno has not been loaded"
2372}
2373
2374//=============================================================================
2375
2376type AccountResetError struct {
2377	expected keybase1.UserVersion
2378	received keybase1.Seqno
2379}
2380
2381func NewAccountResetError(uv keybase1.UserVersion, r keybase1.Seqno) AccountResetError {
2382	return AccountResetError{expected: uv, received: r}
2383}
2384
2385func (e AccountResetError) Error() string {
2386	if e.received == keybase1.Seqno(0) {
2387		return fmt.Sprintf("Account reset, and not reestablished (for user %s)", e.expected.String())
2388	}
2389	return fmt.Sprintf("Account reset, reestablished at %d (for user %s)", e.received, e.expected.String())
2390}
2391
2392type BadSessionError struct {
2393	Desc string
2394}
2395
2396func (e BadSessionError) Error() string {
2397	return fmt.Sprintf("bad session: %s", e.Desc)
2398}
2399
2400type LoginStateTimeoutError struct {
2401	ActiveRequest    string
2402	AttemptedRequest string
2403	Duration         time.Duration
2404}
2405
2406func (e LoginStateTimeoutError) Error() string {
2407	return fmt.Sprintf("LoginState request timeout - attempted: %s, active request: %s, duration: %s", e.ActiveRequest, e.AttemptedRequest, e.Duration)
2408}
2409
2410type KBFSNotRunningError struct{}
2411
2412func (e KBFSNotRunningError) Error() string {
2413	const err string = "Keybase services aren't running - KBFS client not found."
2414	switch runtime.GOOS {
2415	case "linux":
2416		return fmt.Sprintf("%s On Linux you need to start them after an update with `run_keybase` command.", err)
2417	default:
2418		return err
2419	}
2420}
2421
2422type RevokeCurrentDeviceError struct{}
2423
2424func (e RevokeCurrentDeviceError) Error() string {
2425	return "cannot revoke the current device without confirmation"
2426}
2427
2428type RevokeLastDeviceError struct{ NoPassphrase bool }
2429
2430func (e RevokeLastDeviceError) Error() string {
2431	if e.NoPassphrase {
2432		return "cannot revoke the last device; set a passphrase first"
2433	}
2434	return "cannot revoke the last device in your account without confirmation"
2435}
2436
2437// users with PGP keys who try to revoke last device get this:
2438type RevokeLastDevicePGPError struct{}
2439
2440func (e RevokeLastDevicePGPError) Error() string {
2441	return "You cannot revoke the last device in your account. You can reset your account here: keybase.io/#account-reset"
2442}
2443
2444//=============================================================================
2445
2446type ImplicitTeamDisplayNameError struct {
2447	msg string
2448}
2449
2450func (e ImplicitTeamDisplayNameError) Error() string {
2451	return fmt.Sprintf("Error parsing implicit team name: %s", e.msg)
2452}
2453
2454func NewImplicitTeamDisplayNameError(format string, args ...interface{}) ImplicitTeamDisplayNameError {
2455	return ImplicitTeamDisplayNameError{fmt.Sprintf(format, args...)}
2456}
2457
2458type TeamVisibilityError struct {
2459	wantedPublic bool
2460	gotPublic    bool
2461}
2462
2463func (e TeamVisibilityError) Error() string {
2464	pps := func(public bool) string {
2465		if public {
2466			return "public"
2467		}
2468		return "private"
2469	}
2470	return fmt.Sprintf("loaded for %v team but got %v team", pps(e.wantedPublic), pps(e.gotPublic))
2471}
2472
2473func NewTeamVisibilityError(wantedPublic, gotPublic bool) TeamVisibilityError {
2474	return TeamVisibilityError{wantedPublic: wantedPublic, gotPublic: gotPublic}
2475}
2476
2477type KeyMaskNotFoundError struct {
2478	App keybase1.TeamApplication
2479	Gen keybase1.PerTeamKeyGeneration
2480}
2481
2482func (e KeyMaskNotFoundError) Error() string {
2483	msg := fmt.Sprintf("You don't have access to %s for this team", e.App)
2484	if e.Gen != keybase1.PerTeamKeyGeneration(0) {
2485		msg += fmt.Sprintf(" (at generation %d)", int(e.Gen))
2486	}
2487	return msg
2488}
2489
2490type ProvisionFailedOfflineError struct{}
2491
2492func (e ProvisionFailedOfflineError) Error() string {
2493	return "Device provisioning failed because the device is offline"
2494}
2495
2496//=============================================================================
2497
2498func UserErrorFromStatus(s keybase1.StatusCode) error {
2499	switch s {
2500	case keybase1.StatusCode_SCOk:
2501		return nil
2502	case keybase1.StatusCode_SCDeleted:
2503		return UserDeletedError{}
2504	default:
2505		return &APIError{Code: int(s), Msg: "user status error"}
2506	}
2507}
2508
2509//=============================================================================
2510
2511// InvalidRepoNameError indicates that a repo name is invalid.
2512type InvalidRepoNameError struct {
2513	Name string
2514}
2515
2516func (e InvalidRepoNameError) Error() string {
2517	return fmt.Sprintf("Invalid repo name %q", e.Name)
2518}
2519
2520//=============================================================================
2521
2522// RepoAlreadyCreatedError is returned when trying to create a repo
2523// that already exists.
2524type RepoAlreadyExistsError struct {
2525	DesiredName  string
2526	ExistingName string
2527	ExistingID   string
2528}
2529
2530func (e RepoAlreadyExistsError) Error() string {
2531	return fmt.Sprintf(
2532		"A repo named %s (id=%s) already existed when trying to create "+
2533			"a repo named %s", e.ExistingName, e.ExistingID, e.DesiredName)
2534}
2535
2536//=============================================================================
2537
2538// RepoDoesntExistError is returned when trying to delete a repo that doesn't exist.
2539type RepoDoesntExistError struct {
2540	Name string
2541}
2542
2543func (e RepoDoesntExistError) Error() string {
2544	return fmt.Sprintf("There is no repo named %q.", e.Name)
2545}
2546
2547//=============================================================================
2548
2549// NoOpError is returned when an RPC call is issued but it would
2550// result in no change, so the call is dropped.
2551type NoOpError struct {
2552	Desc string
2553}
2554
2555func (e NoOpError) Error() string {
2556	return e.Desc
2557}
2558
2559//=============================================================================
2560
2561type NoSpaceOnDeviceError struct {
2562	Desc string
2563}
2564
2565func (e NoSpaceOnDeviceError) Error() string {
2566	return e.Desc
2567}
2568
2569//=============================================================================
2570
2571type TeamInviteBadTokenError struct{}
2572
2573func (e TeamInviteBadTokenError) Error() string {
2574	return "invalid team invite token"
2575}
2576
2577//=============================================================================
2578
2579type TeamWritePermDeniedError struct{}
2580
2581func (e TeamWritePermDeniedError) Error() string {
2582	return "permission denied to modify team"
2583}
2584
2585//=============================================================================
2586
2587type TeamInviteTokenReusedError struct{}
2588
2589func (e TeamInviteTokenReusedError) Error() string {
2590	return "team invite token already used"
2591}
2592
2593//=============================================================================
2594
2595type TeamBadMembershipError struct{}
2596
2597func (e TeamBadMembershipError) Error() string {
2598	return "cannot perform operation because not a member of the team"
2599}
2600
2601//=============================================================================
2602
2603type TeamProvisionalError struct {
2604	CanKey                bool
2605	IsPublic              bool
2606	PreResolveDisplayName string
2607}
2608
2609func (e TeamProvisionalError) Error() string {
2610	ret := "team is provisional"
2611	if e.CanKey {
2612		ret += ", but the user can key"
2613	} else {
2614		ret += ", and the user cannot key"
2615	}
2616	return ret
2617}
2618
2619func NewTeamProvisionalError(canKey bool, isPublic bool, dn string) error {
2620	return TeamProvisionalError{canKey, isPublic, dn}
2621}
2622
2623//=============================================================================
2624
2625type NoActiveDeviceError struct{}
2626
2627func (e NoActiveDeviceError) Error() string { return "no active device" }
2628
2629//=============================================================================
2630
2631type NoTriplesecError struct{}
2632
2633func (e NoTriplesecError) Error() string { return "No Triplesec was available after prompt" }
2634func NewNoTriplesecError() error         { return NoTriplesecError{} }
2635
2636//=============================================================================
2637
2638type HexWrongLengthError struct{ msg string }
2639
2640func NewHexWrongLengthError(msg string) HexWrongLengthError { return HexWrongLengthError{msg} }
2641
2642func (e HexWrongLengthError) Error() string { return e.msg }
2643
2644//=============================================================================
2645
2646type EphemeralPairwiseMACsMissingUIDsError struct{ UIDs []keybase1.UID }
2647
2648func NewEphemeralPairwiseMACsMissingUIDsError(uids []keybase1.UID) EphemeralPairwiseMACsMissingUIDsError {
2649	return EphemeralPairwiseMACsMissingUIDsError{
2650		UIDs: uids,
2651	}
2652}
2653
2654func (e EphemeralPairwiseMACsMissingUIDsError) Error() string {
2655	return fmt.Sprintf("Missing %d uids from pairwise macs", len(e.UIDs))
2656}
2657
2658//=============================================================================
2659
2660type RecipientNotFoundError struct {
2661	error
2662}
2663
2664func NewRecipientNotFoundError(message string) error {
2665	return RecipientNotFoundError{
2666		error: fmt.Errorf(message),
2667	}
2668}
2669
2670//=============================================================================
2671
2672type FeatureFlagError struct {
2673	msg     string
2674	feature Feature
2675}
2676
2677func NewFeatureFlagError(s string, f Feature) error {
2678	return FeatureFlagError{s, f}
2679}
2680
2681func (f FeatureFlagError) Feature() Feature {
2682	return f.feature
2683}
2684
2685func (f FeatureFlagError) Error() string {
2686	return fmt.Sprintf("Feature %q flagged off: %s", f.feature, f.msg)
2687}
2688
2689var _ error = FeatureFlagError{}
2690
2691//=============================================================================
2692
2693type UserReverifyNeededError struct {
2694	msg string
2695}
2696
2697func NewUserReverifyNeededError(s string) error {
2698	return UserReverifyNeededError{s}
2699}
2700
2701func (e UserReverifyNeededError) Error() string {
2702	return fmt.Sprintf("User green link error: %s", e.msg)
2703}
2704
2705//=============================================================================
2706
2707type OfflineError struct {
2708}
2709
2710func NewOfflineError() error {
2711	return OfflineError{}
2712}
2713
2714func (e OfflineError) Error() string {
2715	return "Offline, and no cached results found"
2716}
2717
2718//=============================================================================
2719
2720type VerboseError interface {
2721	Error() string
2722	Verbose() string
2723}
2724
2725type InvalidStellarAccountIDError struct {
2726	details string
2727}
2728
2729func NewInvalidStellarAccountIDError(details string) InvalidStellarAccountIDError {
2730	return InvalidStellarAccountIDError{
2731		details: details,
2732	}
2733}
2734
2735func (e InvalidStellarAccountIDError) Error() string {
2736	return "Invalid Stellar address."
2737}
2738
2739func (e InvalidStellarAccountIDError) Verbose() string {
2740	return fmt.Sprintf("Invalid Stellar address: %s", e.details)
2741}
2742
2743//=============================================================================
2744
2745type ResetWithActiveDeviceError struct {
2746}
2747
2748func (e ResetWithActiveDeviceError) Error() string {
2749	return "You cannot reset your account from a logged-in device."
2750}
2751
2752//=============================================================================
2753
2754type ResetMissingParamsError struct {
2755	msg string
2756}
2757
2758func NewResetMissingParamsError(msg string) error {
2759	return ResetMissingParamsError{msg: msg}
2760}
2761
2762func (e ResetMissingParamsError) Error() string {
2763	return e.msg
2764}
2765
2766//============================================================================
2767
2768type ChainLinkBadUnstubError struct {
2769	msg string
2770}
2771
2772func NewChainLinkBadUnstubError(s string) error {
2773	return ChainLinkBadUnstubError{s}
2774}
2775
2776func (c ChainLinkBadUnstubError) Error() string {
2777	return c.msg
2778}
2779
2780//============================================================================
2781
2782// AppOutdatedError indicates that an operation failed because the client does
2783// not support some necessary feature and needs to be updated.
2784type AppOutdatedError struct {
2785	cause error
2786}
2787
2788func NewAppOutdatedError(cause error) AppOutdatedError {
2789	return AppOutdatedError{cause: cause}
2790}
2791
2792func (e AppOutdatedError) Error() string {
2793	if e.cause != nil {
2794		return fmt.Sprintf("AppOutdatedError: %v", e.cause.Error())
2795	}
2796	return fmt.Sprintf("AppOutdatedError")
2797}
2798
2799//============================================================================
2800
2801type PushSecretWithoutPasswordError struct {
2802	msg string
2803}
2804
2805func NewPushSecretWithoutPasswordError(msg string) error {
2806	return PushSecretWithoutPasswordError{msg: msg}
2807}
2808
2809func (e PushSecretWithoutPasswordError) Error() string {
2810	return e.msg
2811}
2812
2813// HumanErrorer is an interface that errors can implement if they want to expose what went wrong to
2814// humans, either via the CLI or via the electron interface. It sometimes happens that errors get
2815// wrapped inside of other errors up a stack, and it's hard to know what to show the user.
2816// This can help.
2817type HumanErrorer interface {
2818	HumanError() error
2819}
2820
2821// HumanError takes an error and returns the topmost human error that's in the error, maybe to export
2822// to the CLI, KBFS, or Electron. It's a mashup of the pkg/errors Error() function, and also our
2823// own desire to return the topmost HumanError.
2824//
2825// See https://github.com/pkg/errors/blob/master/errors.go for the original pkg/errors code
2826func HumanError(err error) error {
2827	type causer interface {
2828		Cause() error
2829	}
2830
2831	for err != nil {
2832		humanErrorer, ok := err.(HumanErrorer)
2833		if ok {
2834			tmp := humanErrorer.HumanError()
2835			if tmp != nil {
2836				return tmp
2837			}
2838		}
2839		cause, ok := err.(causer)
2840		if !ok {
2841			break
2842		}
2843		err = cause.Cause()
2844	}
2845	return err
2846}
2847
2848//============================================================================
2849
2850type TeamContactSettingsBlockError struct {
2851	blockedUIDs      []keybase1.UID
2852	blockedUsernames []NormalizedUsername
2853}
2854
2855func (e TeamContactSettingsBlockError) BlockedUIDs() []keybase1.UID {
2856	return e.blockedUIDs
2857}
2858
2859func (e TeamContactSettingsBlockError) BlockedUsernames() []NormalizedUsername {
2860	return e.blockedUsernames
2861}
2862
2863func (e TeamContactSettingsBlockError) Error() string {
2864	var tmp []string
2865	for _, u := range e.blockedUsernames {
2866		tmp = append(tmp, u.String())
2867	}
2868	return fmt.Sprintf("some users couldn't be contacted due to privacy settings (%s)", strings.Join(tmp, ","))
2869}
2870
2871func NewTeamContactSettingsBlockError(s *AppStatus) TeamContactSettingsBlockError {
2872	e := TeamContactSettingsBlockError{}
2873	for k, v := range s.Fields {
2874		switch k {
2875		case "uids":
2876			e.blockedUIDs = parseUIDsFromString(v)
2877		case "usernames":
2878			e.blockedUsernames = parseUsernamesFromString(v)
2879		}
2880	}
2881	return e
2882}
2883
2884// parseUIDsFromString takes a comma-separate string of UIDs and returns an array of UIDs,
2885// **ignoring any errors** since sometimes need to call this code on an error path.
2886func parseUIDsFromString(s string) []keybase1.UID {
2887	tmp := strings.Split(s, ",")
2888	var res []keybase1.UID
2889	for _, elem := range tmp {
2890		u, err := keybase1.UIDFromString(elem)
2891		if err == nil {
2892			res = append(res, u)
2893		}
2894	}
2895	return res
2896}
2897
2898// parseUsernamesFromString takes a string that's a comma-separated list of usernames and then
2899// returns a slice of NormalizedUsernames after splitting them. Does no error checking.
2900func parseUsernamesFromString(s string) []NormalizedUsername {
2901	tmp := strings.Split(s, ",")
2902	var res []NormalizedUsername
2903	for _, elem := range tmp {
2904		res = append(res, NewNormalizedUsername(elem))
2905	}
2906	return res
2907}
2908
2909//=============================================================================
2910
2911type HiddenChainDataMissingError struct {
2912	note string
2913}
2914
2915func (e HiddenChainDataMissingError) Error() string {
2916	return fmt.Sprintf("hidden chain data missing error: %s", e.note)
2917}
2918
2919func NewHiddenChainDataMissingError(format string, args ...interface{}) HiddenChainDataMissingError {
2920	return HiddenChainDataMissingError{fmt.Sprintf(format, args...)}
2921}
2922
2923var _ error = HiddenChainDataMissingError{}
2924
2925type HiddenMerkleErrorType int
2926
2927const (
2928	HiddenMerkleErrorNone HiddenMerkleErrorType = iota
2929
2930	HiddenMerkleErrorInconsistentLeaf
2931	HiddenMerkleErrorInconsistentUncommittedSeqno
2932	HiddenMerkleErrorInvalidHiddenResponseType
2933	HiddenMerkleErrorInvalidLeafType
2934	HiddenMerkleErrorNoHiddenChainInLeaf
2935	HiddenMerkleErrorOldLinkNotYetCommitted
2936	HiddenMerkleErrorRollbackCommittedSeqno
2937	HiddenMerkleErrorRollbackUncommittedSeqno
2938	HiddenMerkleErrorServerWitholdingLinks
2939	HiddenMerkleErrorUnexpectedAbsenceProof
2940)
2941
2942type HiddenMerkleError struct {
2943	m string
2944	t HiddenMerkleErrorType
2945}
2946
2947func NewHiddenMerkleError(t HiddenMerkleErrorType, format string, args ...interface{}) HiddenMerkleError {
2948	return HiddenMerkleError{
2949		t: t,
2950		m: fmt.Sprintf(format, args...),
2951	}
2952}
2953
2954func (e HiddenMerkleError) ErrorType() HiddenMerkleErrorType {
2955	return e.t
2956}
2957
2958func (e HiddenMerkleError) Error() string {
2959	return fmt.Sprintf("hidden merkle client error (type %v): %s", e.t, e.m)
2960}
2961
2962var _ error = HiddenMerkleError{}
2963
2964func IsTooManyFilesError(err error) bool {
2965	return strings.Contains(strings.ToLower(err.Error()), "too many open files")
2966}
2967