Пример #1
0
func saveServices(passwd string, services *Services) {
	sort.Sort(services)
	decryptedBuffer := bytes.NewBuffer(nil)
	err := json.NewEncoder(decryptedBuffer).Encode(services)
	gobro.CheckErr(err)

	blockCipher, err := blowfish.NewCipher([]byte(passwd))
	gobro.CheckErr(err)
	iv := make([]byte, 8)
	_, err = rand.Read(iv)
	gobro.CheckErr(err)

	enc := decryptedBuffer.Bytes()
	cipher.NewCFBEncrypter(blockCipher, iv).XORKeyStream(enc, enc)
	buff := bytes.NewBuffer(iv)
	_, err = buff.Write(enc)
	gobro.CheckErr(err)

	enc = append(iv, enc...)
	base64EncodedLen := base64.StdEncoding.EncodedLen(len(enc))
	base64Enc := make([]byte, base64EncodedLen)
	base64.StdEncoding.Encode(base64Enc, enc)

	err = ioutil.WriteFile(passwdFileName(), base64Enc, os.ModePerm)
	gobro.CheckErr(err)
}
Пример #2
0
func changePassword(args []string) {
	if passwd == nil {
		pw, err := gopass.GetPass("   Current password: "******"" {
			fmt.Fprintln(os.Stderr, "Invalid password")
			return
		}
	}
	services, err := loadServices(getPasswd())
	gobro.CheckErr(err, "Password invalid")
	pw2, err := gopass.GetPass("   New Password: "******"" {
		fmt.Fprintln(os.Stderr, "Invalid password")
		return
	}
	pw3, err := gopass.GetPass("   Repeat Password: "******"" {
		fmt.Fprintln(os.Stderr, "Invalid password")
		return
	}
	if pw2 != pw3 {
		fmt.Fprintln(os.Stderr, "Passwords don't match")
		return
	}
	saveServices(pw2, services)
	passwd = &pw2
}
Пример #3
0
func (gen *PasswordGenerator) loadDictionary() {
	dictFile, err := os.Open("/usr/share/dict/words")
	gobro.CheckErr(err)
	dictBytes, err := ioutil.ReadAll(dictFile)
	gobro.CheckErr(err)
	gen.dictionary = strings.Split(string(dictBytes), "\n")
}
Пример #4
0
func (gen *PasswordGenerator) generateWithWords() string {
	// use /usr/share/dict
	dictFile, err := os.Open("/usr/share/dict/words")
	gobro.CheckErr(err)
	dictBytes, err := ioutil.ReadAll(dictFile)
	gobro.CheckErr(err)
	words := strings.Split(string(dictBytes), "\n")

	password := ""
	maxSubscript := big.NewInt(int64(len(words)))
	for len(password) < gen.length {
		subscript, _ := rand.Int(rand.Reader, maxSubscript)
		password += strings.Title(words[int(subscript.Int64())])
	}

	return password
}
Пример #5
0
func initialize(args []string) {
	_, err := loadConfig()
	if err != nil {
		u, err := user.Current()
		gobro.CheckErr(err)
		saveConfig(Config{PasswdFile: u.HomeDir + "/.passman"})
	}
	services, err := loadServices(getPasswd())
	if err == nil && services != nil && services.Len() > 0 {
		overwrite, err := commander.Prompt("   Overwrite existing password file? (y/N): ")
		if err != nil || strings.ToLower(overwrite) != "y" {
			return
		}
	}
	saveServices(getPasswd(), new(Services))
	_, err = loadServices(getPasswd()) // just to test that we have saved it properly
	gobro.CheckErr(err, "Unable to read password file")
}
Пример #6
0
func passwdFileName() string {
	config, err := loadConfig()
	gobro.CheckErr(err, "Unable to load config file")
	if config.PasswdFile == "" {
		fmt.Fprintln(os.Stderr, "The config file is missing or malformed.")
		os.Exit(1)
	}
	return config.PasswdFile
}
Пример #7
0
func ls(args []string) {
	services, err := loadServices(getPasswd())
	gobro.CheckErr(err, "Password invalid")
	if len(args) > 0 {
		services.Services = services.Search(args[0])
	}
	for _, service := range services.Services {
		fmt.Printf("   %s\n", service.Name)
	}
}
Пример #8
0
func add(args []string) {
	if len(args) == 0 {
		fmt.Fprintln(os.Stderr, "Usage: passman add <service> [<options>]\n"+
			"  -g: Generate password\n  "+
			"    Additional options:\n"+
			"      l: include lowercase characters\n"+
			"      u: include uppercase characters\n"+
			"      n: include numbers\n"+
			"      c: include special characters\n"+
			"      w: generate a password using random words from the dictionary\n"+
			"      \\d+$: password must be at least this long."+
			"      example: add -glun24 will produce a password using, lowercase, characters,\n"+
			"      uppercase characters, and numbers, and will be 24 characters long"+
			"  -p: Enter password\n  "+
			"  -m: attach metadata\n")
		return
	}

	name := args[0]
	services, err := loadServices(getPasswd())
	gobro.CheckErr(err, "Password invalid")
	service := services.Get(name)
	service.Name = name

	generateParams, _ := strarr.FindMatchWithRegex(args, "-g.*")
	if generateParams != "" {
		service.Password = NewPasswordGenerator(generateParams).generate()
	}

	if strarr.Contains(args, "-p") {
		prompt := fmt.Sprintf("   Password for %s: ", service.Name)
		password, err := gopass.GetPass(prompt)
		gobro.CheckErr(err)
		service.Password = password
	}

	if strarr.Contains(args, "-m") {
		service.Meta, _ = commander.Prompt(fmt.Sprintf("   Meta for %s: ", service.Name))
	}

	services.Add(service)
	saveServices(getPasswd(), services)
}
Пример #9
0
func rm(args []string) {
	if len(args) == 0 {
		fmt.Fprintln(os.Stderr, "Usage: passman rm <services>")
		return
	}
	services, err := loadServices(getPasswd())
	gobro.CheckErr(err, "Password invalid")
	for _, name := range args {
		services.Remove(name)
	}
	saveServices(getPasswd(), services)
}
Пример #10
0
func getPasswd() string {
	if passwd == nil {
		pw, err := gopass.GetPass("Password: "******"" {
			fmt.Fprintln(os.Stderr, "Invalid password")
			os.Exit(1)
		}
		passwd = &pw
	}
	return *passwd
}
Пример #11
0
func show(args []string) {
	prefix := ""
	if len(args) > 0 {
		prefix = args[0]
	}

	services, err := loadServices(getPasswd())
	gobro.CheckErr(err, "Password invalid")
	for _, service := range services.Search(prefix) {
		fmt.Printf("   %20s:   %s   %s\n", service.Name, service.Password, service.Meta)
	}
	fmt.Println("")
}
Пример #12
0
func cp(args []string) {
	if len(args) != 1 {
		fmt.Fprintln(os.Stderr, "Usage: passman cp <service>")
		return
	}
	services, err := loadServices(getPasswd())
	gobro.CheckErr(err, "Password invalid")
	service := services.Get(args[0])
	if service.Name != "" {
		clipboard.WriteAll(service.Password)
	} else {
		fmt.Printf("'%s' not found\n", args[0])
	}
}
Пример #13
0
func interactive(args []string) {
	cm := commandMap()
	_, err := loadServices(getPasswd())
	gobro.CheckErr(err, "Password invalid")
	for {
		cmd, err := commander.Prompt("passman$ ")
		if err != nil {
			return
		}
		if cmd == "" {
			continue
		}
		args := make([]string, 0, 3)
		args = append(args, "passman")
		args = append(args, strings.Split(cmd, " ")...)
		cm.Run(args)
	}
}
Пример #14
0
func NewPasswordGenerator(config string) *PasswordGenerator {
	regexp, err := regexp.Compile("\\d+$")
	gobro.CheckErr(err)
	passwordLength := 24 // default
	lengthBytes := regexp.Find([]byte(config))
	if len(lengthBytes) > 0 {
		length, err := strconv.Atoi(string(lengthBytes))
		if err == nil {
			passwordLength = length
		}
	}

	lowercase := strings.Contains(config, "l")
	uppercase := strings.Contains(config, "u")
	numbers := strings.Contains(config, "n")
	characters := strings.Contains(config, "c")
	words := strings.Contains(config, "w")

	if !(words || lowercase || uppercase || numbers || characters) {
		// Default values when no options specified
		lowercase = true
		uppercase = true
		numbers = true
	}

	generator := &PasswordGenerator{
		lowercase:  lowercase,
		uppercase:  uppercase,
		numbers:    numbers,
		characters: characters,
		words:      words,
		length:     passwordLength,
	}

	if words {
		generator.loadDictionary()
	} else {
		generator.loadCharacterTypes()
	}

	return generator
}
Пример #15
0
func loadServices(passwd string) (*Services, error) {
	base64Enc, err := ioutil.ReadFile(passwdFileName())
	if err != nil {
		return nil, err
	}

	enc := make([]byte, base64.StdEncoding.DecodedLen(len(base64Enc)))
	base64.StdEncoding.Decode(enc, base64Enc)

	blockCipher, err := blowfish.NewCipher([]byte(passwd))
	gobro.CheckErr(err)
	decrypted := make([]byte, len(enc)-8)
	cipher.NewCFBDecrypter(blockCipher, enc[:8]).XORKeyStream(decrypted, enc[8:])

	services := new(Services)
	err = json.NewDecoder(bytes.NewBuffer(decrypted)).Decode(services)
	if err != nil {
		return nil, errors.New("Invalid password")
	}
	return services, nil
}
Пример #16
0
func configFileName() string {
	u, err := user.Current()
	gobro.CheckErr(err)
	return u.HomeDir + "/.passman-config"
}