Exemple #1
0
// ReadAuthorizedKeys implements the standard juju behaviour for finding
// authorized_keys. It returns a set of keys in in authorized_keys format
// (see sshd(8) for a description).  If path is non-empty, it names the
// file to use; otherwise the user's .ssh directory will be searched.
// Home directory expansion will be performed on the path if it starts with
// a ~; if the expanded path is relative, it will be interpreted relative
// to $HOME/.ssh.
//
// The result of utils/ssh.PublicKeyFiles will always be prepended to the
// result. In practice, this means ReadAuthorizedKeys never returns an
// error when the call originates in the CLI.
//
// If no SSH keys are found, ReadAuthorizedKeys returns
// ErrNoAuthorizedKeys.
func ReadAuthorizedKeys(ctx *cmd.Context, path string) (string, error) {
	files := ssh.PublicKeyFiles()
	if path == "" {
		files = append(files, "id_dsa.pub", "id_rsa.pub", "identity.pub")
	} else {
		files = append(files, path)
	}
	var firstError error
	var keyData []byte
	for _, f := range files {
		f, err := utils.NormalizePath(f)
		if err != nil {
			if firstError == nil {
				firstError = err
			}
			continue
		}
		if !filepath.IsAbs(f) {
			f = filepath.Join(utils.Home(), ".ssh", f)
		}
		data, err := ioutil.ReadFile(f)
		if err != nil {
			if firstError == nil && !os.IsNotExist(err) {
				firstError = err
			}
			continue
		}
		keyData = append(keyData, bytes.Trim(data, "\n")...)
		keyData = append(keyData, '\n')
		ctx.Verbosef("Adding contents of %q to authorized-keys", f)
	}
	if len(keyData) == 0 {
		if firstError == nil {
			firstError = ErrNoAuthorizedKeys
		}
		return "", firstError
	}
	return string(keyData), nil

}
Exemple #2
0
func (s *AuthKeysSuite) TestReadAuthorizedKeysClientKeys(c *gc.C) {
	keydir := filepath.Join(s.dotssh, "juju")
	err := ssh.LoadClientKeys(keydir) // auto-generates a key pair
	c.Assert(err, jc.ErrorIsNil)
	pubkeyFiles := ssh.PublicKeyFiles()
	c.Assert(pubkeyFiles, gc.HasLen, 1)
	data, err := ioutil.ReadFile(pubkeyFiles[0])
	c.Assert(err, jc.ErrorIsNil)
	prefix := strings.Trim(string(data), "\n") + "\n"

	writeFile(c, filepath.Join(s.dotssh, "id_rsa.pub"), "id_rsa")
	writeFile(c, filepath.Join(s.dotssh, "test.pub"), "test")
	keys, err := config.ReadAuthorizedKeys("")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(keys, gc.Equals, prefix+"id_rsa\n")
	keys, err = config.ReadAuthorizedKeys("test.pub")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(keys, gc.Equals, prefix+"test\n")
	keys, err = config.ReadAuthorizedKeys("notthere.pub")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(keys, gc.Equals, prefix)
}
func checkPublicKeyFiles(c *gc.C, expected ...string) {
	keys := ssh.PublicKeyFiles()
	checkFiles(c, keys, expected)
}