mirror of
https://github.com/gravitational/teleport
synced 2024-10-21 17:53:28 +00:00
Fix key principals not being used when identity files are being used (#11609)
This commit is contained in:
parent
52e7ace91a
commit
32cb76e26a
|
@ -226,6 +226,10 @@ type Config struct {
|
|||
// against Teleport client and obtaining credentials from elsewhere.
|
||||
SkipLocalAuth bool
|
||||
|
||||
// UseKeyPrincipals forces the use of the username from the key principals rather than using
|
||||
// the current user username.
|
||||
UseKeyPrincipals bool
|
||||
|
||||
// Agent is used when SkipLocalAuth is true
|
||||
Agent agent.Agent
|
||||
|
||||
|
@ -2166,7 +2170,7 @@ func (tc *TeleportClient) getProxySSHPrincipal() string {
|
|||
proxyPrincipal = tc.JumpHosts[0].Username
|
||||
}
|
||||
// see if we already have a signed key in the cache, we'll use that instead
|
||||
if !tc.Config.SkipLocalAuth && tc.localAgent != nil {
|
||||
if (!tc.Config.SkipLocalAuth || tc.UseKeyPrincipals) && tc.localAgent != nil {
|
||||
signers, err := tc.localAgent.Signers()
|
||||
if err != nil || len(signers) == 0 {
|
||||
return proxyPrincipal
|
||||
|
|
|
@ -17,12 +17,16 @@ limitations under the License.
|
|||
package client
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/gravitational/teleport/api/client/webclient"
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
"github.com/gravitational/trace"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/agent"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/check.v1"
|
||||
|
@ -499,6 +503,53 @@ func TestApplyProxySettings(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type mockAgent struct {
|
||||
// Agent is embedded to avoid redeclaring all interface methods.
|
||||
// Only the Signers method is implemented by testAgent.
|
||||
agent.Agent
|
||||
ValidPrincipals []string
|
||||
}
|
||||
|
||||
type mockSigner struct {
|
||||
ValidPrincipals []string
|
||||
}
|
||||
|
||||
func (s *mockSigner) PublicKey() ssh.PublicKey {
|
||||
return &ssh.Certificate{
|
||||
ValidPrincipals: s.ValidPrincipals,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *mockSigner) Sign(rand io.Reader, b []byte) (*ssh.Signature, error) {
|
||||
return nil, trace.Errorf("mockSigner does not implement Sign")
|
||||
}
|
||||
|
||||
// Signers implements agent.Agent.Signers.
|
||||
func (m *mockAgent) Signers() ([]ssh.Signer, error) {
|
||||
return []ssh.Signer{&mockSigner{ValidPrincipals: m.ValidPrincipals}}, nil
|
||||
}
|
||||
|
||||
func TestNewClient_UseKeyPrincipals(t *testing.T) {
|
||||
cfg := &Config{
|
||||
Username: "xyz",
|
||||
HostLogin: "xyz",
|
||||
WebProxyAddr: "localhost",
|
||||
SkipLocalAuth: true,
|
||||
UseKeyPrincipals: true, // causes VALID to be returned, as key was used
|
||||
Agent: &mockAgent{ValidPrincipals: []string{"VALID"}},
|
||||
AuthMethods: []ssh.AuthMethod{ssh.Password("xyz") /* placeholder authmethod */},
|
||||
}
|
||||
client, err := NewClient(cfg)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "VALID", client.getProxySSHPrincipal(), "ProxySSHPrincipal mismatch")
|
||||
|
||||
cfg.UseKeyPrincipals = false // causes xyz to be returned as key was not used
|
||||
|
||||
client, err = NewClient(cfg)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "xyz", client.getProxySSHPrincipal(), "ProxySSHPrincipal mismatch")
|
||||
}
|
||||
|
||||
func TestParseSearchKeywords(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -1910,6 +1910,10 @@ func makeClient(cf *CLIConf, useProfileLogin bool) (*client.TeleportClient, erro
|
|||
if cf.IdentityFileIn != "" {
|
||||
// Ignore local authentication methods when identity file is provided
|
||||
c.SkipLocalAuth = true
|
||||
// Force the use of the certificate principals so Unix
|
||||
// username does not get used when logging in
|
||||
c.UseKeyPrincipals = hostLogin == ""
|
||||
|
||||
var (
|
||||
key *client.Key
|
||||
identityAuth ssh.AuthMethod
|
||||
|
|
Loading…
Reference in a new issue