Beispiel #1
0
func ensureSystemSSHKey(context Context) error {
	identityFile := context.AgentConfig().SystemIdentityPath()
	// Don't generate a key unless we have to.
	keyExists, err := systemKeyExists(identityFile)
	if err != nil {
		return fmt.Errorf("failed to check system key exists: %v", err)
	}
	if keyExists {
		return nil
	}
	privateKey, publicKey, err := ssh.GenerateKey(config.JujuSystemKey)
	if err != nil {
		return fmt.Errorf("failed to create system key: %v", err)
	}
	// Write new authorised key.
	keyManager := keymanager.NewClient(context.APIState())
	errResults, err := keyManager.AddKeys(config.JujuSystemKey, publicKey)
	apiErr := err
	if apiErr == nil {
		apiErr = errResults[0].Error
	}
	if err != nil || errResults[0].Error != nil {
		return fmt.Errorf("failed to update authoised keys with new system key: %v", apiErr)
	}
	return ioutil.WriteFile(identityFile, []byte(privateKey), 0600)
}
Beispiel #2
0
// NewKeyManagerClient returns a keymanager client for the root api endpoint
// that the environment command returns.
func (c *SSHKeysBase) NewKeyManagerClient() (*keymanager.Client, error) {
	root, err := c.NewAPIRoot()
	if err != nil {
		return nil, err
	}
	return keymanager.NewClient(root), nil
}
Beispiel #3
0
func updateAuthorizedKeys(context Context, publicKey string) error {
	// Look for an existing authorized key.
	logger.Infof("setting new authorized key for %q", publicKey)
	keyManager := keymanager.NewClient(context.APIState())

	result, err := keyManager.ListKeys(ssh.FullKeys, config.JujuSystemKey)
	if err != nil {
		return errors.Trace(err)
	}
	if result[0].Error != nil {
		return errors.Trace(result[0].Error)
	}
	keys := result[0].Result

	// Loop through the keys. If we find a key that matches the publicKey
	// then we are good, and done.  If the comment on the key is for the system identity
	// but it is not the same, remove it.
	var keysToRemove []string
	for _, key := range keys {
		// The list of keys returned don't have carriage returns, but the
		// publicKey does, so add one one before testing for equality.
		if (key + "\n") == publicKey {
			logger.Infof("system identity key already in authorized list")
			return nil
		}

		fingerprint, comment, err := ssh.KeyFingerprint(key)
		if err != nil {
			// Log the error, but it doesn't stop us doing what we need to do.
			logger.Errorf("bad key in authorized keys: %v", err)
		} else if comment == config.JujuSystemKey {
			keysToRemove = append(keysToRemove, fingerprint)
		}
	}
	if keysToRemove != nil {
		logger.Infof("removing %d keys", len(keysToRemove))
		results, err := keyManager.DeleteKeys(config.JujuSystemKey, keysToRemove...)
		if err != nil {
			// Log the error but continue.
			logger.Errorf("failed to remove keys: %v", err)
		} else {
			for _, err := range results {
				if err.Error != nil {
					// Log the error but continue.
					logger.Errorf("failed to remove key: %v", err.Error)
				}
			}
		}
	}

	errResults, err := keyManager.AddKeys(config.JujuSystemKey, publicKey)
	if err != nil {
		return errors.Annotate(err, "failed to update authorised keys with new system key")
	}
	if err := errResults[0].Error; err != nil {
		return errors.Annotate(err, "failed to update authorised keys with new system key")
	}
	return nil
}
Beispiel #4
0
func (s *keymanagerSuite) TestAddSystemKeyWrongUser(c *gc.C) {
	key1 := sshtesting.ValidKeyOne.Key + " user@host"
	s.setAuthorisedKeys(c, key1)

	apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageEnviron)
	keyManager := keymanager.NewClient(apiState)
	defer keyManager.Close()
	newKey := sshtesting.ValidKeyTwo.Key
	_, err := keyManager.AddKeys("some-user", newKey)
	c.Assert(err, gc.ErrorMatches, "permission denied")
	s.assertEnvironKeys(c, []string{key1})
}
Beispiel #5
0
func (s *keymanagerSuite) TestAddSystemKey(c *gc.C) {
	key1 := sshtesting.ValidKeyOne.Key + " user@host"
	s.setAuthorisedKeys(c, key1)

	apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageModel)
	keyManager := keymanager.NewClient(apiState)
	defer keyManager.Close()
	newKey := sshtesting.ValidKeyTwo.Key
	errResults, err := keyManager.AddKeys("juju-system-key", newKey)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(errResults, gc.DeepEquals, []params.ErrorResult{
		{Error: nil},
	})
	s.assertModelKeys(c, []string{key1, newKey})
}
Beispiel #6
0
func (s *keymanagerSuite) TestAddSystemKeyWrongUser(c *gc.C) {
	key1 := sshtesting.ValidKeyOne.Key + " user@host"
	s.setAuthorisedKeys(c, key1)

	apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageModel)
	keyManager := keymanager.NewClient(apiState)
	defer keyManager.Close()
	newKey := sshtesting.ValidKeyTwo.Key
	_, err := keyManager.AddKeys("some-user", newKey)
	c.Assert(errors.Cause(err), gc.DeepEquals, &rpc.RequestError{
		Message: "permission denied",
		Code:    "unauthorized access",
	})
	s.assertModelKeys(c, []string{key1})
}
Beispiel #7
0
func (s *keymanagerSuite) SetUpTest(c *gc.C) {
	s.JujuConnSuite.SetUpTest(c)
	s.keymanager = keymanager.NewClient(s.APIState)
	c.Assert(s.keymanager, gc.NotNil)

}