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
10 changes: 10 additions & 0 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2445,6 +2445,11 @@ func (c *Client) GetAuthPreference(ctx context.Context) (types.AuthPreference, e
if err != nil {
return nil, trace.Wrap(err)
}

// An old server would send PIVSlot instead of HardwareKey.PIVSlot
// TODO(Joerger): DELETE IN 17.0.0
pref.CheckSetPIVSlot()

return pref, nil
}

Expand All @@ -2454,6 +2459,11 @@ func (c *Client) SetAuthPreference(ctx context.Context, authPref types.AuthPrefe
if !ok {
return trace.BadParameter("invalid type %T", authPref)
}

// An old server would expect PIVSlot instead of HardwareKey.PIVSlot
// TODO(Joerger): DELETE IN 17.0.0
authPrefV2.CheckSetPIVSlot()

_, err := c.grpc.SetAuthPreference(ctx, authPrefV2)
return trace.Wrap(err)
}
Expand Down
36 changes: 33 additions & 3 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1912,9 +1912,15 @@ message AuthPreferenceSpecV2 {
// Requires Teleport Enterprise.
OktaOptions Okta = 17 [(gogoproto.jsontag) = "okta,omitempty"];

// PIVSlot is a PIV slot that Teleport clients should use instead of the
// default based on private key policy. For example, "9a" or "9e".
string PIVSlot = 18 [(gogoproto.jsontag) = "piv_slot,omitempty"];
// TODO(Joerger): DELETE IN 17.0.0
// Deprecated, replaced by HardwareKey settings.
string PIVSlot = 18 [
(gogoproto.jsontag) = "piv_slot,omitempty",
deprecated = true
];

// HardwareKey are the settings for hardware key support.
HardwareKey HardwareKey = 19 [(gogoproto.jsontag) = "hardware_key,omitempty"];
}

// U2F defines settings for U2F device.
Expand Down Expand Up @@ -2004,6 +2010,30 @@ message DeviceTrust {
repeated string EKCertAllowedCAs = 3 [(gogoproto.jsontag) = "ekcert_allowed_cas,omitempty"];
}

// HardwareKey holds settings related to hardware key support.
// Requires Teleport Enterprise.
message HardwareKey {
// PIVSlot is a PIV slot that Teleport clients should use instead of the
// default based on private key policy. For example, "9a" or "9e".
string PIVSlot = 1 [(gogoproto.jsontag) = "piv_slot,omitempty"];

// SerialNumberValidation holds settings for hardware key serial number validation.
// By default, serial number validation is disabled.
HardwareKeySerialNumberValidation SerialNumberValidation = 2 [(gogoproto.jsontag) = "serial_number_validation,omitempty"];
}

message HardwareKeySerialNumberValidation {
// Enabled indicates whether hardware key serial number validation is enabled.
bool Enabled = 1 [(gogoproto.jsontag) = "enabled,omitempty"];

// SerialNumberTraitName is an optional custom user trait name for hardware key
// serial numbers to replace the default: "hardware_key_serial_numbers".
//
// Note: Values for this user trait should be a comma-separated list of serial numbers,
// or a list of comm-separated lists. e.g ["123", "345,678"]
string SerialNumberTraitName = 2 [(gogoproto.jsontag) = "serial_number_trait_name,omitempty"];
}

// Namespace represents namespace resource specification
message Namespace {
// Kind is a resource kind
Expand Down
53 changes: 52 additions & 1 deletion api/types/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,14 @@ type AuthPreference interface {
GetRequireMFAType() RequireMFAType
// GetPrivateKeyPolicy returns the configured private key policy for the cluster.
GetPrivateKeyPolicy() keys.PrivateKeyPolicy

// GetHardwareKey returns the hardware key settings configured for the cluster.
GetHardwareKey() (*HardwareKey, error)
// GetPIVSlot returns the configured piv slot for the cluster.
GetPIVSlot() keys.PIVSlot
// GetHardwareKeySerialNumberValidation returns the cluster's hardware key
// serial number validation settings.
GetHardwareKeySerialNumberValidation() (*HardwareKeySerialNumberValidation, error)

// GetDisconnectExpiredCert returns disconnect expired certificate setting
GetDisconnectExpiredCert() bool
Expand Down Expand Up @@ -398,9 +404,29 @@ func (c *AuthPreferenceV2) GetPrivateKeyPolicy() keys.PrivateKeyPolicy {
}
}

// GetHardwareKey returns the hardware key settings configured for the cluster.
func (c *AuthPreferenceV2) GetHardwareKey() (*HardwareKey, error) {
if c.Spec.HardwareKey == nil {
return nil, trace.NotFound("Hardware key support is not configured in this cluster")
}
return c.Spec.HardwareKey, nil
}

// GetPIVSlot returns the configured piv slot for the cluster.
func (c *AuthPreferenceV2) GetPIVSlot() keys.PIVSlot {
return keys.PIVSlot(c.Spec.PIVSlot)
if hk, err := c.GetHardwareKey(); err == nil {
return keys.PIVSlot(hk.PIVSlot)
}
return ""
}

// GetHardwareKeySerialNumberValidation returns the cluster's hardware key
// serial number validation settings.
func (c *AuthPreferenceV2) GetHardwareKeySerialNumberValidation() (*HardwareKeySerialNumberValidation, error) {
if c.Spec.HardwareKey == nil || c.Spec.HardwareKey.SerialNumberValidation == nil {
return nil, trace.NotFound("Hardware key serial number validation is not configured in this cluster")
}
return c.Spec.HardwareKey.SerialNumberValidation, nil
}

// GetDisconnectExpiredCert returns disconnect expired certificate setting
Expand Down Expand Up @@ -650,6 +676,15 @@ func (c *AuthPreferenceV2) CheckAndSetDefaults() error {
}
}

// TODO(Joerger): DELETE IN 17.0.0
c.CheckSetPIVSlot()

if hk, err := c.GetHardwareKey(); err == nil {
if err := keys.PIVSlot(hk.PIVSlot).Validate(); err != nil {
return trace.Wrap(err)
}
}

// Make sure the IdP section is populated.
if c.Spec.IDP == nil {
c.Spec.IDP = &IdPOptions{}
Expand All @@ -674,6 +709,22 @@ func (c *AuthPreferenceV2) CheckAndSetDefaults() error {
return nil
}

// CheckSetPIVSlot ensures that the PIVSlot and Hardwarekey.PIVSlot stay in sync so that
// older versions of Teleport that do not know about Hardwarekey.PIVSlot are able to keep
// using PIVSlot and newer versions of Teleport can rely solely on Hardwarekey.PIVSlot
// without causing any service degradation.
// TODO(Joerger): DELETE IN 17.0.0
func (c *AuthPreferenceV2) CheckSetPIVSlot() {
if c.Spec.PIVSlot != "" {
if c.Spec.HardwareKey == nil {
c.Spec.HardwareKey = &HardwareKey{}
}
c.Spec.HardwareKey.PIVSlot = c.Spec.PIVSlot
} else if c.Spec.HardwareKey != nil && c.Spec.HardwareKey.PIVSlot != "" {
c.Spec.PIVSlot = c.Spec.HardwareKey.PIVSlot
}
}

// String represents a human readable version of authentication settings.
func (c *AuthPreferenceV2) String() string {
return fmt.Sprintf("AuthPreference(Type=%q,SecondFactor=%q)", c.Spec.Type, c.Spec.SecondFactor)
Expand Down
Loading