Пример #1
0
func initStore(path string, m secret.ScryptMode) error {
	passphrase, err := util.PassPrompt("Secrets passphrase> ")
	if err != nil {
		util.Errorf("Failed to read passphrase: %v", err)
		return err
	}

	if len(passphrase) == 0 {
		return fmt.Errorf("No passphrase provided.")
	}

	defer util.Zero(passphrase)
	passwords := store.NewSecretStore(passphrase)
	if passwords == nil {
		return fmt.Errorf("failed to create store")
	}

	fmt.Println("creating store...")
	fileData, ok := store.MarshalSecretStore(passwords, m)
	if !ok {
		return fmt.Errorf("failed to marshal store")
	}

	err = util.WriteFile(fileData, path)
	if err != nil {
		return err
	}

	passwords, ok = store.UnmarshalSecretStore(fileData, passphrase, m)
	if !ok {
		err = fmt.Errorf("failed to unmarshal store")
	}
	return err
}
Пример #2
0
func merge(ps *store.SecretStore, cfg *config, m secret.ScryptMode) error {
	otherPath := cfg.Args[0]
	passphrase, err := util.PassPrompt("Passphrase for other store> ")
	if err != nil {
		return err
	}

	otherData, err := util.ReadFile(otherPath)
	if err != nil {
		return err
	}

	otherStore, ok := store.UnmarshalSecretStore(otherData, passphrase, m)
	if !ok {
		return errors.New("failed to open other password store")
	}

	mergeList := ps.Merge(otherStore)
	fmt.Printf("%+v\n", mergeList)
	if len(mergeList) > 0 {
		sort.Strings(mergeList)
		for _, label := range mergeList {
			fmt.Printf("Merged '%s'\n", label)
		}
	}
	return nil
}
Пример #3
0
func loadStore(path string, m secret.ScryptMode) *store.SecretStore {
	passphrase, err := util.PassPrompt("Secrets passphrase> ")
	if err != nil {
		util.Errorf("Failed to read passphrase: %v", err)
		return nil
	}

	var passwords *store.SecretStore
	if ok, _ := util.Exists(path); ok {
		defer util.Zero(passphrase)
		fileData, err := util.ReadFile(path)
		if err != nil {
			util.Errorf("%v", err)
			return nil
		}
		var ok bool
		passwords, ok = store.UnmarshalSecretStore(fileData, passphrase, m)
		if !ok {
			return nil
		}
		return passwords
	}
	util.Errorf("could not find %s", path)
	return nil
}
Пример #4
0
func passwd(args []string) error {
	newPass, err := util.PassPrompt("New password: "******"Confirm: ")
	if err != nil {
		return err
	}

	if !bytes.Equal(confirmPass, newPass) {
		return errors.New("passwords don't match")
	}

	util.Zero(confirmPass)

	session.Store.ChangePassword(newPass)
	fmt.Println("[+] Password updated.")
	return nil
}
Пример #5
0
func loadStore(path string) *store.KeyStore {
	// If keystore is newly created, we'll want to write it to
	// disk before leaving this function.
	var flush bool
	if exists, _ := util.Exists(path); !exists {
		flush = true
	}

	passphrase, err := util.PassPrompt("keystore passphrase> ")
	if err != nil {
		util.Errorf("%v", err)
		return nil
	}
	defer util.Zero(passphrase)

	keystore, ok := store.LoadKeyStore(path, true)
	if !ok {
		fmt.Printf("error in LoadKeyStore")
		return nil
	}
	if !keystore.Valid(false) {
		fmt.Println("keystore not valid")
		return nil
	}

	if !flush {
		if !keystore.Unlock(passphrase) {
			return nil
		}
		return keystore
	}

	if !keystore.LockWith(passphrase) {
		util.Errorf("Failed to set initial passphrase.")
		return nil
	} else if !keystore.Unlock(passphrase) {
		util.Errorf("Flushing keystore failed.")
		return nil
	}

	out, err := keystore.Dump()
	if err != nil {
		log.Printf("WARNING: failed to dump keystore: %v", err)
		return nil
	}
	err = ioutil.WriteFile(path, out, 0644)
	if err != nil {
		log.Printf("WARNING: failed to write keystore: %v", err)
	}

	return keystore
}
Пример #6
0
func main() {
	baseFile := filepath.Join(os.Getenv("HOME"), ".secrets.db")
	flag.StringVar(&session.Path, "f", baseFile, "path to password store")
	flag.DurationVar(&defaultTimeout, "t", defaultTimeout, "`timeout`")
	scryptInteractive := flag.Bool("i", false, "use scrypt interactive")
	flag.Parse()

	if defaultTimeout > maxTimeout {
		fmt.Fprintf(os.Stderr, "[!] timeout is too long (max is %s).\n",
			maxTimeout)
		os.Exit(1)
	}

	session.Scrypt = secret.ScryptStandard
	if *scryptInteractive {
		session.Scrypt = secret.ScryptInteractive
	}

	prompt := fmt.Sprintf("Passphrase to unlock %s: ", session.Path)
	passphrase, err := util.PassPrompt(prompt)
	if err != nil {
		fmt.Fprintf(os.Stderr, "[!] %v\n", err)
		os.Exit(1)
	}

	fileData, err := ioutil.ReadFile(session.Path)
	if err != nil {
		fmt.Fprintf(os.Stderr, "[!] %v\n", err)
		os.Exit(1)
	}

	var ok bool
	session.Store, ok = store.UnmarshalSecretStore(fileData, passphrase,
		session.Scrypt)
	if !ok {
		fmt.Fprintf(os.Stderr, "[!] failed to unlocked store.\n")
		os.Exit(1)
	}
	defer shutdown()

	inputLoop(session.Path)
}
Пример #7
0
func multi(ps *store.SecretStore, cfg *config, m secret.ScryptMode) error {
	fmt.Println("Use an empty name to indicate that you are done.")
	for {
		name, err := util.ReadLine("Name: ")
		if err != nil {
			return err
		} else if name == "" {
			break
		}

		var rec *store.SecretRecord
		if ps.Has(name) {
			if !cfg.Overwrite {
				util.Errorf("Entry exists, not forcing overwrite.")
				continue
			} else {
				util.Errorf("*** WARNING: overwriting password")
			}
			rec = ps.Store[name]
		} else {
			rec = &store.SecretRecord{
				Label: name,
			}
		}

		password, err := util.PassPrompt("Password: "******"No password entered.")
			continue
		}
		rec.Secret = password
		rec.Timestamp = time.Now().Unix()
		ps.Store[name] = rec
	}
	return nil
}
Пример #8
0
func unlockStore(ks *store.KeyStore) bool {
	if !ks.Locked() {
		return true
	}
	passphrase, err := util.PassPrompt("keystore passphrase> ")
	if err != nil {
		util.Errorf("%v", err)
		return false
	}
	defer util.Zero(passphrase)

	if !ks.Locked() && ks.PrivateKey == nil {
		if !ks.LockWith(passphrase) {
			util.Errorf("Failed to set initial passphrase.")
			return false
		}
	}

	if !ks.Unlock(passphrase) {
		util.Errorf("Unlock failed (bad passphrase?)")
		return false
	}
	return true
}
Пример #9
0
func addSecret(ps *store.SecretStore, cfg *config) error {
	label := cfg.Args[0]
	if ps.Has(label) {
		if cfg.Overwrite {
			util.Errorf("WARNING: a token already exists under this label!")
		} else {
			return errors.New("token already exists under label")
		}
	}

	// Default prompt is echoing, which we want here.
	secret, err := util.PassPrompt("Secret: ")
	if err != nil {
		return err
	}

	var rec *store.SecretRecord
	secret = sanitiseSecret(secret)
	switch cfg.OTPType {
	case HOTP:
		in, err := util.ReadLine("Initial counter (0): ")
		if err != nil {
			return err
		}
		if in == "" {
			in = "0"
		}
		d, err := strconv.Atoi(in)
		if err != nil {
			return err
		}

		in, err = util.ReadLine("Digits (6 or 8): ")
		if err != nil {
			return err
		} else if in == "" {
			in = "6"
		}

		digits, err := strconv.Atoi(in)
		if err != nil {
			return err
		}

		key, err := base32.StdEncoding.DecodeString(string(secret))
		if err != nil {
			fmt.Printf("%s", secret)
			return err
		}

		var hotp *twofactor.HOTP
		hotp = twofactor.NewHOTP(key, uint64(d), digits)
		confirmation := hotp.OTP()
		fmt.Printf("Confirmation: %s\n", confirmation)
		rec = &store.SecretRecord{
			Label:     label,
			Secret:    []byte(hotp.URL(label)),
			Timestamp: time.Now().Unix(),
			Metadata: map[string][]byte{
				"key":          secret,
				"type":         []byte("HOTP"),
				"confirmation": []byte(confirmation),
			},
		}
	case TOTP:
		in, err := util.ReadLine("Time step (30s): ")
		if err != nil {
			return err
		}
		if in == "" {
			in = "30s"
		}
		d, err := time.ParseDuration(in)
		if err != nil {
			return err
		}

		in, err = util.ReadLine("Digits (6 or 8): ")
		if err != nil {
			return err
		} else if in == "" {
			in = "6"
		}

		digits, err := strconv.Atoi(in)
		if err != nil {
			return err
		}

		key, err := base32.StdEncoding.DecodeString(string(secret))
		if err != nil {
			return err
		}

		var totp *twofactor.TOTP
		totp = twofactor.NewTOTPSHA1(key, 0, uint64(d.Seconds()), digits)
		confirmation := totp.OTP()
		fmt.Printf("Confirmation: %s\n", confirmation)
		rec = &store.SecretRecord{
			Label:     label,
			Secret:    []byte(totp.URL(label)),
			Timestamp: time.Now().Unix(),
			Metadata: map[string][]byte{
				"key":          secret,
				"type":         []byte("TOTP-SHA1"),
				"step":         []byte(d.String()),
				"confirmation": []byte(confirmation),
			},
		}
	case GoogleTOTP:
		var totp *twofactor.TOTP
		totp, err = twofactor.NewGoogleTOTP(string(secret))
		if err != nil {
			return err
		}
		confirmation := totp.OTP()
		fmt.Printf("Confirmation: %s\n", confirmation)
		rec = &store.SecretRecord{
			Label:     label,
			Secret:    []byte(totp.URL(label)),
			Timestamp: time.Now().Unix(),
			Metadata: map[string][]byte{
				"key":          secret,
				"type":         []byte("TOTP-GOOGLE"),
				"step":         []byte("30s"),
				"confirmation": []byte(confirmation),
			},
		}
	default:
		return errors.New("unrecognised OTP type")
	}
	ps.Store[label] = rec
	return nil
}