コード例 #1
0
ファイル: password.go プロジェクト: kisom/password
// removeMeta deletes metadata from the named record.
func removeMeta(fileName, name string) {
	passwords := openFile(fileName)
	defer passwords.Zero()

	rec, ok := passwords.Store[name]
	if !ok || rec.Metadata == nil {
		errorf("Nothing stored under the label %s", name)
		return
	}

	var keys = make([]string, 0, len(rec.Metadata))
	for k := range rec.Metadata {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	fmt.Println("Keys:")
	for i := range keys {
		fmt.Printf("\t%s\n", keys[i])
	}
	for {
		key, err := readpass.DefaultPasswordPrompt("Remove key: ")
		if err != nil {
			errorf("Failed to read key: %v", err)
			continue
		} else if key == "" {
			break
		}
		delete(rec.Metadata, key)
		fmt.Println("Deleted key", key)
	}
	rec.Timestamp = time.Now().Unix()
	saveFile(fileName, passwords)
}
コード例 #2
0
ファイル: password.go プロジェクト: kisom/password
// storeMany allows entering multiple name/password pairs to
// facilitate adding multiple labels (e.g. for a new password
// store). The same notes regarding storeRecord apply here.
func storeMany(fileName string, overWrite bool) {
	var passwords = Passwords{}
	defer passwords.Zero()

	if _, err := os.Stat(fileName); err != nil && !os.IsNotExist(err) {
		errorf("Failed to open password store: %v", err)
		os.Exit(1)
	} else if err == nil {
		passwords = openFile(fileName)
	}

	fmt.Println("Use an empty name to indicate that you are done.")
	for {
		name, err := readpass.DefaultPasswordPrompt("Name: ")
		if err != nil {
			errorf("%v", err)
			break
		} else if name == "" {
			break
		}

		rec, ok := passwords.Store[name]
		if ok && len(rec.Password) != 0 {
			if !overWrite {
				errorf("entry exists, not forcing overwrite")
				os.Exit(1)
			} else {
				errorf("*** warning: overwriting password")
			}
		} else if !ok {
			rec = &Record{
				Name: name,
			}
		}

		password, err := readpass.PasswordPromptBytes("Password: "******"%v", err)
			os.Exit(1)
		} else if len(password) == 0 {
			errorf("no password entered")
			continue
		}
		rec.Password = password
		rec.Timestamp = time.Now().Unix()
		passwords.Store[name] = rec
	}
	saveFile(fileName, passwords)
}
コード例 #3
0
ファイル: password.go プロジェクト: kisom/password
// storeMeta adds metadata to the named record.
func storeMeta(fileName, name string) {
	passwords := openFile(fileName)
	defer passwords.Zero()
	rec, ok := passwords.Store[name]
	if !ok {
		rec = &Record{Name: name}
		password, err := readpass.PasswordPromptBytes("Password: "******"%v", err)
			os.Exit(1)
		} else if len(password) == 0 {
			errorf("no password entered")
			os.Exit(1)
		}
		rec.Password = password
		passwords.Store[name] = rec
		defer zero(password)
	}

	if rec.Metadata == nil {
		rec.Metadata = map[string][]byte{}
	}

	fmt.Println("Enter metadata; use an empty line to indicate that you are done.")
	for {
		line, err := readpass.DefaultPasswordPrompt("key = value: ")
		if err != nil {
			errorf("%v", err)
			break
		} else if line == "" {
			break
		}

		meta := strings.SplitN(line, "=", 2)
		if len(meta) < 2 {
			errorf("Metadata should be in the form 'key=value'")
			continue
		}

		key := strings.TrimSpace(meta[0])
		val := strings.TrimSpace(meta[1])
		rec.Metadata[key] = []byte(val)
	}
	rec.Timestamp = time.Now().Unix()
	saveFile(fileName, passwords)
}
コード例 #4
0
ファイル: otpc.go プロジェクト: kisom/otpc
func addAccount(label string, otpType int) {
	if accounts[label] != "" {
		errorf("warning: label %s exists with url %s", label, accounts[label])
	}

	// Default prompt is echoing, which we want here.
	secret, err := readpass.DefaultPasswordPrompt("Secret: ")
	if err != nil {
		errorf("Failed to read password.")
		os.Exit(1)
	}
	secret = sanitiseSecret(secret)

	switch otpType {
	case HOTP:
		in, err := readpass.DefaultPasswordPrompt("Initial counter (0): ")
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}
		if in == "" {
			in = "0"
		}
		d, err := strconv.Atoi(in)
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}

		in, err = readpass.DefaultPasswordPrompt("Digits (6 or 8): ")
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		} else if in == "" {
			in = "6"
		}

		digits, err := strconv.Atoi(in)
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}

		key, err := base32.StdEncoding.DecodeString(secret)
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}

		var hotp *twofactor.HOTP
		hotp = twofactor.NewHOTP(key, uint64(d), digits)
		fmt.Printf("Confirmation: %s\n", hotp.OTP())
		secret = hotp.URL(label)
	case TOTP:
		in, err := readpass.DefaultPasswordPrompt("Time step (30s): ")
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}
		if in == "" {
			in = "30s"
		}
		d, err := time.ParseDuration(in)
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}

		in, err = readpass.DefaultPasswordPrompt("Digits (6 or 8): ")
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		} else if in == "" {
			in = "6"
		}

		digits, err := strconv.Atoi(in)
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}

		key, err := base32.StdEncoding.DecodeString(secret)
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}

		var totp *twofactor.TOTP
		totp = twofactor.NewTOTPSHA1(key, 0, uint64(d.Seconds()), digits)
		fmt.Printf("Confirmation: %s\n", totp.OTP())
		secret = totp.URL(label)
	case GoogleTOTP:
		var totp *twofactor.TOTP
		totp, err = twofactor.NewGoogleTOTP(secret)
		if err != nil {
			errorf("%v", err)
			os.Exit(1)
		}
		fmt.Printf("Confirmation: %s\n", totp.OTP())
		secret = totp.URL(label)
	default:
		errorf("unrecognised OTP type")
		os.Exit(1)
	}
	accounts[label] = secret
}