Пример #1
0
func (s *ClientKeysSuite) TestPrivateKeyFiles(c *gc.C) {
	// Create/load client keys. They will be cached in memory:
	// any files added to the directory will not be considered
	// unless LoadClientKeys is called again.
	err := ssh.LoadClientKeys("~/.juju/ssh")
	c.Assert(err, jc.ErrorIsNil)
	checkPrivateKeyFiles(c, "~/.juju/ssh/juju_id_rsa")
	priv, pub, err := ssh.GenerateKey("whatever")
	c.Assert(err, jc.ErrorIsNil)
	err = ioutil.WriteFile(gitjujutesting.HomePath(".juju", "ssh", "whatever"), []byte(priv), 0600)
	c.Assert(err, jc.ErrorIsNil)
	err = ssh.LoadClientKeys("~/.juju/ssh")
	c.Assert(err, jc.ErrorIsNil)
	// The new private key won't be observed until the
	// corresponding public key exists.
	checkPrivateKeyFiles(c, "~/.juju/ssh/juju_id_rsa")
	err = ioutil.WriteFile(gitjujutesting.HomePath(".juju", "ssh", "whatever.pub"), []byte(pub), 0600)
	c.Assert(err, jc.ErrorIsNil)
	// new keys won't be reported until we call LoadClientKeys again
	checkPublicKeyFiles(c, "~/.juju/ssh/juju_id_rsa.pub")
	checkPrivateKeyFiles(c, "~/.juju/ssh/juju_id_rsa")
	err = ssh.LoadClientKeys("~/.juju/ssh")
	c.Assert(err, jc.ErrorIsNil)
	checkPublicKeyFiles(c, "~/.juju/ssh/juju_id_rsa.pub", "~/.juju/ssh/whatever.pub")
	checkPrivateKeyFiles(c, "~/.juju/ssh/juju_id_rsa", "~/.juju/ssh/whatever")
}
Пример #2
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)
}
Пример #3
0
func (s *SSHGoCryptoCommandSuite) TestProxyCommand(c *gc.C) {
	realNetcat, err := exec.LookPath("nc")
	if err != nil {
		c.Skip("skipping test, couldn't find netcat: %v")
		return
	}
	netcat := filepath.Join(c.MkDir(), "nc")
	err = ioutil.WriteFile(netcat, []byte("#!/bin/sh\necho $0 \"$@\" > $0.args && exec "+realNetcat+" \"$@\""), 0755)
	c.Assert(err, gc.IsNil)

	private, _, err := ssh.GenerateKey("test-server")
	c.Assert(err, gc.IsNil)
	key, err := cryptossh.ParsePrivateKey([]byte(private))
	client, err := ssh.NewGoCryptoClient(key)
	c.Assert(err, gc.IsNil)
	server := newServer(c)
	var opts ssh.Options
	port := server.listener.Addr().(*net.TCPAddr).Port
	opts.SetProxyCommand(netcat, "-q0", "%h", "%p")
	opts.SetPort(port)
	cmd := client.Command("127.0.0.1", testCommand, &opts)
	server.cfg.PublicKeyCallback = func(_ cryptossh.ConnMetadata, pubkey cryptossh.PublicKey) (*cryptossh.Permissions, error) {
		return nil, nil
	}
	go server.run(c)
	out, err := cmd.Output()
	c.Assert(err, gc.IsNil)
	c.Assert(string(out), gc.Equals, "abc value\n")
	// Ensure the proxy command was executed with the appropriate arguments.
	data, err := ioutil.ReadFile(netcat + ".args")
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, fmt.Sprintf("%s -q0 127.0.0.1 %v\n", netcat, port))
}
Пример #4
0
func readOrMakeSystemIdentity(context Context) (privateKey, publicKey string, err error) {
	identityFile := context.AgentConfig().SystemIdentityPath()
	// Don't generate a key unless we have to.
	keyExists, err := systemKeyExists(identityFile)
	if err != nil {
		return "", "", errors.Annotate(err, "failed to check system key exists")
	}
	if keyExists {
		logger.Infof("key exists, reading contents")

		// Read the contents.
		contents, err := ioutil.ReadFile(identityFile)
		if err != nil {
			return "", "", errors.Trace(err)
		}
		// If we are just reading the private key,
		return string(contents), "", nil
	}

	logger.Infof("generating new key")
	privateKey, publicKey, err = ssh.GenerateKey(config.JujuSystemKey)
	if err != nil {
		return "", "", errors.Annotate(err, "failed to create system key")
	}
	return privateKey, publicKey, nil
}
Пример #5
0
func generatePrivateKey(c *gc.C) string {
	oldBits := ssh.KeyBits
	defer func() {
		ssh.KeyBits = oldBits
	}()
	ssh.KeyBits = 32
	private, _, err := ssh.GenerateKey("test-client")
	c.Assert(err, gc.IsNil)
	return private
}
Пример #6
0
func (s *SSHGoCryptoCommandSuite) TestNewGoCryptoClient(c *gc.C) {
	_, err := ssh.NewGoCryptoClient()
	c.Assert(err, gc.IsNil)
	private, _, err := ssh.GenerateKey("test-client")
	c.Assert(err, gc.IsNil)
	key, err := cryptossh.ParsePrivateKey([]byte(private))
	c.Assert(err, gc.IsNil)
	_, err = ssh.NewGoCryptoClient(key)
	c.Assert(err, gc.IsNil)
}
Пример #7
0
func (s *GenerateSuite) TestGenerate(c *gc.C) {
	defer overrideGenerateKey(c).Restore()
	private, public, err := ssh.GenerateKey("some-comment")

	c.Check(err, jc.ErrorIsNil)
	c.Check(private, jc.HasPrefix, "-----BEGIN RSA PRIVATE KEY-----\n")
	c.Check(private, jc.HasSuffix, "-----END RSA PRIVATE KEY-----\n")
	c.Check(public, jc.HasPrefix, "ssh-rsa ")
	c.Check(public, jc.HasSuffix, " some-comment\n")
}
Пример #8
0
func newServer(c *gc.C) *sshServer {
	private, _, err := ssh.GenerateKey("test-server")
	c.Assert(err, gc.IsNil)
	key, err := cryptossh.ParsePrivateKey([]byte(private))
	c.Assert(err, gc.IsNil)
	server := &sshServer{
		cfg: &cryptossh.ServerConfig{},
	}
	server.cfg.AddHostKey(key)
	server.listener, err = net.Listen("tcp", "127.0.0.1:0")
	c.Assert(err, gc.IsNil)
	return server
}
Пример #9
0
func (s *updateAuthKeysSuite) TestReplacesWrongKey(c *gc.C) {
	// Put a wrong key in there.
	_, publicKey, err := ssh.GenerateKey(config.JujuSystemKey)
	c.Assert(err, jc.ErrorIsNil)
	keys := testing.FakeAuthKeys + "\n" + publicKey
	err = s.State.UpdateEnvironConfig(map[string]interface{}{
		"authorized-keys": keys,
	}, nil, nil)
	c.Assert(err, jc.ErrorIsNil)

	err = upgrades.UpdateAuthorizedKeysForSystemIdentity(s.ctx)
	c.Assert(err, jc.ErrorIsNil)

	s.assertHasPublicKeyInAuth(c, s.systemIdentity)
}
Пример #10
0
// GenerateSystemSSHKey creates a new key for the system identity. The
// authorized_keys in the environment config is updated to include the public
// key for the generated key.
func GenerateSystemSSHKey(env environs.Environ) (privateKey string, err error) {
	logger.Debugf("generate a system ssh key")
	// Create a new system ssh key and add that to the authorized keys.
	privateKey, publicKey, err := ssh.GenerateKey(config.JujuSystemKey)
	if err != nil {
		return "", fmt.Errorf("failed to create system key: %v", err)
	}
	authorized_keys := config.ConcatAuthKeys(env.Config().AuthorizedKeys(), publicKey)
	newConfig, err := env.Config().Apply(map[string]interface{}{
		config.AuthKeysConfig: authorized_keys,
	})
	if err != nil {
		return "", fmt.Errorf("failed to create new config: %v", err)
	}
	if err = env.SetConfig(newConfig); err != nil {
		return "", fmt.Errorf("failed to set new config: %v", err)
	}
	return privateKey, nil
}
Пример #11
0
func (s *SSHGoCryptoCommandSuite) TestCommand(c *gc.C) {
	private, _, err := ssh.GenerateKey("test-server")
	c.Assert(err, gc.IsNil)
	key, err := cryptossh.ParsePrivateKey([]byte(private))
	client, err := ssh.NewGoCryptoClient(key)
	c.Assert(err, gc.IsNil)
	server := newServer(c)
	var opts ssh.Options
	opts.SetPort(server.listener.Addr().(*net.TCPAddr).Port)
	cmd := client.Command("127.0.0.1", testCommand, &opts)
	checkedKey := false
	server.cfg.PublicKeyCallback = func(conn cryptossh.ConnMetadata, pubkey cryptossh.PublicKey) (*cryptossh.Permissions, error) {
		c.Check(pubkey, gc.DeepEquals, key.PublicKey())
		checkedKey = true
		return nil, nil
	}
	go server.run(c)
	out, err := cmd.Output()
	c.Assert(err, gc.IsNil)
	c.Assert(string(out), gc.Equals, "abc value\n")
	c.Assert(checkedKey, jc.IsTrue)
}
Пример #12
0
func (s *ClientKeysSuite) TestPublicKeyFiles(c *gc.C) {
	// LoadClientKeys will create the specified directory
	// and populate it with a key pair.
	err := ssh.LoadClientKeys("~/.juju/ssh")
	c.Assert(err, jc.ErrorIsNil)
	checkPublicKeyFiles(c, "~/.juju/ssh/juju_id_rsa.pub")
	// All files ending with .pub in the client key dir get picked up.
	priv, pub, err := ssh.GenerateKey("whatever")
	c.Assert(err, jc.ErrorIsNil)
	err = ioutil.WriteFile(gitjujutesting.HomePath(".juju", "ssh", "whatever.pub"), []byte(pub), 0600)
	c.Assert(err, jc.ErrorIsNil)
	err = ssh.LoadClientKeys("~/.juju/ssh")
	c.Assert(err, jc.ErrorIsNil)
	// The new public key won't be observed until the
	// corresponding private key exists.
	checkPublicKeyFiles(c, "~/.juju/ssh/juju_id_rsa.pub")
	err = ioutil.WriteFile(gitjujutesting.HomePath(".juju", "ssh", "whatever"), []byte(priv), 0600)
	c.Assert(err, jc.ErrorIsNil)
	err = ssh.LoadClientKeys("~/.juju/ssh")
	c.Assert(err, jc.ErrorIsNil)
	checkPublicKeyFiles(c, "~/.juju/ssh/juju_id_rsa.pub", "~/.juju/ssh/whatever.pub")
}