Пример #1
0
func createShadowFile(brigPath string, ID, password string) error {
	shadowPath := filepath.Join(brigPath, "shadow")
	fd, err := os.OpenFile(shadowPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0755)
	if err != nil {
		return err
	}

	defer util.Closer(fd)

	salt := make([]byte, 8)
	n, err := rand.Reader.Read(salt)
	if err != nil {
		return err
	}

	if n != len(salt) {
		return fmt.Errorf("Inadeqaute salt length from random generator.")
	}

	entry := fmt.Sprintf("%s %x %x\n", ID, salt, hashPassword(salt, password))
	if _, err := fd.Write([]byte(entry)); err != nil {
		return err
	}

	return nil
}
Пример #2
0
func parseShadowFile(brigPath string, who string) (*shadowEntry, error) {
	fd, err := os.Open(filepath.Join(brigPath, "shadow"))
	if err != nil {
		return nil, err
	}

	defer util.Closer(fd)

	var entry *shadowEntry
	bufd := bufio.NewScanner(fd)
	for bufd.Scan() {
		var ID string
		var salt, hash []byte

		_, err = fmt.Sscanf(bufd.Text(), "%s %x %x", &ID, &salt, &hash)
		if err != nil && err != io.EOF {
			return nil, err
		}

		if ID == who {
			entry = &shadowEntry{ID: ID, salt: salt, hash: hash}
		}
	}

	if err := bufd.Err(); err != nil {
		return nil, err
	}

	// Might be a broken shadow file:
	if entry == nil {
		return nil, fmt.Errorf("No shadow entry found for `%v`.", who)
	}

	return entry, nil
}
Пример #3
0
// PromptNewPassword asks the user to input a password.
//
// While typing, the user gets feedback by the prompt color,
// which changes with the security of the password to green.
// Additionally the entrtopy of the password is shown.
// If minEntropy was not reached after hitting enter,
// this function will log a message and ask the user again.
func PromptNewPassword(minEntropy float64) ([]byte, error) {
	rl, err := readline.New("")
	if err != nil {
		return nil, err
	}
	defer util.Closer(rl)

	passwordCfg := rl.GenPasswordConfig()
	passwordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
		rl.SetPrompt(createStrengthPrompt(line, "   New "))
		rl.Refresh()
		return nil, 0, false
	})

	pwd := []byte{}

	for {
		pwd, err = rl.ReadPasswordWithConfig(passwordCfg)
		if err != nil {
			return nil, err
		}

		strength := zxcvbn.PasswordStrength(string(pwd), nil)
		if strength.Entropy >= minEntropy {
			break
		}

		fmt.Printf(colors.Colorize(msgLowEntropy, colors.Yellow)+"\n", minEntropy)
	}

	passwordCfg.SetListener(func(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
		rl.SetPrompt(createStrengthPrompt(line, "Retype "))
		rl.Refresh()
		return nil, 0, false
	})

	fmt.Println(colors.Colorize(msgReEnter, colors.Green))

	for {
		newPwd, err := rl.ReadPasswordWithConfig(passwordCfg)
		if err != nil {
			return nil, err
		}

		if bytes.Equal(pwd, newPwd) {
			break
		}

		fmt.Println(colors.Colorize(msgBadPassword, colors.Yellow))
	}

	return pwd, nil
}
Пример #4
0
func promptPasswordColored(color int) (string, error) {
	prompt := "Password: "******"", err
	}
	defer util.Closer(rl)

	return doPromptLine(rl, prompt, true)
}
Пример #5
0
func createMasterKey(brigPath string, keySize int) error {
	keyPath := filepath.Join(brigPath, "master.key")
	fd, err := os.OpenFile(keyPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0755)
	if err != nil {
		return err
	}

	defer util.Closer(fd)

	if _, err := io.CopyN(fd, rand.Reader, int64(keySize/8)); err != nil {
		return err
	}

	return nil
}
Пример #6
0
// StageDir traverses all files in a directory and calls StageFromReader on them.
func (st *Store) StageDir(filePath, repoPath string) error {
	walkErr := filepath.Walk(filePath, func(path string, info os.FileInfo, err error) error {
		// Simply skip errorneous files:
		if err != nil {
			log.Warningf("Walk: %v", err)
			return err
		}

		// Map the file path relative to repoPath:
		repoPath = prefixSlash(repoPath)
		currPath := filepath.Join(repoPath, path[len(filePath):])

		switch mode := info.Mode(); {
		case mode.IsRegular():
			fd, openErr := os.Open(path)
			if openErr != nil {
				return openErr
			}
			defer util.Closer(fd)

			compressAlgo, chooseErr := compress.ChooseCompressAlgo(path, fd)
			if err != nil {
				return chooseErr
			}

			err = st.StageFromReader(currPath, fd, compressAlgo)
		case mode.IsDir():
			_, err = st.Mkdir(currPath)
		default:
			log.Warningf("Recursive add: Ignoring weird file type: %v")
			return nil
		}

		if err != nil {
			log.WithFields(log.Fields{
				"file_path": filePath,
				"repo_path": repoPath,
				"curr_path": currPath,
			}).Warningf("StageDir: %v", err)
		}

		return nil
	})

	return walkErr
}
Пример #7
0
func handleCat(ctx *cli.Context, client *daemon.Client) error {
	repoPath := prefixSlash(ctx.Args().First())

	filePath := ""
	isStdoutMode := ctx.NArg() < 2

	if isStdoutMode {
		tmpFile, err := ioutil.TempFile("", ".brig-tmp-")
		if err != nil {
			return ExitCode{
				UnknownError,
				fmt.Sprintf("Unable to create temp file: %v", err),
			}
		}

		filePath = tmpFile.Name()
		defer util.Closer(tmpFile)
		defer func() {
			if err := os.Remove(filePath); err != nil {
				log.Warningf("Cannot remove temp-file: %v", err)
			}
		}()
	} else {
		absPath, err := filepath.Abs(ctx.Args()[1])
		if err != nil {
			return ExitCode{
				UnknownError,
				fmt.Sprintf("Unable to make abs path: %v: %v", filePath, err),
			}
		}

		filePath = absPath
	}

	if err := client.Cat(repoPath, filePath); err != nil {
		return ExitCode{
			UnknownError,
			fmt.Sprintf("Could not cat file: %v: %v", repoPath, err),
		}
	}

	if isStdoutMode {
		fd, err := os.Open(filePath)
		if err != nil {
			return ExitCode{
				UnknownError,
				"Could not open temp file",
			}
		}

		if _, err := io.Copy(os.Stdout, fd); err != nil {
			return ExitCode{
				UnknownError,
				fmt.Sprintf("Cannot copy to stdout: %v", err),
			}
		}

		if err := fd.Close(); err != nil {
			log.Warningf("Unable to close tmpfile handle: %v", err)
		}
	}

	return nil
}