func showSecret(ps *store.SecretStore, cfg *config) error { label := cfg.Args[0] if !ps.Has(label) { return errors.New("no token found under label") } rec := ps.Store[label] var otpType int otp, label, err := twofactor.FromURL(string(rec.Secret)) if err != nil { return err } if _, ok := rec.Metadata["type"]; !ok { otpType = parseTwofactorType(otp.Type()) } else { otpType = parseOTPKind(string(rec.Metadata["type"])) } switch otpType { case TOTP: printTOTP(label, otp) case GoogleTOTP: printGTOTP(label, otp) case HOTP: printHOTP(label, otp) cfg.Updated = true hotp := otp.(*twofactor.HOTP) rec.Secret = []byte(hotp.URL(label)) rec.Timestamp = time.Now().Unix() ps.Store[label] = rec default: return errors.New("unknown OTP type") } return nil }
func showQR(ps *store.SecretStore, cfg *config) error { label := cfg.Args[0] if !ps.Has(label) { return errors.New("no token found under label") } filename := cfg.Args[1] rec := ps.Store[label] otp, label, err := twofactor.FromURL(string(rec.Secret)) if err != nil { return err } var qr []byte switch otp.Type() { case twofactor.OATH_HOTP: hotp := otp.(*twofactor.HOTP) qr, err = hotp.QR(label) case twofactor.OATH_TOTP: totp := otp.(*twofactor.TOTP) qr, err = totp.QR(label) default: err = errors.New("QR codes can only be generated for OATH OTPs") } if err != nil { return err } return ioutil.WriteFile(filename, qr, 0600) }