Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion api/client/webclient/webclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,11 @@ type AuthenticationSettings struct {
PrivateKeyPolicy keys.PrivateKeyPolicy `json:"private_key_policy"`
// DeviceTrustDisabled provides a clue to Teleport clients on whether to avoid
// device authentication.
// Deprecated: Use DeviceTrust.Disabled instead.
// DELETE IN 16.0, replaced by the DeviceTrust field (codingllama).
DeviceTrustDisabled bool `json:"device_trust_disabled,omitempty"`

// DeviceTrust holds cluster-wide device trust settings.
DeviceTrust DeviceTrustSettings `json:"device_trust,omitempty"`
// HasMessageOfTheDay is a flag indicating that the cluster has MOTD
// banner text that must be retrieved, displayed and acknowledged by
// the user.
Expand Down Expand Up @@ -448,6 +451,13 @@ type GithubSettings struct {
Display string `json:"display"`
}

// DeviceTrustSettings holds cluster-wide device trust settings that are liable
// to change client behavior.
type DeviceTrustSettings struct {
Disabled bool `json:"disabled,omitempty"`
AutoEnroll bool `json:"auto_enroll,omitempty"`
}

func (ps *ProxySettings) TunnelAddr() (string, error) {
// If TELEPORT_TUNNEL_PUBLIC_ADDR is set, nothing else has to be done, return it.
if tunnelAddr := os.Getenv(defaults.TunnelPublicAddrEnvar); tunnelAddr != "" {
Expand Down
2 changes: 1 addition & 1 deletion lib/client/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3305,7 +3305,7 @@ func (tc *TeleportClient) AttemptDeviceLogin(ctx context.Context, key *Key) erro
return trace.Wrap(err)
}

if !tc.dtAttemptLoginIgnorePing && pingResp.Auth.DeviceTrustDisabled {
if !tc.dtAttemptLoginIgnorePing && (pingResp.Auth.DeviceTrustDisabled || pingResp.Auth.DeviceTrust.Disabled) {
log.Debug("Device Trust: skipping device authentication, device trust disabled")
return nil
}
Expand Down
1 change: 1 addition & 0 deletions lib/client/api_login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ func TestTeleportClient_DeviceLogin(t *testing.T) {
resp, err := teleportClient.Ping(ctx)
require.NoError(t, err, "Ping failed")
require.True(t, resp.Auth.DeviceTrustDisabled, "Expected device trust to be disabled for Teleport OSS")
require.True(t, resp.Auth.DeviceTrust.Disabled, "Expected device trust to be disabled for Teleport OSS")

// Test!
// AttemptDeviceLogin should obey Ping and not attempt the ceremony.
Expand Down
12 changes: 12 additions & 0 deletions lib/web/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,7 @@ func localSettings(cap types.AuthPreference) (webclient.AuthenticationSettings,
Local: &webclient.LocalSettings{},
PrivateKeyPolicy: cap.GetPrivateKeyPolicy(),
DeviceTrustDisabled: deviceTrustDisabled(cap),
DeviceTrust: deviceTrustSettings(cap),
}

// Only copy the connector name if it's truly local and not a local fallback.
Expand Down Expand Up @@ -909,6 +910,7 @@ func oidcSettings(connector types.OIDCConnector, cap types.AuthPreference) webcl
PreferredLocalMFA: cap.GetPreferredLocalMFA(),
PrivateKeyPolicy: cap.GetPrivateKeyPolicy(),
DeviceTrustDisabled: deviceTrustDisabled(cap),
DeviceTrust: deviceTrustSettings(cap),
}
}

Expand All @@ -924,6 +926,7 @@ func samlSettings(connector types.SAMLConnector, cap types.AuthPreference) webcl
PreferredLocalMFA: cap.GetPreferredLocalMFA(),
PrivateKeyPolicy: cap.GetPrivateKeyPolicy(),
DeviceTrustDisabled: deviceTrustDisabled(cap),
DeviceTrust: deviceTrustSettings(cap),
}
}

Expand All @@ -939,6 +942,15 @@ func githubSettings(connector types.GithubConnector, cap types.AuthPreference) w
PreferredLocalMFA: cap.GetPreferredLocalMFA(),
PrivateKeyPolicy: cap.GetPrivateKeyPolicy(),
DeviceTrustDisabled: deviceTrustDisabled(cap),
DeviceTrust: deviceTrustSettings(cap),
}
}

func deviceTrustSettings(cap types.AuthPreference) webclient.DeviceTrustSettings {
dt := cap.GetDeviceTrust()
return webclient.DeviceTrustSettings{
Disabled: deviceTrustDisabled(cap),
AutoEnroll: dt != nil && dt.AutoEnroll,
}
}

Expand Down
26 changes: 24 additions & 2 deletions lib/web/apiserver_ping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ func TestPing(t *testing.T) {
RPID: "example.com",
},
},
assertResp: func(cap types.AuthPreference, resp *webclient.PingResponse) {
assertResp: func(_ types.AuthPreference, resp *webclient.PingResponse) {
assert.True(t, resp.Auth.DeviceTrustDisabled, "Auth.DeviceTrustDisabled")
assert.True(t, resp.Auth.DeviceTrust.Disabled, "Auth.DeviceTrust.Disabled")
},
},
{
Expand All @@ -134,8 +135,29 @@ func TestPing(t *testing.T) {
Mode: constants.DeviceTrustModeOptional,
},
},
assertResp: func(cap types.AuthPreference, resp *webclient.PingResponse) {
assertResp: func(_ types.AuthPreference, resp *webclient.PingResponse) {
assert.False(t, resp.Auth.DeviceTrustDisabled, "Auth.DeviceTrustDisabled")
assert.False(t, resp.Auth.DeviceTrust.Disabled, "Auth.DeviceTrust.Disabled")
},
},
{
name: "OK device trust auto-enroll",
buildType: modules.BuildEnterprise,
spec: &types.AuthPreferenceSpecV2{
Type: constants.Local,
SecondFactor: constants.SecondFactorOptional,
Webauthn: &types.Webauthn{
RPID: "example.com",
},
DeviceTrust: &types.DeviceTrust{
Mode: constants.DeviceTrustModeOptional,
AutoEnroll: true,
},
},
assertResp: func(_ types.AuthPreference, resp *webclient.PingResponse) {
assert.False(t, resp.Auth.DeviceTrustDisabled, "Auth.DeviceTrustDisabled")
assert.False(t, resp.Auth.DeviceTrust.Disabled, "Auth.DeviceTrust.Disabled")
assert.True(t, resp.Auth.DeviceTrust.AutoEnroll, "Auth.DeviceTrust.AutoEnroll")
},
},
}
Expand Down